Skip to content

Commit

Permalink
Fix errors about escapes in keywords (ref: #10455)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Oct 22, 2019
1 parent d74bf5f commit 98fa30a
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 50 deletions.
18 changes: 11 additions & 7 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -1403,7 +1403,10 @@ export default class ExpressionParser extends LValParser {

parseNew(): N.NewExpression | N.MetaProperty {
const node = this.startNode();
const meta = this.parseIdentifier(true);

let meta = this.startNode();
this.next();
meta = this.createIdentifier(meta, "new");

if (this.eat(tt.dot)) {
const metaProp = this.parseMetaProperty(node, meta, "target");
Expand Down Expand Up @@ -2112,6 +2115,8 @@ export default class ExpressionParser extends LValParser {
// Parse the next token as an identifier. If `liberal` is true (used
// when parsing properties), it will also convert keywords into
// identifiers.
// This shouldn't be used to parse the keywords of meta properties, since they
// are not identifiers and cannot contain escape sequences.

parseIdentifier(liberal?: boolean): N.Identifier {
const node = this.startNode();
Expand All @@ -2132,11 +2137,6 @@ export default class ExpressionParser extends LValParser {

if (this.match(tt.name)) {
name = this.state.value;

// An escaped identifier whose value is the same as a keyword
if (!liberal && this.state.containsEsc && isKeyword(name)) {
this.raise(this.state.pos, `Escape sequence in keyword ${name}`);
}
} else if (this.state.type.keyword) {
name = this.state.type.keyword;

Expand All @@ -2156,7 +2156,11 @@ export default class ExpressionParser extends LValParser {
throw this.unexpected();
}

if (!liberal) {
if (liberal) {
// If the current token is not used as a keyword, set its type to "tt.name".
// This will prevent this.next() from throwing about unexpected escapes.
this.state.type = tt.name;
} else {
this.checkReservedWord(
name,
this.state.start,
Expand Down
16 changes: 13 additions & 3 deletions packages/babel-parser/src/tokenizer/index.js
Expand Up @@ -126,8 +126,11 @@ export default class Tokenizer extends LocationParser {
// Move to the next token

next(): void {
if (this.options.tokens && !this.isLookahead) {
this.state.tokens.push(new Token(this.state));
if (!this.isLookahead) {
this.checkKeywordEscapes();
if (this.options.tokens) {
this.state.tokens.push(new Token(this.state));
}
}

this.state.lastTokEnd = this.state.end;
Expand Down Expand Up @@ -1395,7 +1398,7 @@ export default class Tokenizer extends LocationParser {

readWord(): void {
const word = this.readWord1();
const type = (!this.state.containsEsc && keywordTypes.get(word)) || tt.name;
const type = keywordTypes.get(word) || tt.name;

// Allow @@iterator and @@asyncIterator as a identifier only inside type
if (
Expand All @@ -1408,6 +1411,13 @@ export default class Tokenizer extends LocationParser {
this.finishToken(type, word);
}

checkKeywordEscapes(): void {
const kw = this.state.type.keyword;
if (kw && this.state.containsEsc) {
this.raise(this.state.start, `Escape sequence in keyword ${kw}`);
}
}

braceIsBlock(prevType: TokenType): boolean {
const parent = this.curContext();
if (parent === ct.functionExpression || parent === ct.functionStatement) {
Expand Down
@@ -1 +1,3 @@
var co\u{6e}st = 123;

co\u{6e}st x = 2;
@@ -1,32 +1,34 @@
{
"type": "File",
"start": 0,
"end": 21,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 21
"line": 3,
"column": 17
}
},
"errors": [
"SyntaxError: Escape sequence in keyword const (1:14)"
"SyntaxError: Unexpected keyword 'const' (1:4)",
"SyntaxError: Escape sequence in keyword const (1:4)",
"SyntaxError: Escape sequence in keyword const (3:0)"
],
"program": {
"type": "Program",
"start": 0,
"end": 21,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 21
"line": 3,
"column": 17
}
},
"sourceType": "script",
Expand Down Expand Up @@ -101,6 +103,76 @@
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"start": 23,
"end": 40,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 17
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 34,
"end": 39,
"loc": {
"start": {
"line": 3,
"column": 11
},
"end": {
"line": 3,
"column": 16
}
},
"id": {
"type": "Identifier",
"start": 34,
"end": 35,
"loc": {
"start": {
"line": 3,
"column": 11
},
"end": {
"line": 3,
"column": 12
},
"identifierName": "x"
},
"name": "x"
},
"init": {
"type": "NumericLiteral",
"start": 38,
"end": 39,
"loc": {
"start": {
"line": 3,
"column": 15
},
"end": {
"line": 3,
"column": 16
}
},
"extra": {
"rawValue": 2,
"raw": "2"
},
"value": 2
}
}
],
"kind": "const"
}
],
"directives": []
Expand Down
@@ -1 +1,4 @@
var expor\u{74} = 123;

var x;
expor\u{74} { x };
@@ -0,0 +1,3 @@
{
"sourceType": "module"
}
@@ -1,35 +1,37 @@
{
"type": "File",
"start": 0,
"end": 22,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 22
"line": 4,
"column": 18
}
},
"errors": [
"SyntaxError: Escape sequence in keyword export (1:15)"
"SyntaxError: Unexpected keyword 'export' (1:4)",
"SyntaxError: Escape sequence in keyword export (1:4)",
"SyntaxError: Escape sequence in keyword export (4:0)"
],
"program": {
"type": "Program",
"start": 0,
"end": 22,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 22
"line": 4,
"column": 18
}
},
"sourceType": "script",
"sourceType": "module",
"interpreter": null,
"body": [
{
Expand Down Expand Up @@ -101,6 +103,125 @@
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"start": 24,
"end": 30,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 6
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 28,
"end": 29,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
}
},
"id": {
"type": "Identifier",
"start": 28,
"end": 29,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
},
"identifierName": "x"
},
"name": "x"
},
"init": null
}
],
"kind": "var"
},
{
"type": "ExportNamedDeclaration",
"start": 31,
"end": 49,
"loc": {
"start": {
"line": 4,
"column": 0
},
"end": {
"line": 4,
"column": 18
}
},
"specifiers": [
{
"type": "ExportSpecifier",
"start": 45,
"end": 46,
"loc": {
"start": {
"line": 4,
"column": 14
},
"end": {
"line": 4,
"column": 15
}
},
"local": {
"type": "Identifier",
"start": 45,
"end": 46,
"loc": {
"start": {
"line": 4,
"column": 14
},
"end": {
"line": 4,
"column": 15
},
"identifierName": "x"
},
"name": "x"
},
"exported": {
"type": "Identifier",
"start": 45,
"end": 46,
"loc": {
"start": {
"line": 4,
"column": 14
},
"end": {
"line": 4,
"column": 15
},
"identifierName": "x"
},
"name": "x"
}
}
],
"source": null,
"declaration": null
}
],
"directives": []
Expand Down
Expand Up @@ -13,7 +13,7 @@
}
},
"errors": [
"SyntaxError: Escape sequence in keyword if (1:12)"
"SyntaxError: Escape sequence in keyword if (1:0)"
],
"program": {
"type": "Program",
Expand Down

0 comments on commit 98fa30a

Please sign in to comment.