339 lines
9.3 KiB
Go
339 lines
9.3 KiB
Go
package fuzzcases
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/tetratelabs/wazero"
|
|
"github.com/tetratelabs/wazero/internal/platform"
|
|
"github.com/tetratelabs/wazero/internal/testing/require"
|
|
)
|
|
|
|
var ctx = context.Background()
|
|
|
|
//go:embed testdata/*.wasm
|
|
var testcases embed.FS
|
|
|
|
func getWasmBinary(t *testing.T, number int) []byte {
|
|
ret, err := testcases.ReadFile(fmt.Sprintf("testdata/%d.wasm", number))
|
|
require.NoError(t, err)
|
|
return ret
|
|
}
|
|
|
|
func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
|
|
if !platform.CompilerSupported() {
|
|
return
|
|
}
|
|
t.Run("compiler", func(t *testing.T) {
|
|
r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler())
|
|
defer r.Close(ctx)
|
|
runner(t, r)
|
|
})
|
|
}
|
|
|
|
func runWithInterpreter(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
|
|
t.Run("interpreter", func(t *testing.T) {
|
|
r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
|
|
defer r.Close(ctx)
|
|
runner(t, r)
|
|
})
|
|
}
|
|
|
|
func run(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
|
|
runWithInterpreter(t, runner)
|
|
runWithCompiler(t, runner)
|
|
}
|
|
|
|
// Test695 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
|
|
func Test695(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 695))
|
|
require.NoError(t, err)
|
|
|
|
_, err = module.ExportedFunction("i8x16s").Call(ctx)
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory access")
|
|
|
|
_, err = module.ExportedFunction("i16x8s").Call(ctx)
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory access")
|
|
})
|
|
}
|
|
|
|
func Test696(t *testing.T) {
|
|
functionNames := [4]string{
|
|
"select with 0 / after calling dummy",
|
|
"select with 0",
|
|
"typed select with 1 / after calling dummy",
|
|
"typed select with 1",
|
|
}
|
|
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 696))
|
|
require.NoError(t, err)
|
|
|
|
for _, name := range functionNames {
|
|
_, err := module.ExportedFunction(name).Call(ctx)
|
|
require.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
|
|
// Test699 ensures that accessing element instances and data instances works
|
|
// without crash even when the access happens in the nested function call.
|
|
func Test699(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
defer r.Close(ctx)
|
|
_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 699))
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
// Test701 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
|
|
func Test701(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 701))
|
|
require.NoError(t, err)
|
|
|
|
_, err = module.ExportedFunction("i32.extend16_s").Call(ctx)
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory access")
|
|
|
|
_, err = module.ExportedFunction("i32.extend8_s").Call(ctx)
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory access")
|
|
})
|
|
}
|
|
|
|
func Test704(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 704))
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func Test708(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 708))
|
|
require.NotNil(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory access")
|
|
})
|
|
}
|
|
|
|
func Test709(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 709))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("f64x2.promote_low_f32x4")
|
|
require.NotNil(t, f)
|
|
res, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
require.NotEqual(t, uint64(0), res[0])
|
|
require.NotEqual(t, uint64(0), res[1])
|
|
})
|
|
}
|
|
|
|
func Test715(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 715))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("select on conditional value after table.size")
|
|
require.NotNil(t, f)
|
|
res, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, uint64(1), res[0])
|
|
})
|
|
}
|
|
|
|
func Test716(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 716))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("select on ref.func")
|
|
require.NotNil(t, f)
|
|
res, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, uint64(1), res[0])
|
|
})
|
|
}
|
|
|
|
func Test717(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 717))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("vectors")
|
|
require.NotNil(t, f)
|
|
res, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
const expectedLen = 35
|
|
require.Equal(t, expectedLen, len(res))
|
|
for i := 0; i < expectedLen; i++ {
|
|
require.Equal(t, uint64(i), res[i])
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test718(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 718))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("v128.load_zero on the ceil")
|
|
require.NotNil(t, f)
|
|
_, err = f.Call(ctx)
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func Test719(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 719))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("require unreachable")
|
|
require.NotNil(t, f)
|
|
_, err = f.Call(ctx)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "wasm error: unreachable\nwasm stack trace:")
|
|
})
|
|
}
|
|
|
|
func Test720(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 720))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("access memory after table.grow")
|
|
require.NotNil(t, f)
|
|
res, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint32(0xffffffff), uint32(res[0]))
|
|
})
|
|
}
|
|
|
|
func Test721(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 721))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("conditional before elem.drop")
|
|
require.NotNil(t, f)
|
|
ret, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, uint64(1), ret[0])
|
|
})
|
|
}
|
|
|
|
func Test722(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 722))
|
|
require.NoError(t, err)
|
|
|
|
f := mod.ExportedFunction("conditional before data.drop")
|
|
require.NotNil(t, f)
|
|
ret, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, uint64(1), ret[0])
|
|
})
|
|
}
|
|
|
|
func Test725(t *testing.T) {
|
|
functions := []string{"i32.load8_s", "i32.load16_s"}
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 725))
|
|
require.NoError(t, err)
|
|
|
|
for _, fn := range functions {
|
|
f := mod.ExportedFunction(fn)
|
|
require.NotNil(t, f)
|
|
_, err := f.Call(ctx)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory")
|
|
}
|
|
})
|
|
}
|
|
|
|
// Test730 ensures that the vector min/max operations comply with the spec wrt sign bits of zeros:
|
|
//
|
|
// - min(0, 0) = 0, min(-0, 0) = -0, min(0, -0) = -0, min(-0, -0) = -0
|
|
// - max(0, 0) = 0, max(-0, 0) = 0, max(0, -0) = 0, max(-0, -0) = -0
|
|
func Test730(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
exp [2]uint64
|
|
}{
|
|
{name: "f32x4.max", exp: [2]uint64{0x80000000 << 32, 0x00000000}},
|
|
{name: "f32x4.min", exp: [2]uint64{0x80000000, 0x80000000<<32 | 0x80000000}},
|
|
{name: "f64x2.max", exp: [2]uint64{0, 0}},
|
|
{name: "f64x2.min", exp: [2]uint64{1 << 63, 1 << 63}},
|
|
{name: "f64x2.max/mix", exp: [2]uint64{0, 1 << 63}},
|
|
{name: "f64x2.min/mix", exp: [2]uint64{1 << 63, 0}},
|
|
}
|
|
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 730))
|
|
require.NoError(t, err)
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
f := mod.ExportedFunction(tc.name)
|
|
require.NotNil(t, f)
|
|
actual, err := f.Call(ctx)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tc.exp[:], actual)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test733(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 733))
|
|
require.NoError(t, err)
|
|
|
|
name := "out of bounds"
|
|
t.Run(name, func(t *testing.T) {
|
|
f := mod.ExportedFunction(name)
|
|
require.NotNil(t, f)
|
|
_, err = f.Call(ctx)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "out of bounds memory")
|
|
})
|
|
|
|
// Note: this case uses large memory space, so can be slow like 1 to 2 seconds.
|
|
name = "store higher offset"
|
|
t.Run(name, func(t *testing.T) {
|
|
f := mod.ExportedFunction(name)
|
|
require.NotNil(t, f)
|
|
_, err = f.Call(ctx)
|
|
require.NoError(t, err)
|
|
|
|
mem := mod.Memory()
|
|
require.NotNil(t, mem)
|
|
|
|
v, ok := mem.ReadUint64Le(ctx, 0x80000100)
|
|
require.True(t, ok)
|
|
require.Equal(t, uint64(0xffffffffffffffff), v)
|
|
})
|
|
})
|
|
}
|
|
|
|
func Test873(t *testing.T) {
|
|
run(t, func(t *testing.T, r wazero.Runtime) {
|
|
_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 873))
|
|
require.NoError(t, err)
|
|
})
|
|
}
|