Skip to content

Commit ed98335

Browse files
committed
[MERGE #5734 @wyrichte] Fixes #5576 - Chakra should not redeclare "undefined" keyword
Merge pull request #5734 from wyrichte:build/wyrichte/5576_1 Fixed by adding opcode OP_EnsureNoRootRedeclFunc that enforces the section of #sec-globaldeclarationinstantiation where #CanDeclareGlobalFunction is called. This enforces that when a global function that is not configurable, not writable, and not enumerable is overwritten a TypeError is thrown.
2 parents b9b758c + 8ecdb9e commit ed98335

26 files changed

+1074
-817
lines changed

lib/Backend/JnHelperMethodList.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ HELPERCALLCHK(Op_LdElemUndefDynamic, Js::JavascriptOperators::OP_LoadUndefinedTo
6666
HELPERCALLCHK(Op_LdElemUndefScoped, Js::JavascriptOperators::OP_LoadUndefinedToElementScoped, AttrCanNotBeReentrant)
6767
HELPERCALLCHK(Op_EnsureNoRootProperty, Js::JavascriptOperators::OP_EnsureNoRootProperty, AttrCanThrow | AttrCanNotBeReentrant)
6868
HELPERCALLCHK(Op_EnsureNoRootRedeclProperty, Js::JavascriptOperators::OP_EnsureNoRootRedeclProperty, AttrCanThrow | AttrCanNotBeReentrant)
69+
HELPERCALLCHK(Op_EnsureCanDeclGloFunc, Js::JavascriptOperators::OP_EnsureCanDeclGloFunc, AttrCanThrow | AttrCanNotBeReentrant)
6970
HELPERCALLCHK(Op_EnsureNoRedeclPropertyScoped, Js::JavascriptOperators::OP_ScopedEnsureNoRedeclProperty, AttrCanThrow | AttrCanNotBeReentrant)
7071

7172
HELPERCALLCHK(Op_ToSpreadedFunctionArgument, Js::JavascriptOperators::OP_LdCustomSpreadIteratorList, AttrCanThrow)

lib/Backend/Lower.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2491,6 +2491,10 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
24912491
this->LowerElementUndefined(instr, IR::HelperOp_EnsureNoRootRedeclProperty);
24922492
break;
24932493

2494+
case Js::OpCode::EnsureCanDeclGloFunc:
2495+
this->LowerElementUndefined(instr, IR::HelperOp_EnsureCanDeclGloFunc);
2496+
break;
2497+
24942498
case Js::OpCode::ScopedEnsureNoRedeclFld:
24952499
this->LowerElementUndefinedScoped(instr, IR::HelperOp_EnsureNoRedeclPropertyScoped);
24962500
break;

lib/Parser/rterrors.h

+1
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ RT_ERROR_MSG(JSERR_RegExpTooManyCapturingGroups, 5675, "", "Regular expression c
370370
RT_ERROR_MSG(JSERR_ProxyHandlerReturnedFalse, 5676, "Proxy %s handler returned false", "Proxy handler returned false", kjstTypeError, 0)
371371
RT_ERROR_MSG(JSERR_UnicodeRegExpRangeContainsCharClass, 5677, "%s", "Character classes not allowed in a RegExp class range.", kjstSyntaxError, 0)
372372
RT_ERROR_MSG(JSERR_DuplicateKeysFromOwnPropertyKeys, 5678, "%s", "Proxy's ownKeys trap returned duplicate keys", kjstTypeError, 0)
373+
RT_ERROR_MSG(JSERR_InvalidGloFuncDecl, 5679, "The global property %s is not configurable, writable, nor enumerable, therefore cannot be declared as a function", "", kjstTypeError, 0)
373374

374375
//Host errors
375376
RT_ERROR_MSG(JSERR_HostMaybeMissingPromiseContinuationCallback, 5700, "", "Host may not have set any promise continuation callback. Promises may not be executed.", kjstTypeError, 0)

lib/Runtime/ByteCode/ByteCodeCacheReleaseFileVersion.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
//-------------------------------------------------------------------------------------------------------
55
// NOTE: If there is a merge conflict the correct fix is to make a new GUID.
66

7-
// {BFA0BED0-7B1A-4018-83DA-B1D989D38BFD}
7+
// {9FAAF688-ACBA-4092-BA5B-77D97D3CD53A}
88
const GUID byteCodeCacheReleaseFileVersion =
9-
{ 0xBFA0BED0, 0x7B1A, 0x4018, { 0x83, 0xDA, 0xB1, 0xD9, 0x89, 0xD3, 0x8B, 0xFD } };
9+
{ 0x9FAAF688, 0xACBA, 0x4092, { 0xBA, 0x5B, 0x77, 0xD9, 0x7D, 0x3C, 0xD5, 0x3A } };

lib/Runtime/ByteCode/ByteCodeDumper.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,11 @@ namespace Js
630630
Output::Print(_u(" root.%s"), pPropertyName->GetBuffer());
631631
break;
632632
}
633+
case OpCode::EnsureCanDeclGloFunc:
634+
{
635+
Output::Print(_u(" root.%s"), pPropertyName->GetBuffer());
636+
break;
637+
}
633638
case OpCode::LdLocalElemUndef:
634639
{
635640
Output::Print(_u(" %s = undefined"), pPropertyName->GetBuffer());

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -5588,10 +5588,17 @@ void ByteCodeGenerator::EnsureNoRedeclarations(ParseNodeBlock *pnodeBlock, FuncI
55885588
});
55895589
}
55905590

5591-
auto emitRedeclCheck = [this](Symbol * sym, FuncInfo * funcInfo)
5591+
auto emitRedeclCheck = [this](Symbol * sym, FuncInfo * funcInfo, bool isFncDecl = false)
55925592
{
55935593
Js::PropertyId propertyId = sym->EnsurePosition(this);
55945594

5595+
// Global function declarations must pass #sec-candeclareglobalfunction
5596+
// which is enforced by EnsureCanDeclGloFunc
5597+
if (isFncDecl)
5598+
{
5599+
this->m_writer.ElementRootU(Js::OpCode::EnsureCanDeclGloFunc, funcInfo->FindOrAddReferencedPropertyId(propertyId));
5600+
}
5601+
55955602
if (this->flags & fscrEval)
55965603
{
55975604
if (!funcInfo->byteCodeFunction->GetIsStrictMode())
@@ -5615,7 +5622,7 @@ void ByteCodeGenerator::EnsureNoRedeclarations(ParseNodeBlock *pnodeBlock, FuncI
56155622
case knopFncDecl:
56165623
if (pnode->AsParseNodeFnc()->IsDeclaration())
56175624
{
5618-
emitRedeclCheck(pnode->AsParseNodeFnc()->pnodeName->sym, funcInfo);
5625+
emitRedeclCheck(pnode->AsParseNodeFnc()->pnodeName->sym, funcInfo, true);
56195626
}
56205627

56215628
pnode = pnode->AsParseNodeFnc()->pnodeNext;

lib/Runtime/ByteCode/OpCodes.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@
7171
MACRO_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7272

7373
#define MACRO_EXTENDED_ROOT(opcode, layout, attr) \
74-
MACRO_EXTENDED_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
74+
MACRO_EXTEND_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7575

7676
#define MACRO_EXTEND_WMS_ROOT(opcode, layout, attr) \
77-
MACRO_EXTENDED_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
77+
MACRO_EXTEND_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7878

7979
#define MACRO_WMS_PROFILED( opcode, layout, attr) \
8080
MACRO_WMS(opcode, layout, OpHasProfiled|attr) \
@@ -354,6 +354,7 @@ MACRO_WMS( ChkUndecl, Reg1, OpSideEffect
354354

355355
MACRO_WMS_ROOT( EnsureNoRootFld, ElementRootU, OpSideEffect)
356356
MACRO_WMS_ROOT( EnsureNoRootRedeclFld, ElementRootU, OpSideEffect)
357+
MACRO_EXTEND_WMS_ROOT( EnsureCanDeclGloFunc, ElementRootU, OpSideEffect)
357358
MACRO_WMS( ScopedEnsureNoRedeclFld, ElementScopedC, OpSideEffect)
358359

359360
MACRO_WMS( InitUndecl, Reg1, OpCanCSE)

lib/Runtime/Language/InterpreterHandler.inl

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ EXDEF2_WMS(A2toXX, SetComputedNameVar, JavascriptOperat
142142
DEF2_WMS(XXtoA1, InitUndecl, OP_InitUndecl)
143143
DEF2_WMS(ELEM_RtU_to_XX, EnsureNoRootFld, OP_EnsureNoRootProperty)
144144
DEF2_WMS(ELEM_RtU_to_XX, EnsureNoRootRedeclFld, OP_EnsureNoRootRedeclProperty)
145+
EXDEF2_WMS(ELEM_RtU_to_XX, EnsureCanDeclGloFunc, OP_EnsureCanDeclGloFunc)
145146
DEF2_WMS(ELEM_C2_to_XX, ScopedEnsureNoRedeclFld, OP_ScopedEnsureNoRedeclProperty)
146147
DEF2_WMS(A1toA1Profiled, ProfiledBeginSwitch, PROFILEDOP(ProfiledSwitch<true>, ProfiledSwitch<false>))
147148
DEF2_WMS(XXtoA1Mem, LdC_A_Null, JavascriptOperators::OP_LdNull)

lib/Runtime/Language/InterpreterStackFrame.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -6526,6 +6526,12 @@ namespace Js
65266526
JavascriptOperators::OP_EnsureNoRootRedeclProperty(instance, this->m_functionBody->GetReferencedPropertyId(propertyIdIndex));
65276527
}
65286528

6529+
void InterpreterStackFrame::OP_EnsureCanDeclGloFunc(uint propertyIdIndex)
6530+
{
6531+
Var instance = this->GetRootObject();
6532+
JavascriptOperators::OP_EnsureCanDeclGloFunc(instance, this->m_functionBody->GetReferencedPropertyId(propertyIdIndex));
6533+
}
6534+
65296535
void InterpreterStackFrame::OP_ScopedEnsureNoRedeclProperty(Var aValue, uint propertyIdIndex, Var aValue2)
65306536
{
65316537
Js::PropertyId propertyId = this->m_functionBody->GetReferencedPropertyId(propertyIdIndex);

lib/Runtime/Language/InterpreterStackFrame.h

+1
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ namespace Js
656656

657657
void OP_EnsureNoRootProperty(uint propertyIdIndex);
658658
void OP_EnsureNoRootRedeclProperty(uint propertyIdIndex);
659+
void OP_EnsureCanDeclGloFunc(uint propertyIdIndex);
659660
void OP_ScopedEnsureNoRedeclProperty(Var aValue, uint propertyIdIndex, Var aValue2);
660661
Var OP_InitUndecl();
661662
void OP_InitUndeclSlot(Var aValue, int32 slot);

lib/Runtime/Language/JavascriptOperators.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -7572,6 +7572,15 @@ using namespace Js;
75727572
JIT_HELPER_END(Op_EnsureNoRootRedeclProperty);
75737573
}
75747574

7575+
void JavascriptOperators::OP_EnsureCanDeclGloFunc(Var instance, PropertyId propertyId)
7576+
{
7577+
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Op_EnsureCanDeclGloFunc);
7578+
Assert(VarIs<RootObjectBase>(instance));
7579+
RootObjectBase *obj = VarTo<RootObjectBase>(instance);
7580+
obj->EnsureCanDeclGloFunc(propertyId);
7581+
JIT_HELPER_END(Op_EnsureCanDeclGloFunc);
7582+
}
7583+
75757584
void JavascriptOperators::OP_ScopedEnsureNoRedeclProperty(FrameDisplay *pDisplay, PropertyId propertyId, Var defaultInstance)
75767585
{
75777586
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Op_EnsureNoRedeclPropertyScoped);

lib/Runtime/Language/JavascriptOperators.h

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ namespace Js
173173
static BOOL EnsureProperty(Var instance, PropertyId propertyId);
174174
static void OP_EnsureNoRootProperty(Var instance, PropertyId propertyId);
175175
static void OP_EnsureNoRootRedeclProperty(Var instance, PropertyId propertyId);
176+
static void OP_EnsureCanDeclGloFunc(Var instance, PropertyId propertyId);
176177
static void OP_ScopedEnsureNoRedeclProperty(FrameDisplay *pDisplay, PropertyId propertyId, Var instanceDefault);
177178
static JavascriptArray* GetOwnPropertyNames(Var instance, ScriptContext *scriptContext);
178179
static JavascriptArray* GetOwnPropertySymbols(Var instance, ScriptContext *scriptContext);

0 commit comments

Comments
 (0)