From df98db14528eb825b26c6180a7404bb033b04993 Mon Sep 17 00:00:00 2001 From: Olek <115580134+oleks-rip@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:12:14 -0500 Subject: [PATCH] Check wasm return type (#6240) * Check wasm return type * Add more tests --- src/test/app/Wasm_test.cpp | 60 +++++++++++++++++++++++++++ src/xrpld/app/wasm/detail/WasmiVM.cpp | 5 ++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 699178cac2..aee7968f78 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -953,6 +953,65 @@ struct Wasm_test : public beast::unit_test::suite env.close(); } + void + testReturnType() + { + using namespace test::jtx; + Env env(*this); + std::shared_ptr hfs(new TestHostFunctions(env, 0)); + + // return int64. + { // (module + // (memory (export "memory") 1) + // (func (export "finish") (result i64) + // i64.const 0x100000000)) + auto const wasmHex = + "0061736d010000000105016000017e030201000503010001" + "071302066d656d6f727902000666696e69736800000a0a01" + "08004280808080100b"; + auto const wasmStr = boost::algorithm::unhex(std::string(wasmHex)); + Bytes const wasm(wasmStr.begin(), wasmStr.end()); + auto const re = + runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000); + BEAST_EXPECT(!re); + } + + // return void. wasmi return execution error + { //(module + // (type (;0;) (func)) + // (func (;0;) (type 0) + // return) + // (memory (;0;) 1) + // (export "memory" (memory 0)) + // (export "finish" (func 0))) + auto const wasmHex = + "0061736d01000000010401600000030201000503010001071302066d656d6f" + "727902000666696e69736800000a050103000f0b"; + auto const wasmStr = boost::algorithm::unhex(std::string(wasmHex)); + Bytes const wasm(wasmStr.begin(), wasmStr.end()); + auto const re = + runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000); + BEAST_EXPECT(!re); + } + + // return i32, i32. wasmi doesn't create module + { //(module + // (memory (export "memory") 1) + // (func (export "finish") (result i32 i32) + // i32.const 0x10000000 + // i32.const 0x100000FF)) + auto const wasmHex = + "0061736d010000000106016000027f7f030201000503010001071302066d65" + "6d6f727902000666696e69736800000a10010e0041808080800141ff818080" + "010b"; + auto const wasmStr = boost::algorithm::unhex(std::string(wasmHex)); + Bytes const wasm(wasmStr.begin(), wasmStr.end()); + auto const re = + runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000); + BEAST_EXPECT(!re); + } + } + void run() override { @@ -984,6 +1043,7 @@ struct Wasm_test : public beast::unit_test::suite testStartFunctionLoop(); testBadAlloc(); testBadAlign(); + testReturnType(); // perfTest(); } diff --git a/src/xrpld/app/wasm/detail/WasmiVM.cpp b/src/xrpld/app/wasm/detail/WasmiVM.cpp index 037f787a26..fa2e2fe085 100644 --- a/src/xrpld/app/wasm/detail/WasmiVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmiVM.cpp @@ -874,8 +874,11 @@ WasmiEngine::runHlp( throw std::runtime_error( "<" + std::string(funcName) + "> return nothing"); // LCOV_EXCL_LINE + else if (res.r.vec_.data[0].kind != WASM_I32) + throw std::runtime_error( + "<" + std::string(funcName) + "> return type mismatch, ret: " + + std::to_string(static_cast(res.r.vec_.data[0].kind))); - assert(res.r.vec_.data[0].kind == WASM_I32); if (gas == -1) gas = std::numeric_limits::max(); WasmResult const ret{