From 624d4c7b2adb1fe518f7eb66480a6f419607792b Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Sat, 21 Feb 2026 10:16:00 +0800 Subject: [PATCH] Fix sign extension of i32 addresses in interpreter's getFinalAddress ptr.geti32() returns int32_t, which gets sign-extended to int64_t via C++ ternary promotion rules before being stored as uint64_t. For i32 addresses >= 0x80000000, this produces incorrect 64-bit addresses (e.g., 0xFFFFFFFF80000000 instead of 0x80000000), causing spurious out-of-bounds traps. Fix by casting through uint32_t first to zero-extend instead of sign-extend. --- src/wasm-interpreter.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 5ae570437ed..df8c9c05c9e 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -5151,7 +5151,8 @@ class ModuleRunnerBase : public ExpressionRunner { Address getFinalAddress(LS* curr, Literal ptr, Index bytes, Address memorySize) { Address memorySizeBytes = memorySize * Memory::kPageSize; - uint64_t addr = ptr.type == Type::i32 ? ptr.geti32() : ptr.geti64(); + uint64_t addr = ptr.type == Type::i32 ? (uint64_t)(uint32_t)ptr.geti32() + : (uint64_t)ptr.geti64(); trapIfGt(curr->offset, memorySizeBytes, "offset > memory"); trapIfGt(addr, memorySizeBytes - curr->offset, "final > memory"); addr += curr->offset; @@ -5167,7 +5168,8 @@ class ModuleRunnerBase : public ExpressionRunner { Address getFinalAddressWithoutOffset(Literal ptr, Index bytes, Address memorySize) { - uint64_t addr = ptr.type == Type::i32 ? ptr.geti32() : ptr.geti64(); + uint64_t addr = ptr.type == Type::i32 ? (uint64_t)(uint32_t)ptr.geti32() + : (uint64_t)ptr.geti64(); checkLoadAddress(addr, bytes, memorySize); return addr; }