Repository navigation
Description
What version of Bun is running?
1.3.14 (latest release; the older, more severe behavior also reproduced on 1.3.5 — both shown below)
What platform is your computer?
Microsoft Windows 11 Home 10.0.26200 x64 (transpiler behavior, so presumably platform-independent — the sibling #27553 was reported on Darwin)
What steps can reproduce the bug?
The repro file must contain raw NUL bytes (0x00) inside a regex literal, so it can't be pasted directly. gen.js writes it:
// gen.js — writes repro.js whose regex literal contains RAW 0x00 bytes
const fs = require("fs");
const NUL = "\x00";
fs.writeFileSync(
"repro.js",
"const re = /" + NUL + "HFMASK(\\d+)" + NUL + "/g;\n" +
'const s = "\\x00HFMASK0\\x00"; // escape sequences, transpiler-safe\n' +
'console.log("source codepoints:", [...re.source].map(c => c.codePointAt(0).toString(16)).join(" "));\n' +
'console.log("source length:", re.source.length);\n' +
'console.log("matches:", re.exec(s) !== null);\n'
);node gen.js
node repro.js
bun repro.js(The repro prints .source as hex codepoints rather than the string itself because GitHub strips the NUL escape sequence from issue bodies — an earlier revision of this issue was mangled exactly that way.)
What is the expected behavior?
Same as Node (v24.18.0): the two raw U+0000 characters are preserved in the pattern — first and last codepoint 0, source length 13 — and the regex matches the NUL-delimited string:
source codepoints: 0 48 46 4d 41 53 4b 28 5c 64 2b 29 0
source length: 13
matches: true
Per EscapeRegExpPattern, RegExp.prototype.source escapes only / and line terminators, so a raw NUL in the source text must come through as one U+0000 character.
What do you see instead?
Bun 1.3.14 — matching now works, but the transpiler has rewritten each raw NUL into the literal 6-character escape text — backslash, u, 0, 0, 0, 0 (codepoints 5c 75 30 30 30 30) — so .source / .toString() no longer round-trip the source text (length 23 instead of 13):
source codepoints: 5c 75 30 30 30 30 48 46 4d 41 53 4b 28 5c 64 2b 29 5c 75 30 30 30 30
source length: 23
matches: true
Bun 1.3.5 — each raw NUL became the literal 6-character text \uFFFD (codepoints 5c 75 46 46 46 44) and matching failed entirely:
source codepoints: 5c 75 46 46 46 44 48 46 4d 41 53 4b 28 5c 64 2b 29 5c 75 46 46 46 44
source length: 23
matches: false
Additional information
- The 1.3.5-era match failure looks like the regex-literal sibling of
String.rawcorrupts null bytes in template literals #27553 (String.rawcorrupting raw NULs into the literal 6-character text\uFFFD), and appears to have been fixed as a side effect of fix(transpiler): preserve null bytes in tagged template literals #27554's codepoint-iterator sentinel fix. What remains on 1.3.14 is the source-text rewrite. - Likely the same printer path as Non-ASCII bytes corrupted in String.raw, RegExp.source, and runtime transpiler cache #30563 / Preserve non-ASCII bytes in String.raw and RegExp.source #30566 (
printRegExpLiteralre-escaping): on 1.3.14 the non-ASCII case from that issue still reproduces for regex literals —/╭─╮/.source.length→18(expected3) — even though Non-ASCII bytes corrupted in String.raw, RegExp.source, and runtime transpiler cache #30563 is closed and its fix PR Preserve non-ASCII bytes in String.raw and RegExp.source #30566 was closed unmerged. Meanwhile theString.rawraw-NUL case fromString.rawcorrupts null bytes in template literals #27553 is fixed on 1.3.14 (String.rawwith a raw NUL byte →length 1,charCodeAt(0) === 0). - Real-world impact of the match failure:
heygen-com/hyperframesships a minifieddist/cli.jswhose HTML mask/restore regex contains raw NUL bytes (/\x00HFMASK(\d+)\x00/gwith real 0x00 bytes in the bundle). Underbunxwith Bun ≤ 1.3.11 the restore regex matches nothing and every video render comes out as blank white frames — the output MP4 is mechanically valid, so this took a long time to root-cause back to the runtime. Agents and CI pipelines invoking CLIs viabunxwith pinned/older Bun versions hit this. Hardening issue on their side: dist/cli.js ships raw NUL bytes in the HFMASK restore regex (blank white renders under bunx, Bun ≤ 1.3.11) + preview crashes EPERM on Windows without Developer Mode (unguarded symlinkSync) heygen-com/hyperframes#2139.
Activity
github-actions commentedon Jul 10, 2026
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
robobun commentedon Jul 10, 2026
✅ Reproduced on main: the bun-target printer rewrites each raw control character in a regex literal into literal
\uXXXXescape text, sore.source.lengthis 23 instead of 13 and.sourceno longer round-trips.Fix in progress → #33866, which prints the regex pattern text verbatim (covers the raw-NUL case here and the non-ASCII case from #30563). A minimal control-characters-only fix with tests for this repro is also available on the
farm/94e20982/regex-literal-control-charsbranch.Preserve non-ASCII in regex .source and tagged template .raw
Add #33930 regression test for raw NUL/control bytes in regex .source
Preserve non-ASCII in regex .source and tagged template .raw
Preserve non-ASCII in regex .source and tagged template .raw