From 80b3562cbd2f105db4f0ee6df7dfa41fc7d1aa95 Mon Sep 17 00:00:00 2001 From: adams85 <31276480+adams85@users.noreply.github.com> Date: Thu, 22 Feb 2024 08:05:21 +0100 Subject: [PATCH] Fix minor line terminator/line number tracking issues FIX: Properly normalize line endings in raw strings of invalid template tokens. FIX: Properly track line numbers for escaped newlines in strings. --- acorn/src/expression.js | 2 +- acorn/src/statement.js | 2 +- acorn/src/tokenize.js | 3 ++- test/tests-harmony.js | 8 ++++---- test/tests.js | 24 ++++++++++++------------ 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/acorn/src/expression.js b/acorn/src/expression.js index bd1884547..8aa29130d 100644 --- a/acorn/src/expression.js +++ b/acorn/src/expression.js @@ -706,7 +706,7 @@ pp.parseTemplateElement = function({isTagged}) { this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal") } elem.value = { - raw: this.value, + raw: this.value.replace(/\r\n?/g, "\n"), cooked: null } } else { diff --git a/acorn/src/statement.js b/acorn/src/statement.js index 9c88c6aee..d5e5c6fc8 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -42,7 +42,7 @@ pp.isLet = function(context) { // Statement) is allowed here. If context is not empty then only a Statement // is allowed. However, `let [` is an explicit negative lookahead for // ExpressionStatement, so special-case it first. - if (nextCh === 91 || nextCh === 92) return true // '[', '/' + if (nextCh === 91 || nextCh === 92) return true // '[', '\' if (context) return false if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) return true // '{', astral diff --git a/acorn/src/tokenize.js b/acorn/src/tokenize.js index 7aa777534..dceae076f 100644 --- a/acorn/src/tokenize.js +++ b/acorn/src/tokenize.js @@ -677,7 +677,7 @@ pp.readInvalidTemplateToken = function() { return this.finishToken(tt.invalidTemplate, this.input.slice(this.start, this.pos)) case "\r": - if (this.input[this.pos] + 1 === "\n") ++this.pos + if (this.input[this.pos + 1] === "\n") ++this.pos // fall through case "\n": case "\u2028": case "\u2029": ++this.curLine @@ -745,6 +745,7 @@ pp.readEscapedChar = function(inTemplate) { if (isNewLine(ch)) { // Unicode new line characters after \ get removed from output in both // template literals and strings + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine } return "" } return String.fromCharCode(ch) diff --git a/test/tests-harmony.js b/test/tests-harmony.js index c54f02aa5..e617647b9 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -816,23 +816,23 @@ test("`\\n\\r\\b\\v\\t\\f\\\n\\\r\n\\\u2028\\\u2029`", { tail: true, loc: { start: {line: 1, column: 1}, - end: {line: 3, column: 4} + end: {line: 5, column: 0} } }], expressions: [], loc: { start: {line: 1, column: 0}, - end: {line: 3, column: 5} + end: {line: 5, column: 1} } }, loc: { start: {line: 1, column: 0}, - end: {line: 3, column: 5} + end: {line: 5, column: 1} } }], loc: { start: {line: 1, column: 0}, - end: {line: 3, column: 5} + end: {line: 5, column: 1} } }, { ecmaVersion: 6, diff --git a/test/tests.js b/test/tests.js index 5d1da0fe4..11bc4cb2a 100644 --- a/test/tests.js +++ b/test/tests.js @@ -6928,8 +6928,8 @@ test("\"Hello\\\u2028world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } }, @@ -6939,8 +6939,8 @@ test("\"Hello\\\u2028world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } } @@ -6951,8 +6951,8 @@ test("\"Hello\\\u2028world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } }); @@ -6972,8 +6972,8 @@ test("\"Hello\\\u2029world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } }, @@ -6983,8 +6983,8 @@ test("\"Hello\\\u2029world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } } @@ -6995,8 +6995,8 @@ test("\"Hello\\\u2029world\"", { column: 0 }, end: { - line: 1, - column: 14 + line: 2, + column: 6 } } });