Permalink
Browse files

[CVE-2017-0028] Fix binding of 'async' identifier in the presence of …

…async arrow function.
  • Loading branch information...
pleath authored and MikeHolman committed Jan 12, 2017
1 parent b7854cd commit 402f3d967c0a905ec5b9ca9c240783d3f2c15724
Showing with 28 additions and 1 deletion.
  1. +20 −0 lib/Parser/Parse.cpp
  2. +8 −1 test/es6/lambda-params-shadow.js
View
@@ -2863,6 +2863,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
_Inout_opt_ charcount_t *plastRParen /*= nullptr*/)
{
ParseNodePtr pnode = nullptr;
PidRefStack *savedTopAsyncRef = nullptr;
charcount_t ichMin = 0;
size_t iecpMin = 0;
size_t iuMin;
@@ -2915,6 +2916,13 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
isLambdaExpr = true;
goto LFunction;
}
else if (m_token.tk == tkLParen)
{
// This is potentially an async arrow function. Save the state of the async references
// in case it needs to be restored. (Note that the case of a single parameter with no ()'s
// is detected upstream and need not be handled here.)
savedTopAsyncRef = pid->GetTopRef();
}
}
// Don't push a reference if this is a single lambda parameter, because we'll reparse with
@@ -3269,6 +3277,18 @@ LFunction :
pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, isAsyncExpr, &fCanAssign, &term, pfIsDotOrIndex);
if (savedTopAsyncRef != nullptr &&
this->m_token.tk == tkDArrow)
{
// This is an async arrow function; we're going to back up and reparse it.
// Make sure we don't leave behind a bogus reference to the 'async' identifier.
for (IdentPtr pid = wellKnownPropertyPids.async; pid->GetTopRef() != savedTopAsyncRef;)
{
Assert(pid->GetTopRef() != nullptr);
pid->RemovePrevPidRef(nullptr);
}
}
// Pass back identifier if requested
if (pToken && term.tk == tkID)
{
@@ -18,7 +18,14 @@ class B extends A {
}
}
let b = new B();
if (count !== 3) {
class async extends A {
constructor() {
super();
let Q = async A => { A };
}
}
let a = new async();
if (count !== 4) {
WScript.Echo('fail');
}

0 comments on commit 402f3d9

Please sign in to comment.