From f198db6523f36e14e0831fbee8daafc4d7fcfce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 6 Dec 2025 17:11:10 +0200 Subject: [PATCH 1/2] Implement a FNV1-a style checksum to the binary decoded Wasm data, and display a help notice about needing to serve the HTML/JS file with UTF-8 encoding. This helps developers identify if their own shell files might not have the necessary encoding. --- src/postamble_minimal.js | 3 +++ src/preamble.js | 4 ++++ tools/link.py | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js index 9472ec752e9f8..f6d4981265891 100644 --- a/src/postamble_minimal.js +++ b/src/postamble_minimal.js @@ -151,6 +151,9 @@ function initRuntime(wasmExports) { #if SINGLE_FILE && SINGLE_FILE_BINARY_ENCODE && !WASM2JS Module['wasm'] = binaryDecode("<<< WASM_BINARY_DATA >>>"); +#if ASSERTIONS +assert(Module['wasm'].reduce((x,y) => ((x^y)*65599) >>> 0, 2166136261) == "<<< WASM_BINARY_DATA_CHECKSUM >>>", "The checksum of the binary decoded WebAssembly Module code does not match the original data. Double check that this .html/.js file is interpreted with UTF-8 encoding, e.g. by setting inside of the HTML file, or by passing 'Content-Type: application/javascript; charset=utf-8' HTTP header."); +#endif #elif SINGLE_FILE && WASM == 1 && !WASM2JS Module['wasm'] = base64Decode('<<< WASM_BINARY_DATA >>>'); #endif diff --git a/src/preamble.js b/src/preamble.js index 1df464281ee21..151ef0bee0b69 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -876,6 +876,10 @@ function getWasmImports() { return exports; #else wasmBinaryFile ??= findWasmBinary(); +#if SINGLE_FILE && SINGLE_FILE_BINARY_ENCODE && !WASM2JS && ASSERTIONS + assert(wasmBinaryFile.reduce((x,y) => ((x^y)*65599) >>> 0, 2166136261) == "<<< WASM_BINARY_DATA_CHECKSUM >>>", "The checksum of the binary decoded WebAssembly Module code does not match the original data. Double check that this .html/.js file is interpreted with UTF-8 encoding, e.g. by setting inside of the HTML file, or by passing 'Content-Type: application/javascript; charset=utf-8' HTTP header."); +#endif + #if WASM_ASYNC_COMPILATION #if RUNTIME_DEBUG dbg('asynchronously preparing wasm'); diff --git a/tools/link.py b/tools/link.py index 1e2efa3747887..87ed6ae267e13 100644 --- a/tools/link.py +++ b/tools/link.py @@ -2490,6 +2490,12 @@ def phase_binaryen(target, options, wasm_target): if settings.SINGLE_FILE_BINARY_ENCODE: js = do_replace(js, '"<<< WASM_BINARY_DATA >>>"', binary_encode(wasm_target)) + if settings.ASSERTIONS: + def checksum(a): + h = 2166136261 + for b in a: h = (h ^ b) * 65599 & 0xffffffff + return h + js = do_replace(js, '"<<< WASM_BINARY_DATA_CHECKSUM >>>"', str(checksum(utils.read_binary(wasm_target)))) else: js = do_replace(js, '<<< WASM_BINARY_DATA >>>', base64_encode(wasm_target)) delete_file(wasm_target) From d16c751c0c1fb561a6399b894910df941c07a7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 6 Dec 2025 17:30:51 +0200 Subject: [PATCH 2/2] ruff --- tools/link.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/link.py b/tools/link.py index 87ed6ae267e13..7dfbfe2cdae81 100644 --- a/tools/link.py +++ b/tools/link.py @@ -2493,7 +2493,8 @@ def phase_binaryen(target, options, wasm_target): if settings.ASSERTIONS: def checksum(a): h = 2166136261 - for b in a: h = (h ^ b) * 65599 & 0xffffffff + for b in a: + h = (h ^ b) * 65599 & 0xffffffff return h js = do_replace(js, '"<<< WASM_BINARY_DATA_CHECKSUM >>>"', str(checksum(utils.read_binary(wasm_target)))) else: