wa-lang.org/wazero@v1.0.2/internal/integration_test/fuzzcases/fuzzcases_test.go (about)

     1  package fuzzcases
     2  
     3  import (
     4  	"context"
     5  	"embed"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"wa-lang.org/wazero"
    10  	"wa-lang.org/wazero/internal/platform"
    11  	"wa-lang.org/wazero/internal/testing/require"
    12  )
    13  
    14  var ctx = context.Background()
    15  
    16  //go:embed testdata/*.wasm
    17  var testcases embed.FS
    18  
    19  func getWasmBinary(t *testing.T, number int) []byte {
    20  	ret, err := testcases.ReadFile(fmt.Sprintf("testdata/%d.wasm", number))
    21  	require.NoError(t, err)
    22  	return ret
    23  }
    24  
    25  func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    26  	if !platform.CompilerSupported() {
    27  		return
    28  	}
    29  	t.Run("compiler", func(t *testing.T) {
    30  		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler())
    31  		defer r.Close(ctx)
    32  		runner(t, r)
    33  	})
    34  }
    35  
    36  func runWithInterpreter(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    37  	t.Run("interpreter", func(t *testing.T) {
    38  		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
    39  		defer r.Close(ctx)
    40  		runner(t, r)
    41  	})
    42  }
    43  
    44  func run(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
    45  	runWithInterpreter(t, runner)
    46  	runWithCompiler(t, runner)
    47  }
    48  
    49  // Test695 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
    50  func Test695(t *testing.T) {
    51  	run(t, func(t *testing.T, r wazero.Runtime) {
    52  		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 695))
    53  		require.NoError(t, err)
    54  
    55  		_, err = module.ExportedFunction("i8x16s").Call(ctx)
    56  		require.NotNil(t, err)
    57  		require.Contains(t, err.Error(), "out of bounds memory access")
    58  
    59  		_, err = module.ExportedFunction("i16x8s").Call(ctx)
    60  		require.NotNil(t, err)
    61  		require.Contains(t, err.Error(), "out of bounds memory access")
    62  	})
    63  }
    64  
    65  func Test696(t *testing.T) {
    66  	functionNames := [4]string{
    67  		"select with 0 / after calling dummy",
    68  		"select with 0",
    69  		"typed select with 1 / after calling dummy",
    70  		"typed select with 1",
    71  	}
    72  
    73  	run(t, func(t *testing.T, r wazero.Runtime) {
    74  		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 696))
    75  		require.NoError(t, err)
    76  
    77  		for _, name := range functionNames {
    78  			_, err := module.ExportedFunction(name).Call(ctx)
    79  			require.NoError(t, err)
    80  		}
    81  	})
    82  }
    83  
    84  // Test699 ensures that accessing element instances and data instances works
    85  // without crash even when the access happens in the nested function call.
    86  func Test699(t *testing.T) {
    87  	run(t, func(t *testing.T, r wazero.Runtime) {
    88  		defer r.Close(ctx)
    89  		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 699))
    90  		require.NoError(t, err)
    91  	})
    92  }
    93  
    94  // Test701 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
    95  func Test701(t *testing.T) {
    96  	run(t, func(t *testing.T, r wazero.Runtime) {
    97  		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 701))
    98  		require.NoError(t, err)
    99  
   100  		_, err = module.ExportedFunction("i32.extend16_s").Call(ctx)
   101  		require.NotNil(t, err)
   102  		require.Contains(t, err.Error(), "out of bounds memory access")
   103  
   104  		_, err = module.ExportedFunction("i32.extend8_s").Call(ctx)
   105  		require.NotNil(t, err)
   106  		require.Contains(t, err.Error(), "out of bounds memory access")
   107  	})
   108  }
   109  
   110  func Test704(t *testing.T) {
   111  	run(t, func(t *testing.T, r wazero.Runtime) {
   112  		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 704))
   113  		require.NoError(t, err)
   114  	})
   115  }
   116  
   117  func Test708(t *testing.T) {
   118  	run(t, func(t *testing.T, r wazero.Runtime) {
   119  		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 708))
   120  		require.NotNil(t, err)
   121  		require.Contains(t, err.Error(), "out of bounds memory access")
   122  	})
   123  }
   124  
   125  func Test709(t *testing.T) {
   126  	run(t, func(t *testing.T, r wazero.Runtime) {
   127  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 709))
   128  		require.NoError(t, err)
   129  
   130  		f := mod.ExportedFunction("f64x2.promote_low_f32x4")
   131  		require.NotNil(t, f)
   132  		res, err := f.Call(ctx)
   133  		require.NoError(t, err)
   134  
   135  		require.NotEqual(t, uint64(0), res[0])
   136  		require.NotEqual(t, uint64(0), res[1])
   137  	})
   138  }
   139  
   140  func Test715(t *testing.T) {
   141  	run(t, func(t *testing.T, r wazero.Runtime) {
   142  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 715))
   143  		require.NoError(t, err)
   144  
   145  		f := mod.ExportedFunction("select on conditional value after table.size")
   146  		require.NotNil(t, f)
   147  		res, err := f.Call(ctx)
   148  		require.NoError(t, err)
   149  
   150  		require.Equal(t, uint64(1), res[0])
   151  	})
   152  }
   153  
   154  func Test716(t *testing.T) {
   155  	run(t, func(t *testing.T, r wazero.Runtime) {
   156  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 716))
   157  		require.NoError(t, err)
   158  
   159  		f := mod.ExportedFunction("select on ref.func")
   160  		require.NotNil(t, f)
   161  		res, err := f.Call(ctx)
   162  		require.NoError(t, err)
   163  
   164  		require.Equal(t, uint64(1), res[0])
   165  	})
   166  }
   167  
   168  func Test717(t *testing.T) {
   169  	run(t, func(t *testing.T, r wazero.Runtime) {
   170  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 717))
   171  		require.NoError(t, err)
   172  
   173  		f := mod.ExportedFunction("vectors")
   174  		require.NotNil(t, f)
   175  		res, err := f.Call(ctx)
   176  		require.NoError(t, err)
   177  
   178  		const expectedLen = 35
   179  		require.Equal(t, expectedLen, len(res))
   180  		for i := 0; i < expectedLen; i++ {
   181  			require.Equal(t, uint64(i), res[i])
   182  		}
   183  	})
   184  }
   185  
   186  func Test718(t *testing.T) {
   187  	run(t, func(t *testing.T, r wazero.Runtime) {
   188  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 718))
   189  		require.NoError(t, err)
   190  
   191  		f := mod.ExportedFunction("v128.load_zero on the ceil")
   192  		require.NotNil(t, f)
   193  		_, err = f.Call(ctx)
   194  		require.NoError(t, err)
   195  	})
   196  }
   197  
   198  func Test719(t *testing.T) {
   199  	run(t, func(t *testing.T, r wazero.Runtime) {
   200  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 719))
   201  		require.NoError(t, err)
   202  
   203  		f := mod.ExportedFunction("require unreachable")
   204  		require.NotNil(t, f)
   205  		_, err = f.Call(ctx)
   206  		require.Error(t, err)
   207  		require.Contains(t, err.Error(), "wasm error: unreachable\nwasm stack trace:")
   208  	})
   209  }
   210  
   211  func Test720(t *testing.T) {
   212  	run(t, func(t *testing.T, r wazero.Runtime) {
   213  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 720))
   214  		require.NoError(t, err)
   215  
   216  		f := mod.ExportedFunction("access memory after table.grow")
   217  		require.NotNil(t, f)
   218  		res, err := f.Call(ctx)
   219  		require.NoError(t, err)
   220  		require.Equal(t, uint32(0xffffffff), uint32(res[0]))
   221  	})
   222  }
   223  
   224  func Test721(t *testing.T) {
   225  	run(t, func(t *testing.T, r wazero.Runtime) {
   226  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 721))
   227  		require.NoError(t, err)
   228  
   229  		f := mod.ExportedFunction("conditional before elem.drop")
   230  		require.NotNil(t, f)
   231  		ret, err := f.Call(ctx)
   232  		require.NoError(t, err)
   233  
   234  		require.Equal(t, uint64(1), ret[0])
   235  	})
   236  }
   237  
   238  func Test722(t *testing.T) {
   239  	run(t, func(t *testing.T, r wazero.Runtime) {
   240  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 722))
   241  		require.NoError(t, err)
   242  
   243  		f := mod.ExportedFunction("conditional before data.drop")
   244  		require.NotNil(t, f)
   245  		ret, err := f.Call(ctx)
   246  		require.NoError(t, err)
   247  
   248  		require.Equal(t, uint64(1), ret[0])
   249  	})
   250  }
   251  
   252  func Test725(t *testing.T) {
   253  	functions := []string{"i32.load8_s", "i32.load16_s"}
   254  	run(t, func(t *testing.T, r wazero.Runtime) {
   255  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 725))
   256  		require.NoError(t, err)
   257  
   258  		for _, fn := range functions {
   259  			f := mod.ExportedFunction(fn)
   260  			require.NotNil(t, f)
   261  			_, err := f.Call(ctx)
   262  			require.Error(t, err)
   263  			require.Contains(t, err.Error(), "out of bounds memory")
   264  		}
   265  	})
   266  }
   267  
   268  // Test730 ensures that the vector min/max operations comply with the spec wrt sign bits of zeros:
   269  //
   270  //   - min(0, 0) = 0, min(-0, 0) = -0, min(0, -0) = -0, min(-0, -0) = -0
   271  //   - max(0, 0) = 0, max(-0, 0) =  0, max(0, -0) =  0, max(-0, -0) = -0
   272  func Test730(t *testing.T) {
   273  	tests := []struct {
   274  		name string
   275  		exp  [2]uint64
   276  	}{
   277  		{name: "f32x4.max", exp: [2]uint64{0x80000000 << 32, 0x00000000}},
   278  		{name: "f32x4.min", exp: [2]uint64{0x80000000, 0x80000000<<32 | 0x80000000}},
   279  		{name: "f64x2.max", exp: [2]uint64{0, 0}},
   280  		{name: "f64x2.min", exp: [2]uint64{1 << 63, 1 << 63}},
   281  		{name: "f64x2.max/mix", exp: [2]uint64{0, 1 << 63}},
   282  		{name: "f64x2.min/mix", exp: [2]uint64{1 << 63, 0}},
   283  	}
   284  
   285  	run(t, func(t *testing.T, r wazero.Runtime) {
   286  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 730))
   287  		require.NoError(t, err)
   288  
   289  		for _, tc := range tests {
   290  			t.Run(tc.name, func(t *testing.T) {
   291  				f := mod.ExportedFunction(tc.name)
   292  				require.NotNil(t, f)
   293  				actual, err := f.Call(ctx)
   294  				require.NoError(t, err)
   295  				require.Equal(t, tc.exp[:], actual)
   296  			})
   297  		}
   298  	})
   299  }
   300  
   301  func Test733(t *testing.T) {
   302  	run(t, func(t *testing.T, r wazero.Runtime) {
   303  		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 733))
   304  		require.NoError(t, err)
   305  
   306  		name := "out of bounds"
   307  		t.Run(name, func(t *testing.T) {
   308  			f := mod.ExportedFunction(name)
   309  			require.NotNil(t, f)
   310  			_, err = f.Call(ctx)
   311  			require.Error(t, err)
   312  			require.Contains(t, err.Error(), "out of bounds memory")
   313  		})
   314  
   315  		// Note: this case uses large memory space, so can be slow like 1 to 2 seconds.
   316  		name = "store higher offset"
   317  		t.Run(name, func(t *testing.T) {
   318  			f := mod.ExportedFunction(name)
   319  			require.NotNil(t, f)
   320  			_, err = f.Call(ctx)
   321  			require.NoError(t, err)
   322  
   323  			mem := mod.Memory()
   324  			require.NotNil(t, mem)
   325  
   326  			v, ok := mem.ReadUint64Le(ctx, 0x80000100)
   327  			require.True(t, ok)
   328  			require.Equal(t, uint64(0xffffffffffffffff), v)
   329  		})
   330  	})
   331  }
   332  
   333  func Test873(t *testing.T) {
   334  	run(t, func(t *testing.T, r wazero.Runtime) {
   335  		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 873))
   336  		require.NoError(t, err)
   337  	})
   338  }
   339  
   340  func Test874(t *testing.T) {
   341  	run(t, func(t *testing.T, r wazero.Runtime) {
   342  		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 874))
   343  		require.NoError(t, err)
   344  	})
   345  }