fix start function loop

This commit is contained in:
pwang200
2026-01-09 11:38:54 -05:00
committed by GitHub
parent 9ed60b45f8
commit 91f3d51f3d
6 changed files with 91 additions and 6 deletions

View File

@@ -850,6 +850,38 @@ struct Wasm_test : public beast::unit_test::suite
runFinishFunction(localVariableBombHex).has_value() == false);
}
void
testStartFunctionLoop()
{
testcase("infinite loop in start function");
using namespace test::jtx;
Env env(*this);
auto wasmStr = boost::algorithm::unhex(startLoopHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
TestLedgerDataProvider ledgerDataProvider(env);
ImportVec imports;
auto& engine = WasmEngine::instance();
auto checkRes = engine.check(
wasm, "finish", {}, imports, &ledgerDataProvider, env.journal);
BEAST_EXPECTS(
checkRes == tesSUCCESS, std::to_string(TERtoInt(checkRes)));
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imports,
&ledgerDataProvider,
1'000'000,
env.journal);
BEAST_EXPECTS(
re.error() == tecFAILED_PROCESSING,
std::to_string(TERtoInt(re.error())));
}
void
run() override
{
@@ -878,6 +910,7 @@ struct Wasm_test : public beast::unit_test::suite
testWasmWasi();
testWasmSectionCorruption();
testStartFunctionLoop();
// perfTest();
}
};

View File

@@ -1340,3 +1340,7 @@ extern std::string const infiniteLoopWasmHex =
"303861373930636664623432626432343732302900490f7461726765745f66656174757265"
"73042b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f726566657265"
"6e63652d74797065732b0a6d756c746976616c7565";
extern std::string const startLoopHex =
"0061736d010000000108026000006000017f03030200010712020573746172740000066669"
"6e69736800010801000a0e02070003400c000b0b040041010b";

View File

@@ -77,3 +77,4 @@ extern std::string const invalidSectionIdHex;
extern std::string const localVariableBombHex;
extern std::string const infiniteLoopWasmHex;
extern std::string const startLoopHex;

View File

@@ -0,0 +1,22 @@
(module
;; Function 1: The Infinite Loop
(func $run_forever
(loop $infinite
br $infinite
)
)
;; Function 2: Finish
(func $finish (result i32)
i32.const 1
)
;; 1. EXPORT the functions (optional, if you want to call them later)
(export "start" (func $run_forever))
(export "finish" (func $finish))
;; 2. The special start section
;; This tells the VM: "Run function $run_forever immediately
;; when this module is instantiated."
(start $run_forever)
)

View File

@@ -179,6 +179,10 @@ public:
FuncInfo
getFunc(std::string_view funcName) const;
wasm_functype_t*
getFuncType(std::string_view funcName) const;
wmem
getMem() const;

View File

@@ -249,9 +249,9 @@ ModuleWrapper::ModuleWrapper(
: module_(init(s, wasmBin, j)), j_(j)
{
wasm_module_exports(module_.get(), &exportTypes_.vec_);
auto wimports = buildImports(s, imports);
if (instantiate)
{
auto wimports = buildImports(s, imports);
addInstance(s, wimports);
}
}
@@ -427,6 +427,26 @@ ModuleWrapper::getFunc(std::string_view funcName) const
return instanceWrap_.getFunc(funcName, exportTypes_);
}
wasm_functype_t*
ModuleWrapper::getFuncType(std::string_view funcName) const
{
for (size_t i = 0; i < exportTypes_.vec_.size; i++)
{
auto const* exp_type(exportTypes_.vec_.data[i]);
wasm_name_t const* name = wasm_exporttype_name(exp_type);
wasm_externtype_t const* exn_type = wasm_exporttype_type(exp_type);
if (wasm_externtype_kind(exn_type) == WASM_EXTERN_FUNC &&
funcName == std::string_view(name->data, name->size))
{
return wasm_externtype_as_functype(
const_cast<wasm_externtype_t*>(exn_type));
}
}
throw std::runtime_error(
"can't find function <" + std::string(funcName) + ">");
}
wmem
ModuleWrapper::getMem() const
{
@@ -889,13 +909,14 @@ WasmiEngine::checkHlp(
if (wasmCode.empty())
throw std::runtime_error("empty nodule");
int const m = addModule(wasmCode, true, -1, imports);
if ((m < 0) || !moduleWrap_ || !moduleWrap_->instanceWrap_)
throw std::runtime_error("no instance"); // LCOV_EXCL_LINE
int const m = addModule(wasmCode, false, -1, imports);
if ((m < 0) || !moduleWrap_)
throw std::runtime_error("no module"); // LCOV_EXCL_LINE
// Looking for a func and compare parameter types
auto const f = getFunc(!funcName.empty() ? funcName : "_start");
auto const* ftp = wasm_functype_params(f.second);
auto const f =
moduleWrap_->getFuncType(!funcName.empty() ? funcName : "_start");
auto const* ftp = wasm_functype_params(f);
auto const p = convertParams(params);
if (int const comp = compareParamTypes(ftp, p); comp >= 0)