Arrow function followed by divide or syntax error?
Andreas Rossberg
rossberg at google.com
Wed May 24 09:10:21 UTC 2017
Note that the arrow function can only form an ExpressionStatement, which
requires a terminating semicolon. There is none in this example, nor a line
break that would allow one to be inserted implicitly. So when reaching the
first `/` a syntax error is apparent, since there is no way the input can
still form a well-formed statement at that point.
On 24 May 2017 at 10:32, Peter van der Zee <ecma at qfox.nl> wrote:
> > Unlike an ordinary function expression, which is a PrimaryExpression, an
> arrow function is merely an AssigmentExpression, so has much lower
> precedence than any arithmetic operator.
>
> I'm curious how this should be parsed so let's break this down.
>
> Given the following "Script" (I don't think the actual goal matters much
> here):
> ```
> x=x=>{}/alert(1)/+alert(2)//
> ```
>
> Script :
> ScriptBody opt
>
> ScriptBody :
> StatementList
>
> StatementList [Yield, Return] :
> StatementListItem [?Yield, ?Return]
> StatementList [?Yield, ?Return] StatementListItem [?Yield, ?Return]
>
> StatementListItem [Yield, Return] :
> Statement [?Yield, ?Return]
> Declaration [?Yield]
>
> Statement [Yield, Return] :
> BlockStatement [?Yield, ?Return]
> VariableStatement [?Yield]
> EmptyStatement
> ExpressionStatement [?Yield]
> ... (trunced)
>
> ExpressionStatement [Yield] :
> [lookahead ∉ { { , function , class , let [ }] Expression [In, ?Yield] ;
>
> Expression [In, Yield] :
> AssignmentExpression [?In, ?Yield]
> Expression [?In, ?Yield] , AssignmentExpression [?In, ?Yield]
>
> AssignmentExpression [In, Yield] :
> ConditionalExpression [?In, ?Yield]
> [+Yield]
> YieldExpression [?In]
> ArrowFunction [?In, ?Yield]LeftHandSideExpression [?Yield] =
> AssignmentExpression [?In, ?Yield]
> LeftHandSideExpression [?Yield] AssignmentOperator
> AssignmentExpression [?In, ?Yield]
>
> I hope we can agree that the leading `x=` is consumed by
> "LeftHandSideExpression [?Yield] AssignmentOperator" in the very last
> rule above. Proceeding with "AssignmentExpression" from the arrow arg.
>
> Note that there is no other rule that applies up to this point.
>
> ArrowFunction [In, Yield] :
> ArrowParameters [?Yield] [no LineTerminator here] => ConciseBody [?In]
>
> ArrowParameters [Yield] :
> BindingIdentifier [?Yield]
> CoverParenthesizedExpressionAndArrowParameterList [?Yield]
>
> Here "CoverParenthesizedExpressionAndArrowParameterList" will consume
> the second `x` and then the only rule in "ArrowFunction" will consume
> the arrow (`=>`). Continueing to parse the remainder
> `{}/alert(1)/+alert(2)//` starting at "ConciseBody".
>
> ConciseBody [In] :
> [lookahead ≠ {] AssignmentExpression [?In]
> { FunctionBody }
>
> Obviously only the second rule applies so we parse the function body
> and the curlies. We parse greedy but the function body is empty so
> only the next two chars are consumed (`{}`). Parser has
> `/alert(1)/+alert(2)//` left to parse and the "Statement" rule has
> depleted it's options. So we go back to "StatementList" and parse
> another statement. This should result in a regular expression, a plus
> operator, a call expression, and a single line comment.
>
> I don't think there's a rule here that allows parsing operators after
> an explicit arrow function body as being part of the arrow function.
> In fact, I remember that this was explicitly designed this way to
> prevent this ambiguity. Beyond that I agree that it parses similar to
> function expressions.
>
> If this was wrong I'd love to know the right way to parse this.
>
> - peter
>
>
>
> On Wed, May 24, 2017 at 9:18 AM, Andreas Rossberg <rossberg at google.com>
> wrote:
> > On 24 May 2017 at 08:57, Gareth Heyes <gareth.heyes at portswigger.net>
> wrote:
> >>
> >>
> >>>
> >>> you'll get a SyntaxError in all browsers but Edge, which interprets it
> as
> >>> `(x => {}) * alert(1)`.
> >>>
> >>> Given how confusing that expression is, I think that the SyntaxError is
> >>> the right choice.
> >>
> >>
> >> Well it is a function expression. So IMO Edge is right. It's equivalent
> >> to:
> >> x=function(){} * alert(1)
> >
> >
> > Edge is wrong. Unlike an ordinary function expression, which is a
> > PrimaryExpression, an arrow function is merely an AssigmentExpression, so
> > has much lower precedence than any arithmetic operator. The rationale is
> > that its body doesn't necessarily have braces, so `x => x * 1` would be
> > ambiguous.
> >
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170524/10b9c2ab/attachment-0001.html>
More information about the es-discuss
mailing list