Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/test/app/Wasm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -878,6 +910,7 @@ struct Wasm_test : public beast::unit_test::suite
testWasmWasi();
testWasmSectionCorruption();

testStartFunctionLoop();
// perfTest();
}
};
Expand Down
4 changes: 4 additions & 0 deletions src/test/app/wasm_fixtures/fixtures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,3 +1340,7 @@ extern std::string const infiniteLoopWasmHex =
"303861373930636664623432626432343732302900490f7461726765745f66656174757265"
"73042b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f726566657265"
"6e63652d74797065732b0a6d756c746976616c7565";

extern std::string const startLoopHex =
"0061736d010000000108026000006000017f03030200010712020573746172740000066669"
"6e69736800010801000a0e02070003400c000b0b040041010b";
1 change: 1 addition & 0 deletions src/test/app/wasm_fixtures/fixtures.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ extern std::string const invalidSectionIdHex;
extern std::string const localVariableBombHex;

extern std::string const infiniteLoopWasmHex;
extern std::string const startLoopHex;
22 changes: 22 additions & 0 deletions src/test/app/wasm_fixtures/wat/start_loop.wat
Original file line number Diff line number Diff line change
@@ -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)
)
4 changes: 4 additions & 0 deletions src/xrpld/app/wasm/WasmiVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ struct ModuleWrapper

FuncInfo
getFunc(std::string_view funcName) const;

wasm_functype_t*
getFuncType(std::string_view funcName) const;

wmem
getMem() const;

Expand Down
33 changes: 27 additions & 6 deletions src/xrpld/app/wasm/detail/WasmiVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this already fixed, you need to rebase

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is rebased already. This line is to make sure the imports are built (hence tested), even when the module instance is not instantiated. I am not sure what previous fix relates to this change.

if (instantiate)
{
auto wimports = buildImports(s, imports);
addInstance(s, wimports);
}
}
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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)
Expand Down
Loading