Bug 1157127. When reusing the global of an initial about:blank for a new document, clear out its XBL scope when we change the global's principal. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 22 Jul 2016 16:19:52 -0400
changeset 306305 fcfd05dd7d14472c6f5df5ecdb58019b2fce93f3
parent 306304 ab1504ebfbde99e2f432fd618cdbd0da6ff2cb7b
child 306306 b45c5745abc0cd63b8352465f4a1db907a423779
push id79823
push userbzbarsky@mozilla.com
push dateFri, 22 Jul 2016 20:20:07 +0000
treeherdermozilla-inbound@fcfd05dd7d14 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1157127
milestone50.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 1157127. When reusing the global of an initial about:blank for a new document, clear out its XBL scope when we change the global's principal. r=bholley
dom/base/nsGlobalWindow.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/reftests/bugs/1157127-1-ref.html
layout/reftests/bugs/1157127-1.html
layout/reftests/bugs/1157127-subframe.xml
layout/reftests/bugs/reftest.list
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2740,18 +2740,26 @@ nsGlobalWindow::SetNewDocument(nsIDocume
     JSCompartment *compartment = js::GetObjectCompartment(newInnerGlobal);
 #ifdef DEBUG
     bool sameOrigin = false;
     nsIPrincipal *existing =
       nsJSPrincipals::get(JS_GetCompartmentPrincipals(compartment));
     aDocument->NodePrincipal()->Equals(existing, &sameOrigin);
     MOZ_ASSERT(sameOrigin);
 #endif
-    JS_SetCompartmentPrincipals(compartment,
-                                nsJSPrincipals::get(aDocument->NodePrincipal()));
+    MOZ_ASSERT_IF(aDocument == oldDoc,
+                  xpc::GetCompartmentPrincipal(compartment) ==
+                  aDocument->NodePrincipal());
+    if (aDocument != oldDoc) {
+      JS_SetCompartmentPrincipals(compartment,
+                                  nsJSPrincipals::get(aDocument->NodePrincipal()));
+      // Make sure we clear out the old content XBL scope, so the new one will
+      // get created with a principal that subsumes our new principal.
+      xpc::ClearContentXBLScope(newInnerGlobal);
+    }
   } else {
     if (aState) {
       newInnerWindow = wsh->GetInnerWindow();
       newInnerGlobal = newInnerWindow->GetWrapperPreserveColor();
     } else {
       if (thisChrome) {
         newInnerWindow = nsGlobalChromeWindow::Create(this);
       } else if (mIsModalContentWindow) {
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -370,16 +370,22 @@ AllowContentXBLScope(JSCompartment* c)
 
 bool
 UseContentXBLScope(JSCompartment* c)
 {
   XPCWrappedNativeScope* scope = CompartmentPrivate::Get(c)->scope;
   return scope && scope->UseContentXBLScope();
 }
 
+void
+ClearContentXBLScope(JSObject* global)
+{
+    CompartmentPrivate::Get(global)->scope->ClearContentXBLScope();
+}
+
 } /* namespace xpc */
 
 JSObject*
 XPCWrappedNativeScope::EnsureAddonScope(JSContext* cx, JSAddonId* addonId)
 {
     JS::RootedObject global(cx, GetGlobalJSObject());
     MOZ_ASSERT(js::IsObjectInContextCompartment(global, cx));
     MOZ_ASSERT(!mIsContentXBLScope);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1010,16 +1010,17 @@ public:
 
     XPCWrappedNativeScope(JSContext* cx, JS::HandleObject aGlobal);
 
     nsAutoPtr<JSObject2JSObjectMap> mWaiverWrapperMap;
 
     bool IsContentXBLScope() { return mIsContentXBLScope; }
     bool AllowContentXBLScope();
     bool UseContentXBLScope() { return mUseContentXBLScope; }
+    void ClearContentXBLScope() { mContentXBLScope = nullptr; }
 
     bool IsAddonScope() { return mIsAddonScope; }
 
     bool HasInterposition() { return mInterposition; }
     nsCOMPtr<nsIAddonInterposition> GetInterposition();
 
     static bool SetAddonInterposition(JSContext* cx,
                                       JSAddonId* addonId,
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -118,16 +118,21 @@ AllowContentXBLScope(JSCompartment* c);
 
 // Returns whether we will use an XBL scope for this compartment. This is
 // semantically equivalent to comparing global != GetXBLScope(global), but it
 // does not have the side-effect of eagerly creating the XBL scope if it does
 // not already exist.
 bool
 UseContentXBLScope(JSCompartment* c);
 
+// Clear out the content XBL scope (if any) on the given global.  This will
+// force creation of a new one if one is needed again.
+void
+ClearContentXBLScope(JSObject* global);
+
 bool
 IsInAddonScope(JSObject* obj);
 
 JSObject*
 GetAddonScope(JSContext* cx, JS::HandleObject contentScope, JSAddonId* addonId);
 
 bool
 IsSandboxPrototypeProxy(JSObject* obj);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1157127-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<body>
+  <script>
+    var ifr = document.createElement("iframe");
+    ifr.src = "1157127-subframe.xml";
+    document.body.appendChild(ifr);
+
+    var doc = ifr.contentDocument;
+    var div = doc.createElement("div");
+    div.style.resize = "both";
+    div.style.overflow = "scroll";
+    doc.body.appendChild(div);
+    div.offsetWidth;
+  </script>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1157127-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<body>
+  <script>
+    document.domain = document.domain;
+    var ifr = document.createElement("iframe");
+    ifr.src = "1157127-subframe.xml";
+    document.body.appendChild(ifr);
+
+    var doc = ifr.contentDocument;
+    var div = doc.createElement("div");
+    div.style.resize = "both";
+    div.style.overflow = "scroll";
+    doc.body.appendChild(div);
+    div.offsetWidth;
+  </script>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1157127-subframe.xml
@@ -0,0 +1,1 @@
+<root/>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1924,16 +1924,17 @@ skip-if(!B2G) == 1133905-4-vh-rtl.html 1
 skip-if(!B2G) fuzzy-if(B2G,102,577) == 1133905-5-vh-rtl.html 1133905-ref-vh-rtl.html
 skip-if(!B2G) fuzzy-if(B2G,102,877) == 1133905-6-vh-rtl.html 1133905-ref-vh-rtl.html
 skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul
 == 1151145-1.html 1151145-1-ref.html
 == 1151306-1.html 1151306-1-ref.html
 == 1153845-1.html 1153845-1-ref.html
 == 1155828-1.html 1155828-1-ref.html
 == 1156129-1.html 1156129-1-ref.html
+pref(dom.use_xbl_scopes_for_remote_xul,true) HTTP(..) == 1157127-1.html 1157127-1-ref.html
 == 1169331-1.html 1169331-1-ref.html
 fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html
 == 1179078-1.html 1179078-1-ref.html
 == 1179288-1.html 1179288-1-ref.html
 == 1190635-1.html 1190635-1-ref.html
 == 1202512-1.html 1202512-1-ref.html
 == 1202512-2.html 1202512-2-ref.html
 != 1207326-1.html about:blank