fix(parser): normalize raw template line endings with invalid escapes (#28285)

Template raw values must normalize CR and CRLF even when an invalid
escape leaves the cooked value undefined.

AI-assisted implementation.
This commit is contained in:
Boshen authored and GitHub committed 2026-10-29 16:30:15 +08:00
1 parent 2ac9a42f4b
commit 91a638d109
10 files changed
+29 -13

No files matched your search

+4
View File
@@ -16,3 +16,7 @@ apps/oxlint/test/fixtures/** text=auto eol=lf
crates/oxc_linter/src/generated/rules_enum.rs linguist-generated=true merge=ours
crates/oxc_linter/src/generated/rule_runner_impls.rs linguist-generated=true merge=ours
crates/oxc_linter/src/generated/assert_layouts.rs linguist-generated=true
# Preserve the line terminators exercised by these parser regression fixtures.
tasks/coverage/misc/pass/tagged-template-invalid-escape-cr.js -text whitespace=cr-at-eol
tasks/coverage/misc/pass/tagged-template-invalid-escape-crlf.js -text whitespace=cr-at-eol
+2 -1
View File
@@ -646,7 +646,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
let cooked = if self.cur_token().escaped() {
// `cooked = None` when template literal has invalid escape sequence
let cooked = self.cur_template_string();
if cooked.is_some() && raw.contains('\r') {
// TRV normalizes line endings even when an invalid escape makes TV undefined.
if raw.contains('\r') {
raw =
Str::from_str_in(&raw.cow_replace("\r\n", "\n").cow_replace('\r', "\n"), self);
}
@@ -0,0 +1 @@
function tag(strings) { return strings; } tag`\xZ `; tag`head\xZ ${0}middle\u{} ${1}tail\8 `;
@@ -0,0 +1,10 @@
function tag(strings) {
return strings;
}
tag`\xZ
`;
tag`head\xZ
${0}middle\u{}
${1}tail\8
`;
+2 -2
View File
@@ -1,3 +1,3 @@
codegen_misc Summary:
AST Parsed : 115/115 (100.00%)
Positive Passed: 115/115 (100.00%)
AST Parsed : 117/117 (100.00%)
Positive Passed: 117/117 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
formatter_misc Summary:
AST Parsed : 115/115 (100.00%)
Positive Passed: 115/115 (100.00%)
AST Parsed : 117/117 (100.00%)
Positive Passed: 117/117 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
lexer_misc Summary:
AST Parsed : 370/370 (100.00%)
Positive Passed: 370/370 (100.00%)
AST Parsed : 372/372 (100.00%)
Positive Passed: 372/372 (100.00%)
+2 -2
View File
@@ -1,6 +1,6 @@
parser_misc Summary:
AST Parsed : 115/115 (100.00%)
Positive Passed: 115/115 (100.00%)
AST Parsed : 117/117 (100.00%)
Positive Passed: 117/117 (100.00%)
Negative Passed: 257/257 (100.00%)
× TS(1275): 'accessor' modifier can only appear on a property declaration.
+2 -2
View File
@@ -1,6 +1,6 @@
semantic_misc Summary:
AST Parsed : 115/115 (100.00%)
Positive Passed: 109/115 (94.78%)
AST Parsed : 117/117 (100.00%)
Positive Passed: 111/117 (94.87%)
semantic Error: tasks/coverage/misc/pass/declare-let-private.ts
Bindings mismatch:
after transform: ScopeId(0): ["private"]
@@ -1,3 +1,3 @@
transformer_misc Summary:
AST Parsed : 115/115 (100.00%)
Positive Passed: 115/115 (100.00%)
AST Parsed : 117/117 (100.00%)
Positive Passed: 117/117 (100.00%)