diff --git a/test/test_other.py b/test/test_other.py index 067cce39f5311..a09ea101b437b 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -15539,3 +15539,8 @@ def test_cxx20_modules_std_headers(self): } ''') self.do_runf('main.cpp', 'Hello Module!', emcc_args=['-std=c++20', '-fmodules']) + + def test_invalid_export_name(self): + create_file('test.c', '__attribute__((export_name("my.func"))) void myfunc() {}') + err = self.expect_fail([EMCC, 'test.c']) + self.assertContained('emcc: error: invalid export name: my.func', err) diff --git a/tools/emscripten.py b/tools/emscripten.py index d312c7ffb5c4b..bc85680721343 100644 --- a/tools/emscripten.py +++ b/tools/emscripten.py @@ -578,6 +578,9 @@ def finalize_wasm(infile, outfile, js_syms): # These are any exports that were not requested on the command line and are # not known auto-generated system functions. unexpected_exports = [e for e in metadata.all_exports if treat_as_user_export(e)] + for n in unexpected_exports: + if not n.isidentifier(): + exit_with_error(f'invalid export name: {n}') unexpected_exports = [asmjs_mangle(e) for e in unexpected_exports] unexpected_exports = [e for e in unexpected_exports if e not in expected_exports] diff --git a/tools/shared.py b/tools/shared.py index 94a65b1318dad..a11a3c2f3766e 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -651,7 +651,7 @@ def is_c_symbol(name): def treat_as_user_export(name): - return not name.startswith('dynCall_') + return not name.startswith(('dynCall_', 'orig$')) def asmjs_mangle(name):