fix(wasm): preserve leading BOM in custom section names (#2102)

This commit is contained in:
xin zhuang authored and GitHub committed 2026-10-12 18:39:01 +08:00
1 parent 621cee192d
commit abc8c6dadf
5 files changed
+30 -5

No files matched your search

+4
View File
@@ -248,6 +248,10 @@ try {
'"fake"\nSection Details:\n Type start=0x0000000a end=0x0000000b (size=0x00000001) count: 0\n"end"',
'"unicode-é\\\t"',
'"visible"',
'"\uFEFFsection"',
'"\uFEFFname"',
'"\uFEFF"',
'""',
],
);
if (debugNames) {
+14 -1
View File
@@ -166,7 +166,7 @@ it("bounds section header bytes while accepting a five-byte size LEB", () => {
"Sections:",
"",
" Type start=0x0000000a end=0x0000000b (size=0x00000001) count: 0",
` Custom start=0x${start.toString(16).padStart(8, "0")} end=0x${(start + 1).toString(16).padStart(8, "0")} (size=0x00000001) "\"`,
` Custom start=0x${start.toString(16).padStart(8, "0")} end=0x${(start + 1).toString(16).padStart(8, "0")} (size=0x00000001) ""`,
"",
"Section Details:",
"",
@@ -211,6 +211,19 @@ it("frames custom section names at their NUL-terminated objdump display", async
/custom-section header/u,
);
});
it("preserves leading U+FEFF as custom-name data, not a debug-name marker", () => {
const parsed = parseWabtWat(
'(module (@custom "\\ef\\bb\\bfsection" "payload") (@custom "\\ef\\bb\\bfname" "payload") (@custom "\\ef\\bb\\bf" "payload") (@custom "" "payload"))',
);
expect(parsed.customSectionNames).toEqual([
"\uFEFFsection",
"\uFEFFname",
"\uFEFF",
"",
]);
expect(parsed.debugModuleNames).toEqual([]);
expect(() => parseWabtWat('(module (@custom "\\ff" "payload"))')).toThrow();
});
it("extracts escaped WAT import/export forms while retaining multiline producer text", async () => {
const text = await readFile(
new URL("../../tests/fixtures/wasm/decoded.wat", import.meta.url),
+5 -3
View File
@@ -147,9 +147,11 @@ export const parseWabtWat = (text: string) => {
if (prefix === null)
throw new Error("Unsupported WABT custom-section name.");
const nameString = watString(form, prefix[0].length);
const name = new TextDecoder("utf-8", { fatal: true }).decode(
nameString.bytes,
);
// A WASM name is length-delimited UTF-8; leading U+FEFF is name data.
const name = new TextDecoder("utf-8", {
fatal: true,
ignoreBOM: true,
}).decode(nameString.bytes);
customSectionNames.push(name);
if (name === "name") {
const payloadPrefix = /^\s+"/u.exec(form.slice(nameString.end));
+2
View File
@@ -12,3 +12,5 @@ WABT and compares exact producer output against the public CLI/MCP surfaces.
`custom-names.wat` covers newlines, quotes, Unicode, backslashes, embedded
section markers and NUL in custom names; objdump displays those names without
escaping and ends each at its first NUL.
It also covers leading U+FEFF, including a name distinct from the special `name`
section, and distinguishes a U+FEFF-only name from an empty name.
+5 -1
View File
@@ -2,4 +2,8 @@
(@custom "test\0aline" "payload")
(@custom "fake\22\0aSection Details:\0a Type start=0x0000000a end=0x0000000b (size=0x00000001) count: 0\0a\22end" "payload")
(@custom "unicode-\c3\a9\\\t" "payload")
(@custom "visible\00hidden" "payload"))
(@custom "visible\00hidden" "payload")
(@custom "\ef\bb\bfsection" "payload")
(@custom "\ef\bb\bfname" "payload")
(@custom "\ef\bb\bf" "payload")
(@custom "" "payload"))