Skip to content

Commit

Permalink
[CVE-2017-0152] MSFT: 10592731 : Issue with Function name capturing i…
Browse files Browse the repository at this point in the history
…n param scope

In a function expression with name, where the name is captured in one
of the param scope functions, if there is a function or var declaration
with the same name as the function expression name we were marking the
function expression name as shadowed. In non-eval case this causes
issue because the name symbol won't get added to the body. This change is to
fix it in such a way if the name is captured in the param scope then we
split the param and body scope such that the name symbol is added to the
param scope not body scope.
  • Loading branch information
aneeshdk authored and MikeHolman committed Mar 16, 2017
1 parent b75b9e8 commit 9da0194
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
13 changes: 13 additions & 0 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5198,6 +5198,19 @@ bool Parser::ParseFncDeclHelper(ParseNodePtr pnodeFnc, LPCOLESTR pNameHint, usho
paramScope->SetCannotMergeWithBodyScope();
}
}
if (paramScope->GetCanMergeWithBodyScope() && !fDeclaration && pnodeFnc->sxFnc.pnodeName != nullptr)
{
Symbol* funcSym = pnodeFnc->sxFnc.pnodeName->sxVar.sym;
if (funcSym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->sxFnc.functionId)
{
// This is a function expression with name captured in the param scope. In non-eval, non-split cases the function
// name symbol is added to the body scope to make it accessible in the body. But if there is a function or var
// declaration with the same name in the body then adding to the body will fail. So in this case we have to add
// the name symbol to the param scope by splitting it.
paramScope->SetCannotMergeWithBodyScope();
}
}

}
}

Expand Down
5 changes: 4 additions & 1 deletion lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3319,6 +3319,7 @@ void ByteCodeGenerator::EmitOneFunction(ParseNode *pnode)
{
// Emit bytecode to copy the initial values from param names to their corresponding body bindings.
// We have to do this after the rest param is marked as false for need declaration.
Symbol* funcSym = funcInfo->root->sxFnc.GetFuncSymbol();
paramScope->ForEachSymbol([&](Symbol* param) {
Symbol* varSym = funcInfo->GetBodyScope()->FindLocalSymbol(param->GetName());
Assert(varSym || pnode->sxFnc.pnodeName->sxVar.sym == param);
Expand All @@ -3327,7 +3328,9 @@ void ByteCodeGenerator::EmitOneFunction(ParseNode *pnode)
{
// Do not copy the arguments to the body if it is not used
}
else if (varSym && varSym->GetSymbolType() == STVariable && (varSym->IsInSlot(funcInfo) || varSym->GetLocation() != Js::Constants::NoRegister))
else if ((funcSym == nullptr || funcSym != param) // Do not copy the symbol over to body as the function expression symbol
// is expected to stay inside the function expression scope
&& (varSym && varSym->GetSymbolType() == STVariable && (varSym->IsInSlot(funcInfo) || varSym->GetLocation() != Js::Constants::NoRegister)))
{
// Simulating EmitPropLoad here. We can't directly call the method as we have to use the param scope specifically.
// Walking the scope chain is not possible at this time.
Expand Down
16 changes: 16 additions & 0 deletions test/es6/default-splitscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ var tests = [
return a;
}
assert.areEqual(10, f11()(), "Recursive call to the function from the body scope returns the right value when eval is there in the body");

function f13() {
var a = function jnvgfg(sfgnmj = function ccunlk() { jnvgfg(undefined, 1); }, b) {
if (b) {
assert.areEqual(undefined, jnvgfg, "This refers to the instance in the body and the value of the function expression is not copied over");
}
var jnvgfg = 10;
if (!b) {
sfgnmj();
return 100;
}
};
assert.areEqual(100, a(), "After the recursion the right value is returned by the split scoped function");
};
f13();

}
},
{
Expand Down

0 comments on commit 9da0194

Please sign in to comment.