Skip to content

Commit fbdd924

Browse files
authored
Add assertion checking if too many args are passed into exports. (#21349)
* Add assertion checking if too many args are passed into exports. Fixes #21348 * Fix webidl constructor number of arguments.
1 parent 7958a3b commit fbdd924

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed

src/preamble.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,16 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
495495
#include "URIUtils.js"
496496

497497
#if ASSERTIONS
498-
function createExportWrapper(name) {
498+
function createExportWrapper(name, nargs) {
499499
return (...args) => {
500500
assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
501501
#if EXIT_RUNTIME
502502
assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
503503
#endif
504504
var f = wasmExports[name];
505505
assert(f, `exported native function \`${name}\` not found`);
506+
// Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
507+
assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
506508
return f(...args);
507509
};
508510
}

test/test_other.py

+14
Original file line numberDiff line numberDiff line change
@@ -12035,6 +12035,20 @@ def test_native_call_after_exit(self):
1203512035
out = self.run_js('foo.js', assert_returncode=NON_ZERO)
1203612036
self.assertContained('native function `main` called after runtime exit', out)
1203712037

12038+
def test_native_call_nargs(self):
12039+
self.set_setting('ASSERTIONS')
12040+
self.set_setting('EXPORTED_FUNCTIONS', ['_main', '_foo'])
12041+
create_file('foo.c', r'''
12042+
#include <emscripten.h>
12043+
void foo(int arg) {}
12044+
int main() {
12045+
EM_ASM(_foo(99, 100));
12046+
}
12047+
''')
12048+
self.build('foo.c')
12049+
out = self.run_js('foo.js', assert_returncode=NON_ZERO)
12050+
self.assertContained('native function `foo` called with 2 args but expects 1', out)
12051+
1203812052
def test_metadce_wasm2js_i64(self):
1203912053
# handling i64 unsigned remainder brings in some i64 support code. metadce
1204012054
# must not remove it.

tools/emscripten.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ def install_wrapper(sym):
885885
if settings.ASSERTIONS and install_wrapper(name):
886886
# With assertions enabled we create a wrapper that are calls get routed through, for
887887
# the lifetime of the program.
888-
wrapper += "createExportWrapper('%s');" % name
888+
wrapper += f"createExportWrapper('{name}', {nargs});"
889889
elif settings.WASM_ASYNC_COMPILATION:
890890
# With WASM_ASYNC_COMPILATION wrapper will replace the global var and Module var on
891891
# first use.

tools/webidl_binder.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ def is_ptr_arg(i):
536536
elif arg_type == 'Double':
537537
body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}); }}\n".format(js_arg)
538538

539-
call_args = pre_arg
539+
call_args = pre_arg.copy()
540540

541541
for i, arg in enumerate(args):
542542
if options.wasm64 and is_ptr_arg(i):

0 commit comments

Comments
 (0)