From b7a1ed072d9defc90a60c2feec91979ba626f0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20K=C3=BChner?= Date: Tue, 2 Nov 2021 18:42:10 +0100 Subject: [PATCH] Fix parsing error in exponent expressions with unary left-hand sides (#201) * Fix parsing error in exponent expressions with unary left-hand sides. Esprima (correctly) rejects expressions like -1**2. - https://github.com/jquery/esprima/pull/2070 However, expressions like (-1)**2 are valid but still rejected. This commit fixes this issue by identifying when the left operand is parenthesized. Fixes https://github.com/jquery/esprima/issues/1981 * add test for unary left side --- src/Esprima/JavascriptParser.cs | 12 +- .../invalid-syntax/unary_left_side.js | 1 + .../invalid-syntax/unary_left_side.tree.json | 112 ++++++++++++++++++ 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.js create mode 100644 test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.tree.json diff --git a/src/Esprima/JavascriptParser.cs b/src/Esprima/JavascriptParser.cs index 3f030d5b..0c110d1e 100644 --- a/src/Esprima/JavascriptParser.cs +++ b/src/Esprima/JavascriptParser.cs @@ -1861,10 +1861,14 @@ private Expression ParseUnaryExpression() private Expression ParseExponentiationExpression() { - var startToken = _lookahead; - - var expr = InheritCoverGrammar(parseUnaryExpression); - if (expr.Type != Nodes.UnaryExpression && Match("**")) + var startToken = _lookahead; + + var isLeftParenthesized = this.Match("("); + var expr = InheritCoverGrammar(parseUnaryExpression); + + var exponentAllowed = expr.Type != Nodes.UnaryExpression || isLeftParenthesized; + + if (exponentAllowed && Match("**")) { NextToken(); _context.IsAssignmentTarget = false; diff --git a/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.js b/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.js new file mode 100644 index 00000000..ec7c4647 --- /dev/null +++ b/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.js @@ -0,0 +1 @@ +(+2)**4; \ No newline at end of file diff --git a/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.tree.json b/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.tree.json new file mode 100644 index 00000000..ee247cad --- /dev/null +++ b/test/Esprima.Tests/Fixtures/invalid-syntax/unary_left_side.tree.json @@ -0,0 +1,112 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "**", + "left": { + "type": "UnaryExpression", + "operator": "+", + "argument": { + "type": "Literal", + "value": 2, + "raw": "2", + "range": [ + 2, + 3 + ], + "loc": { + "start": { + "line": 1, + "column": 2 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "prefix": true, + "range": [ + 1, + 3 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 3 + } + } + }, + "right": { + "type": "Literal", + "value": 4, + "raw": "4", + "range": [ + 6, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + "range": [ + 0, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + "range": [ + 0, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + } + } + ], + "sourceType": "script", + "range": [ + 0, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + } +} \ No newline at end of file