Bug 1273251: Part 2 - Mark extension window compartments as nuked, and nuke all wrappers. r?mccr8 draft
authorKris Maglione <maglione.k@gmail.com>
Mon, 14 Nov 2016 08:05:00 -0800
changeset 440648 ccf57291e2b56650eff94d44f6bd09ff267232b5
parent 440647 2de38a7d10d48e8afb28bb929f4557197db782a5
child 440649 30b422627c215456cd5cbdc01d6be2edae05b183
push id36285
push usermaglione.k@gmail.com
push dateThu, 17 Nov 2016 23:17:43 +0000
reviewersmccr8
bugs1273251
milestone52.0a1
Bug 1273251: Part 2 - Mark extension window compartments as nuked, and nuke all wrappers. r?mccr8 MozReview-Commit-ID: E0ImYZIgEjU
dom/base/nsGlobalWindow.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9106,23 +9106,39 @@ public:
     nsCOMPtr<nsISupports> window = do_QueryReferent(mWindow);
     if (!skipNukeCrossCompartment && window) {
       nsGlobalWindow* win = nsGlobalWindow::FromSupports(window);
       nsGlobalWindow* currentInner = win->IsInnerWindow() ? win : win->GetCurrentInnerWindowInternal();
       NS_ENSURE_TRUE(currentInner, NS_OK);
 
       AutoSafeJSContext cx;
       JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
-      // We only want to nuke wrappers for the chrome->content case
       if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
-        js::NukeCrossCompartmentWrappers(cx,
-                                         BrowserCompartmentMatcher(),
-                                         js::SingleCompartment(js::GetObjectCompartment(obj)),
-                                         win->IsInnerWindow() ? js::DontNukeWindowReferences
-                                                              : js::NukeWindowReferences);
+        JSCompartment* cpt = js::GetObjectCompartment(obj);
+        nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
+
+        nsAutoString addonId;
+        if (NS_SUCCEEDED(pc->GetAddonId(addonId)) && !addonId.IsEmpty()) {
+          // We want to nuke all references to the add-on compartment.
+          js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(),
+                                           js::SingleCompartment(cpt),
+                                           win->IsInnerWindow() ? js::DontNukeWindowReferences
+                                                                : js::NukeWindowReferences);
+
+          // Now mark the compartment as nuked and non-scriptable.
+          auto compartmentPrivate = xpc::CompartmentPrivate::Get(cpt);
+          compartmentPrivate->wasNuked = true;
+          compartmentPrivate->scriptability.Block();
+        } else {
+          // We only want to nuke wrappers for the chrome->content case
+          js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(),
+                                           js::SingleCompartment(cpt),
+                                           win->IsInnerWindow() ? js::DontNukeWindowReferences
+                                                                : js::NukeWindowReferences);
+        }
       }
     }
 
     return NS_OK;
   }
 
 private:
   uint64_t mID;