Skip to content

Commit f93a85d

Browse files
committed
OS#17542375 Correct possible overflow of deferred stubs array
When undeferring a function with deferred stubs, we try and use those stubs to determine if expressions beginning with a left paren are nested lambda functions. We do this when we see a left paren and the next deferred stub is a lambda function starting at the same character. Unfortunately we don't keep track of the count of deferred stubs in the current deferred stubs array. If all of the nested functions in the function we're undefering are located in source before the left paren character, we should not check for the next deferred stub as this would overflow the array and cause a possible AV. Fix this by tracking the count of stubs in the current deferred stubs array. Fixes: https://microsoft.visualstudio.com/OS/_workitems/edit/17542375
1 parent 20fa861 commit f93a85d

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

lib/Parser/Parse.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
9595
m_currentNodeDeferredFunc(nullptr),
9696
m_currentNodeProg(nullptr),
9797
m_currDeferredStub(nullptr),
98+
m_currDeferredStubCount(0),
9899
m_pCurrentAstSize(nullptr),
99100
m_ppnodeScope(nullptr),
100101
m_ppnodeExprScope(nullptr),
@@ -3068,7 +3069,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
30683069
// is a lambda at the current character. If it is, we know this LParen is the beginning of a lambda nested
30693070
// function and we can avoid parsing the next series of tokens as a parenthetical expression and reparsing
30703071
// after finding the => token.
3071-
if (buildAST && m_currDeferredStub != nullptr && GetCurrentFunctionNode() != nullptr)
3072+
if (buildAST && m_currDeferredStub != nullptr && GetCurrentFunctionNode() != nullptr && GetCurrentFunctionNode()->nestedCount < m_currDeferredStubCount)
30723073
{
30733074
DeferredFunctionStub* stub = m_currDeferredStub + GetCurrentFunctionNode()->nestedCount;
30743075
if (stub->ichMin == ichMin)
@@ -5577,13 +5578,17 @@ void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, us
55775578
{
55785579
*pNeedScanRCurly = false;
55795580
}
5581+
uint savedStubCount = m_currDeferredStubCount;
55805582
DeferredFunctionStub* savedStub = m_currDeferredStub;
55815583
if (pnodeFnc->IsNested() && pnodeFncSave != nullptr && m_currDeferredStub != nullptr && pnodeFncSave->ichMin != pnodeFnc->ichMin)
55825584
{
5583-
m_currDeferredStub = (m_currDeferredStub + (pnodeFncSave->nestedCount - 1))->deferredStubs;
5585+
DeferredFunctionStub* childStub = m_currDeferredStub + (pnodeFncSave->nestedCount - 1);
5586+
m_currDeferredStubCount = childStub->nestedCount;
5587+
m_currDeferredStub = childStub->deferredStubs;
55845588
}
55855589
this->FinishFncDecl(pnodeFnc, pNameHint, fLambda, skipFormals);
55865590
m_currDeferredStub = savedStub;
5591+
m_currDeferredStubCount = savedStubCount;
55875592
}
55885593
else
55895594
{
@@ -11859,6 +11864,7 @@ HRESULT Parser::ParseSourceWithOffset(__out ParseNodeProg ** parseTree, LPCUTF8
1185911864
if (m_functionBody)
1186011865
{
1186111866
m_currDeferredStub = m_functionBody->GetDeferredStubs();
11867+
m_currDeferredStubCount = m_currDeferredStub != nullptr ? m_functionBody->GetNestedCount() : 0;
1186211868
m_InAsmMode = grfscr & fscrNoAsmJs ? false : m_functionBody->GetIsAsmjsMode();
1186311869
}
1186411870
m_deferAsmJs = !m_InAsmMode;

lib/Parser/Parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ class Parser
415415
ParseNodeFnc * m_currentNodeDeferredFunc; // current function or NULL
416416
ParseNodeProg * m_currentNodeProg; // current program
417417
DeferredFunctionStub *m_currDeferredStub;
418+
uint m_currDeferredStubCount;
418419
int32 * m_pCurrentAstSize;
419420
ParseNodePtr * m_ppnodeScope; // function list tail
420421
ParseNodePtr * m_ppnodeExprScope; // function expression list tail

0 commit comments

Comments
 (0)