Pārlūkot izejas kodu

MSFT: 6967505 setInterval(alert(), 10000/237) throws Invalid calling object exception after domtimeline script is injected

In debugger when we used to put all globaobject properties in the ActivationObject and use that
as "this" pointer for global object. We should separate out the ActivationObject from GlobalObject and
use the GlobalObject as "this". Fixed a couple of issues exposed by this change.
Yong Qu 10 gadi atpakaļ
vecāks
revīzija
eaf36fe3d8

+ 2 - 5
lib/Runtime/Debug/DebugManager.cpp

@@ -125,7 +125,7 @@ namespace Js
         return (DynamicObject*)CrossSite::MarshalVar(scriptContext, (Var)this->pConsoleScope);
     }
 
-    FrameDisplay *DebugManager::GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne, bool addGlobalThisAtScopeTwo)
+    FrameDisplay *DebugManager::GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne)
     {
         // The scope chain for console eval looks like:
         //  - dummy empty object - new vars, let, consts, functions get added here
@@ -136,10 +136,7 @@ namespace Js
 
         FrameDisplay* environment = JavascriptOperators::OP_LdFrameDisplay(this->GetConsoleScope(scriptContext), const_cast<FrameDisplay *>(&NullFrameDisplay), scriptContext);
 
-        if (addGlobalThisAtScopeTwo)
-        {
-            environment = JavascriptOperators::OP_LdFrameDisplay(scriptContext->GetGlobalObject()->ToThis(), environment, scriptContext);
-        }
+        environment = JavascriptOperators::OP_LdFrameDisplay(scriptContext->GetGlobalObject()->ToThis(), environment, scriptContext);
 
         if (scopeAtOne != nullptr)
         {

+ 1 - 1
lib/Runtime/Debug/DebugManager.h

@@ -59,7 +59,7 @@ namespace Js
         MutationBreakpoint* GetActiveMutationBreakpoint() const;
 #endif
         DynamicObject* GetConsoleScope(ScriptContext* scriptContext);
-        FrameDisplay *GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne, bool addGlobalThisAtScopeTwo);
+        FrameDisplay *GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne);
         void UpdateConsoleScope(DynamicObject* copyFromScope, ScriptContext* scriptContext);
         PageAllocator * GetDiagnosticPageAllocator() { return &this->diagnosticPageAllocator; }
 #if DBG

+ 3 - 2
lib/Runtime/Debug/DiagObjectModel.cpp

@@ -1086,7 +1086,8 @@ namespace Js
 
             // In the eval function, we will not show global items directly, instead they should go as a group node.
             bool shouldAddGlobalItemsDirectly = pFBody->GetIsGlobalFunc() && !pFBody->IsEval();
-            if (shouldAddGlobalItemsDirectly)
+            bool dontAddGlobalsDirectly = (frameWalkerFlags & FrameWalkerFlags::FW_DontAddGlobalsDirectly) == FrameWalkerFlags::FW_DontAddGlobalsDirectly;
+            if (shouldAddGlobalItemsDirectly && !dontAddGlobalsDirectly)
             {
                 // Global properties will be enumerated using RootObjectVariablesWalker
                 pVarWalkers->Add(Anew(arena, RootObjectVariablesWalker, pFrame, pFrame->GetRootObject(), UIGroupType_None));
@@ -1171,7 +1172,7 @@ namespace Js
             }
 
             // No need to add global properties if this is a global function, as it is already done above.
-            if (!shouldAddGlobalItemsDirectly)
+            if (!shouldAddGlobalItemsDirectly && !dontAddGlobalsDirectly)
             {
                 pVarWalker = Anew(arena, RootObjectVariablesWalker, pFrame, pFrame->GetRootObject(),  UIGroupType_Globals);
                 pVarWalkers->Add(pVarWalker);

+ 6 - 5
lib/Runtime/Debug/DiagObjectModel.h

@@ -144,11 +144,12 @@ namespace Js
 
     enum FrameWalkerFlags
     {
-        FW_None                 = 0x0,
-        FW_MakeGroups           = 0x1,  // Make groups such as [Scope], [Globals] etc.
-        FW_EnumWithScopeAlso    = 0x2,  // While walking include the with scope as well.
-        FW_AllowLexicalThis     = 0x4,  // Do not filter out Js::PropertyIds::_lexicalThisSlotSymbol
-        FW_AllowSuperReference  = 0x8,  // Allow walking of Js::PropertyIds::_superReferenceSymbol and Js::PropertyIds::_superCtorReferenceSymbol
+        FW_None                   = 0x0,
+        FW_MakeGroups             = 0x1,  // Make groups such as [Scope], [Globals] etc.
+        FW_EnumWithScopeAlso      = 0x2,  // While walking include the with scope as well.
+        FW_AllowLexicalThis       = 0x4,  // Do not filter out Js::PropertyIds::_lexicalThisSlotSymbol
+        FW_AllowSuperReference    = 0x8,  // Allow walking of Js::PropertyIds::_superReferenceSymbol and Js::PropertyIds::_superCtorReferenceSymbol
+        FW_DontAddGlobalsDirectly = 0x10, // Do not add global object directly.
     };
 
     class VariableWalkerBase : public IDiagObjectModelWalkerBase

+ 23 - 0
lib/Runtime/Language/JavascriptOperators.cpp

@@ -2846,6 +2846,29 @@ CommonNumber:
         // If we have console scope and no one in the scope had the property add it to console scope
         if ((length > 0) && ConsoleScopeActivationObject::Is(pDisplay->GetItem(length - 1)))
         {
+            // CheckPrototypesForAccessorOrNonWritableProperty does not check for const in global object. We should check it here. 
+            if ((length > 1) && GlobalObject::Is(pDisplay->GetItem(length - 2)))
+            {
+                GlobalObject* globalObject = GlobalObject::FromVar(pDisplay->GetItem(length - 2));
+                Var setterValue = nullptr;
+
+                DescriptorFlags flags = JavascriptOperators::GetRootSetter(globalObject, propertyId, &setterValue, &info, scriptContext);
+                Assert((flags & Accessor) != Accessor);
+                Assert((flags & Proxy) != Proxy);
+                if ((flags & Data) == Data && (flags & Writable) == None)
+                {
+                    if (!allowUndecInConsoleScope)
+                    {
+                        if (flags & Const)
+                        {
+                            JavascriptError::ThrowTypeError(scriptContext, ERRAssignmentToConst);
+                        }
+                        Assert(!isLexicalThisSlotSymbol);
+                        return;
+                    }
+                }
+            }
+
             RecyclableObject* obj = RecyclableObject::FromVar((DynamicObject*)pDisplay->GetItem(length - 1));
             OUTPUT_TRACE(Js::ConsoleScopePhase, _u("Adding property '%s' to console scope object\n"), scriptContext->GetPropertyName(propertyId)->GetBuffer());
             JavascriptOperators::SetProperty(obj, obj, propertyId, newValue, scriptContext, propertyOperationFlags);