From 079f8cd5bc44db20db9c62c3a280c24feaf2f0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Wed, 26 May 2021 22:57:59 -0400 Subject: [PATCH] fix: disallow surrogate in the end of contextual name (#13377) --- packages/babel-parser/src/parser/util.js | 16 ++++-- .../input.js | 1 + .../output.json | 56 +++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/input.js create mode 100644 packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/output.json diff --git a/packages/babel-parser/src/parser/util.js b/packages/babel-parser/src/parser/util.js index f1106f45864a..c4c05a6f9f24 100644 --- a/packages/babel-parser/src/parser/util.js +++ b/packages/babel-parser/src/parser/util.js @@ -71,11 +71,17 @@ export default class UtilParser extends Tokenizer { isUnparsedContextual(nameStart: number, name: string): boolean { const nameEnd = nameStart + name.length; - return ( - this.input.slice(nameStart, nameEnd) === name && - (nameEnd === this.input.length || - !isIdentifierChar(this.input.charCodeAt(nameEnd))) - ); + if (this.input.slice(nameStart, nameEnd) === name) { + const nextCh = this.input.charCodeAt(nameEnd); + return !( + isIdentifierChar(nextCh) || + // check if `nextCh is between 0xd800 - 0xdbff, + // if `nextCh` is NaN, `NaN & 0xfc00` is 0, the function + // returns true + (nextCh & 0xfc00) === 0xd800 + ); + } + return false; } isLookaheadContextual(name: string): boolean { diff --git a/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/input.js b/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/input.js new file mode 100644 index 000000000000..25b03f15b3da --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/input.js @@ -0,0 +1 @@ +async function𝐬 f() {} diff --git a/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/output.json b/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/output.json new file mode 100644 index 000000000000..2e59de9f1cae --- /dev/null +++ b/packages/babel-parser/test/fixtures/es2017/async-functions/async-function-and-non-bmp-character/output.json @@ -0,0 +1,56 @@ +{ + "type": "File", + "start":0,"end":23,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":23}}, + "errors": [ + "SyntaxError: Missing semicolon. (1:5)", + "SyntaxError: Missing semicolon. (1:16)", + "SyntaxError: Missing semicolon. (1:20)" + ], + "program": { + "type": "Program", + "start":0,"end":23,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":23}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "expression": { + "type": "Identifier", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5},"identifierName":"async"}, + "name": "async" + } + }, + { + "type": "ExpressionStatement", + "start":6,"end":16,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":16}}, + "expression": { + "type": "Identifier", + "start":6,"end":16,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":16},"identifierName":"function𝐬"}, + "name": "function𝐬" + } + }, + { + "type": "ExpressionStatement", + "start":17,"end":20,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":20}}, + "expression": { + "type": "CallExpression", + "start":17,"end":20,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":20}}, + "callee": { + "type": "Identifier", + "start":17,"end":18,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":18},"identifierName":"f"}, + "name": "f" + }, + "arguments": [] + } + }, + { + "type": "BlockStatement", + "start":21,"end":23,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":23}}, + "body": [], + "directives": [] + } + ], + "directives": [] + } +} \ No newline at end of file