You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Measured while implementing #6891, on cf7f2af6e. Filed unassigned, not fixed there: #6891 closes the LT SLASH half with a one-token rule; this half provably cannot be closed the same way, so it is its own decision.
The defect
scanSource opens a REGEX when the character before a / is not a value (IDENT_CHAR, ), ]). } and GT are not values, so both of these open a phantom regex that runs to end of line:
a self-closing JSX tag whose / follows a brace — Foo bar={x} SLASH GT, Foo {...p} SLASH GT
a / in JSX text — {a}/{b}, or code OS_PAGE_REACT=off /code SLASH code x /code
A self-closing tag whose / follows a value (br SLASH GT, Foo SLASH GT, Foo x="1" SLASH GT) was never affected — the discriminator is the preceding byte, not the tag shape.
Measured
Over all 4,322 tracked source files, with #6891's fix applied and both flag arrays diffed byte for byte against the pre-fix scanner: 145 bytes across 28 files are still flagged literal by this shape. They were invisible before only because the closing tag's larger phantom started earlier on the same line and covered them.
It reaches the FABRICATES direction too — the phantom swallows a comment opener that follows it on the same line, so genuinely commented-out text comes back to a caller as live code:
const c = Foo bar={x} SLASH GT ; // dead = 1;
maskComments leaves dead = 1; standing. That is the direction this module's header calls worse than no verifier at all.
There is no one-token rule for it, and the two obvious ones are both wrong:
/ followed by GT is a tag closer. That is exactly how a regex matching a GT is spelled — str.replace(/GT/g, '>') — and this tree writes that shape.
} and GT are values. Both are genuinely ambiguous in JavaScript: function f(){} /re/ is a regex, and a GT /re/.test(b) parses.
Separating them needs to know whether the scanner is inside a JSX element, which is a parser. js-comment-mask.mjs is deliberately a cheap language-level masker, and turning it into a parser is a different card.
Already pinned, so this cannot be closed silently
scripts/__tests__/js-comment-mask-jsx-6891.test.ts carries a KNOWN LIMITS block asserting today's behaviour for all four shapes. Whoever closes this will see those pins fail and must retire them deliberately — the same two-way discipline that surfaced #6891 itself.
Shape of a fix, for triage rather than as a decision
Leave it. The residue is 145 bytes, it is pinned, and no gate's verdict moves today. Cheapest, and honest as long as the pins stay.
Measured while implementing #6891, on
cf7f2af6e. Filed unassigned, not fixed there: #6891 closes theLT SLASHhalf with a one-token rule; this half provably cannot be closed the same way, so it is its own decision.The defect
scanSourceopens a REGEX when the character before a/is not a value (IDENT_CHAR,),]).}andGTare not values, so both of these open a phantom regex that runs to end of line:/follows a brace —Foo bar={x} SLASH GT,Foo {...p} SLASH GT/in JSX text —{a}/{b}, orcode OS_PAGE_REACT=off /code SLASH code x /codeA self-closing tag whose
/follows a value (br SLASH GT,Foo SLASH GT,Foo x="1" SLASH GT) was never affected — the discriminator is the preceding byte, not the tag shape.Measured
Over all 4,322 tracked source files, with #6891's fix applied and both flag arrays diffed byte for byte against the pre-fix scanner: 145 bytes across 28 files are still flagged literal by this shape. They were invisible before only because the closing tag's larger phantom started earlier on the same line and covered them.
It reaches the FABRICATES direction too — the phantom swallows a comment opener that follows it on the same line, so genuinely commented-out text comes back to a caller as live code:
maskCommentsleavesdead = 1;standing. That is the direction this module's header calls worse than no verifier at all.Why #6891 did not take it
There is no one-token rule for it, and the two obvious ones are both wrong:
/followed byGTis a tag closer. That is exactly how a regex matching aGTis spelled —str.replace(/GT/g, '>')— and this tree writes that shape.}andGTare values. Both are genuinely ambiguous in JavaScript:function f(){} /re/is a regex, anda GT /re/.test(b)parses.Separating them needs to know whether the scanner is inside a JSX element, which is a parser.
js-comment-mask.mjsis deliberately a cheap language-level masker, and turning it into a parser is a different card.Already pinned, so this cannot be closed silently
scripts/__tests__/js-comment-mask-jsx-6891.test.tscarries aKNOWN LIMITSblock asserting today's behaviour for all four shapes. Whoever closes this will see those pins fail and must retire them deliberately — the same two-way discipline that surfaced #6891 itself.Shape of a fix, for triage rather than as a decision
scripts/check-comment-mask-corpus.mjs, named in this module's header as NOT ported here) and decide against a measurement over an independent parser rather than against cases. This is the route finding(tooling):js-comment-maskreads a JSX closing tag as a regex literal — 7 measured call sites become undelimitable #6891's own triage comment named as the only one that answers "which direction does it fail in".Generated by Claude Code