interpreter: clear higher bits for 32-bit signed shr (#708)

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda
2022-07-21 17:13:09 +09:00
committed by GitHub
parent b98a11e9c3
commit e44fa5f44a
4 changed files with 43 additions and 1 deletions

View File

@@ -23,6 +23,8 @@ var (
case701 []byte
//go:embed testdata/704.wasm
case704 []byte
//go:embed testdata/708.wasm
case708 []byte
)
func newRuntimeCompiler() wazero.Runtime {
@@ -53,9 +55,11 @@ func Test695(t *testing.T) {
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")
})
}
@@ -137,9 +141,11 @@ func Test701(t *testing.T) {
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")
})
}
@@ -165,3 +171,25 @@ func Test704(t *testing.T) {
})
}
}
func Test708(t *testing.T) {
if !platform.CompilerSupported() {
return
}
for _, tc := range []struct {
name string
r wazero.Runtime
}{
{name: "compiler", r: newRuntimeCompiler()},
{name: "interpreter", r: newRuntimeInterpreter()},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
defer tc.r.Close(ctx)
_, err := tc.r.InstantiateModuleFromBinary(ctx, case708)
require.NotNil(t, err)
require.Contains(t, err.Error(), "out of bounds memory access")
})
}
}

Binary file not shown.

View File

@@ -0,0 +1,14 @@
(module
(func
i32.const -1
i32.const 2
i32.shr_s
;; The shifted i32 should have the higher 32-bit cleared. If the result is signed-extended to 64-bit integer,
;; which means it has higher 32-bit all set, this i32.load calculates offset as int64(-1 << 2) + 4 = 0.
;; In that case, this won't rseult in memory out of bounds, which is not correct behavior.
i32.load offset=4
drop
)
(memory 1)
(start 0)
)