diff --git a/src/interp/interp-util.cc b/src/interp/interp-util.cc index 3d21d6d09..b6b16442d 100644 --- a/src/interp/interp-util.cc +++ b/src/interp/interp-util.cc @@ -16,6 +16,7 @@ #include "wabt/interp/interp-util.h" +#include #include #include "wabt/stream.h" @@ -84,9 +85,10 @@ void WriteValues(Stream* stream, const ValueTypes& types, const Values& values) { assert(types.size() == values.size()); - for (size_t i = 0; i < values.size(); ++i) { + size_t count = std::min(types.size(), values.size()); + for (size_t i = 0; i < count; ++i) { WriteValue(stream, TypedValue{types[i], values[i]}); - if (i != values.size() - 1) { + if (i != count - 1) { stream->Writef(", "); } } diff --git a/src/interp/interp.cc b/src/interp/interp.cc index ff869e06c..c457b84b1 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -537,7 +537,15 @@ Result DefinedFunc::DoCall(Thread& thread, const Values& params, Values& results, Trap::Ptr* out_trap) { - assert(params.size() == type_.params.size()); + if (params.size() != type_.params.size()) { + *out_trap = + Trap::New(thread.store(), + StringPrintf("argument count mismatch: expected %" PRIindex + ", got %" PRIindex, + static_cast(type_.params.size()), + static_cast(params.size()))); + return Result::Error; + } thread.PushValues(type_.params, params); RunResult result = thread.PushCall(*this, out_trap); if (result == RunResult::Trap) { diff --git a/src/test-interp.cc b/src/test-interp.cc index 272676f77..92e0cc8d1 100644 --- a/src/test-interp.cc +++ b/src/test-interp.cc @@ -174,6 +174,21 @@ TEST_F(InterpTest, Fac) { EXPECT_EQ(120u, results[0].Get()); } +TEST_F(InterpTest, CallArgCountMismatch) { + ReadModule(s_fac_module); + Instantiate(); + auto func = GetFuncExport(0); + + // Calling the one-parameter export with no arguments must trap rather than + // read past the end of the params vector. + Values results; + Trap::Ptr trap; + Result result = func->Call(store_, {}, results, &trap); + + ASSERT_EQ(Result::Error, result); + ASSERT_TRUE(trap); +} + TEST_F(InterpTest, Fac_Trace) { ReadModule(s_fac_module); Instantiate();