From 6c854ad221bc420396963710d31732c6ff986b58 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 5 Sep 2014 15:31:15 +0200
Subject: [PATCH 1/4] [loose parser] Be more careful about calling resetTo
It will try to eat whitespace, and can thus raise an unterminated comment exception
Issue #375
---
acorn_loose.js | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/acorn_loose.js b/acorn_loose.js
index 208c188afc..b3506b46b5 100644
--- a/acorn_loose.js
+++ b/acorn_loose.js
@@ -86,7 +86,7 @@
// Try to skip some text, based on the error message, and then continue
var msg = e.message, pos = e.raisedAt, replace = true;
if (/unterminated/i.test(msg)) {
- pos = lineEnd(e.pos);
+ pos = lineEnd(e.pos + 1);
if (/string/.test(msg)) {
replace = {start: e.pos, end: pos, type: tt.string, value: input.slice(e.pos + 1, pos)};
} else if (/regular expr/i.test(msg)) {
@@ -125,10 +125,18 @@
}
function resetTo(pos) {
- var ch = input.charAt(pos - 1);
- var reAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) ||
- /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(input.slice(pos - 10, pos));
- fetchToken.jumpTo(pos, reAllowed);
+ for (;;) {
+ try {
+ var ch = input.charAt(pos - 1);
+ var reAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) ||
+ /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(input.slice(pos - 10, pos));
+ return fetchToken.jumpTo(pos, reAllowed);
+ } catch(e) {
+ if (!(e instanceof SyntaxError && /unterminated comment/i.test(e.message))) throw e;
+ pos = lineEnd(e.pos + 1);
+ if (pos >= input.length) return;
+ }
+ }
}
function lookAhead(n) {
From 7da3b6f1fd3c97063b169daa4305638508d8098d Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Wed, 3 Sep 2014 18:20:39 +0100
Subject: [PATCH 2/4] Fix start position for HTML comments and add tests.
---
acorn.js | 14 ++++++--------
test/driver.js | 24 +++++++++++++++++++++---
test/tests.js | 47 ++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 69 insertions(+), 16 deletions(-)
diff --git a/acorn.js b/acorn.js
index acf76f6a6c..d7e6ce4e85 100644
--- a/acorn.js
+++ b/acorn.js
@@ -565,16 +565,16 @@
startLoc, options.locations && new Position);
}
- function skipLineComment() {
+ function skipLineComment(startSkip) {
var start = tokPos;
var startLoc = options.onComment && options.locations && new Position;
- var ch = input.charCodeAt(tokPos+=2);
+ var ch = input.charCodeAt(tokPos+=startSkip);
while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
++tokPos;
ch = input.charCodeAt(tokPos);
}
if (options.onComment)
- options.onComment(false, input.slice(start + 2, tokPos), start, tokPos,
+ options.onComment(false, input.slice(start + startSkip, tokPos), start, tokPos,
startLoc, options.locations && new Position);
}
@@ -609,7 +609,7 @@
if (next === 42) { // '*'
skipBlockComment();
} else if (next === 47) { // '/'
- skipLineComment();
+ skipLineComment(2);
} else break;
} else if (ch === 160) { // '\xa0'
++tokPos;
@@ -678,8 +678,7 @@
if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&
newline.test(input.slice(lastEnd, tokPos))) {
// A `-->` line comment
- tokPos += 3;
- skipLineComment();
+ skipLineComment(3);
skipSpace();
return readToken();
}
@@ -700,8 +699,7 @@
if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&
input.charCodeAt(tokPos + 3) == 45) {
// ` HTML comment", {}, {locations: true},
+ [{
+ block: false,
+ text: " HTML comment",
+ startLoc: { line: 2, column: 0 },
+ endLoc: { line: 2, column: 16 }
+ }]);
})();
(function() {
@@ -28747,4 +28784,4 @@ testFail("for(const x = 0;;);", "Unexpected token (1:4)", {ecmaVersion: 6});
actualTokens.push(token);
}
});
-})();
\ No newline at end of file
+})();
From a246bf83d00f6888268997dbf55533bb33e66bd3 Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Fri, 5 Sep 2014 11:18:49 +0100
Subject: [PATCH 3/4] Do not throw syntax error if strict mode function has
same name as one of its parameters.
---
acorn.js | 2 +-
index.html | 16 +++++++---------
test/tests.js | 2 ++
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/acorn.js b/acorn.js
index d7e6ce4e85..f01d4a4ef5 100644
--- a/acorn.js
+++ b/acorn.js
@@ -2258,7 +2258,7 @@
if (strict || !isExpression && node.body.body.length && isUseStrict(node.body.body[0])) {
var nameHash = {};
if (node.id)
- checkFunctionParam(node.id, nameHash);
+ checkFunctionParam(node.id, {});
for (var i = 0; i < node.params.length; i++)
checkFunctionParam(node.params[i], nameHash);
if (node.rest)
diff --git a/index.html b/index.html
index bfdc2e1c12..d0d5e8de73 100644
--- a/index.html
+++ b/index.html
@@ -356,16 +356,16 @@ the next one's tokStart will point at the right position.
startLoc, options.locations && new Position);
}
- function skipLineComment() {
+ function skipLineComment(startSkip) {
var start = tokPos;
var startLoc = options.onComment && options.locations && new Position;
- var ch = input.charCodeAt(tokPos+=2);
+ var ch = input.charCodeAt(tokPos+=startSkip);
while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
++tokPos;
ch = input.charCodeAt(tokPos);
}
if (options.onComment)
- options.onComment(false, input.slice(start + 2, tokPos), start, tokPos,
+ options.onComment(false, input.slice(start + startSkip, tokPos), start, tokPos,
startLoc, options.locations && new Position);
} | Called at the start of the parse and after every token. Skips
whitespace and comments, and. | function skipSpace() {
@@ -396,7 +396,7 @@ whitespace and comments, and. | if (next === 42) { // '*'
skipBlockComment();
} else if (next === 47) { // '/'
- skipLineComment();
+ skipLineComment(2);
} else break;
} else if (ch === 160) { // '\xa0'
++tokPos;
@@ -457,8 +457,7 @@ into it.
var next = input.charCodeAt(tokPos + 1);
if (next === code) {
if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&
- newline.test(input.slice(lastEnd, tokPos))) { |
| A --> line comment | tokPos += 3;
- skipLineComment();
+ newline.test(input.slice(lastEnd, tokPos))) { |
| A --> line comment | skipLineComment(3);
skipSpace();
return readToken();
}
@@ -477,8 +476,7 @@ into it.
return finishOp(_bitShift, size);
}
if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&
- input.charCodeAt(tokPos + 3) == 45) { |
| <!--, an XML-style comment that should be interpreted as a line comment | tokPos += 4;
- skipLineComment();
+ input.charCodeAt(tokPos + 3) == 45) { |
| <!--, an XML-style comment that should be interpreted as a line comment | skipLineComment(4);
skipSpace();
return readToken();
}
@@ -1750,7 +1748,7 @@ are not repeated, and it does not try to bind the words eval
or arguments. | if (strict || !isExpression && node.body.body.length && isUseStrict(node.body.body[0])) {
var nameHash = {};
if (node.id)
- checkFunctionParam(node.id, nameHash);
+ checkFunctionParam(node.id, {});
for (var i = 0; i < node.params.length; i++)
checkFunctionParam(node.params[i], nameHash);
if (node.rest)
diff --git a/test/tests.js b/test/tests.js
index 211d4a1bec..b51695ad24 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -28785,3 +28785,5 @@ test(" |