Bug 1482835 - Remove JS_GetCompartmentPrincipals calls in the compartment nuking code. r=mccr8
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 14 Sep 2018 17:38:57 +0000
changeset 495123 e0802d8df93ad985967484485c7d942486472f8b
parent 495122 e48187f4283ef27679e55c91908a781282ddad18
child 495124 1de6dfd1e6ed1e54e440f1d9bf18ffc579b76a3b
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1482835
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1482835 - Remove JS_GetCompartmentPrincipals calls in the compartment nuking code. r=mccr8 Differential Revision: https://phabricator.services.mozilla.com/D5856
dom/base/WindowDestroyedEvent.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
--- a/dom/base/WindowDestroyedEvent.cpp
+++ b/dom/base/WindowDestroyedEvent.cpp
@@ -1,30 +1,33 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 #include "WindowDestroyedEvent.h"
 
 #include "nsJSUtils.h"
 #include "jsapi.h"
 #include "js/Wrapper.h"
 #include "nsIPrincipal.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIAppStartup.h"
 #include "nsToolkitCompsCID.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
+#include "xpcpublic.h"
 
 namespace mozilla {
 
-// Try to match compartments that are not web content by matching compartments
-// with principals that are either the system principal or an expanded principal.
-// This may not return true for all non-web-content compartments.
 struct BrowserCompartmentMatcher : public js::CompartmentFilter {
   bool match(JS::Compartment* aC) const override
   {
-    nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(aC));
-    return nsContentUtils::IsSystemOrExpandedPrincipal(pc);
+    return !xpc::MightBeWebContentCompartment(aC);
   }
 };
 
 WindowDestroyedEvent::WindowDestroyedEvent(nsGlobalWindowInner* aWindow,
                                            uint64_t aID, const char* aTopic)
   : mozilla::Runnable("WindowDestroyedEvent")
   , mID(aID)
   , mPhase(Phase::Destroying)
@@ -107,18 +110,21 @@ WindowDestroyedEvent::Run()
           nsGlobalWindowOuter* outer = nsGlobalWindowOuter::FromSupports(window);
           currentInner = outer->GetCurrentInnerWindowInternal();
         }
         NS_ENSURE_TRUE(currentInner, NS_OK);
 
         AutoSafeJSContext cx;
         JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
         if (obj && !js::IsSystemRealm(js::GetNonCCWObjectRealm(obj))) {
-          JS::Compartment* cpt = js::GetObjectCompartment(obj);
-          nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
+          JS::Realm* realm = js::GetNonCCWObjectRealm(obj);
+          JS::Compartment* cpt = JS::GetCompartmentForRealm(realm);
+
+          nsCOMPtr<nsIPrincipal> pc =
+            nsJSPrincipals::get(JS::GetRealmPrincipals(realm));
 
           if (BasePrincipal::Cast(pc)->AddonPolicy()) {
             // We want to nuke all references to the add-on compartment.
             xpc::NukeAllWrappersForCompartment(cx, cpt,
                                                mIsInnerWindow ? js::DontNukeWindowReferences
                                                               : js::NukeWindowReferences);
           } else {
             // We only want to nuke wrappers for the chrome->content case
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -508,16 +508,35 @@ IsInSandboxCompartment(JSObject* obj)
     JS::Compartment* comp = js::GetObjectCompartment(obj);
 
     // We always eagerly create compartment privates for sandbox compartments.
     CompartmentPrivate* priv = CompartmentPrivate::Get(comp);
     return priv && priv->isSandboxCompartment;
 }
 
 bool
+CompartmentOriginInfo::MightBeWebContent() const
+{
+    // Compartments with principals that are either the system principal or an
+    // expanded principal are definitely not web content.
+    return !nsContentUtils::IsSystemOrExpandedPrincipal(mOrigin);
+}
+
+bool
+MightBeWebContentCompartment(JS::Compartment* compartment)
+{
+    if (CompartmentPrivate* priv = CompartmentPrivate::Get(compartment)) {
+        return priv->originInfo.MightBeWebContent();
+    }
+
+    // No CompartmentPrivate; try IsSystemCompartment.
+    return !js::IsSystemCompartment(compartment);
+}
+
+bool
 IsUniversalXPConnectEnabled(JS::Compartment* compartment)
 {
     CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
     if (!priv) {
         return false;
     }
     return priv->universalXPConnectEnabled;
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2927,16 +2927,18 @@ public:
       , mSite(aSite)
     {
         MOZ_ASSERT(aOrigin);
         MOZ_ASSERT(aSite.IsInitialized());
     }
 
     bool IsSameOrigin(nsIPrincipal* aOther) const;
 
+    bool MightBeWebContent() const;
+
     const mozilla::SiteIdentifier& SiteRef() const {
         return mSite;
     }
 
     bool HasChangedDocumentDomain() const {
         return mChangedDocumentDomain;
     }
     void SetChangedDocumentDomain() {
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -87,16 +87,18 @@ bool IsContentXBLScope(JS::Realm* realm)
 bool IsInContentXBLScope(JSObject* obj);
 
 bool IsUAWidgetCompartment(JS::Compartment* compartment);
 bool IsUAWidgetScope(JS::Realm* realm);
 bool IsInUAWidgetScope(JSObject* obj);
 
 bool IsInSandboxCompartment(JSObject* obj);
 
+bool MightBeWebContentCompartment(JS::Compartment* compartment);
+
 void SetCompartmentChangedDocumentDomain(JS::Compartment* compartment);
 
 // Return a raw XBL scope object corresponding to contentScope, which must
 // be an object whose global is a DOM window.
 //
 // The return value is not wrapped into cx->compartment, so be sure to enter
 // its compartment before doing anything meaningful.
 //