Backed out changeset e85a00771f86 (bug 1322273) for assertion failures
authorIris Hsiao <ihsiao@mozilla.com>
Wed, 22 Feb 2017 10:33:56 +0800
changeset 390761 e93cf8e37f4fa79ef679e828172971c87d3e81b0
parent 390760 f7fd37690c35748b2069a5fab4078e2c444e6263
child 390762 e3aead1e9d17e8268314fade1a65f2d8aa6a34d4
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1322273
milestone54.0a1
backs oute85a00771f868560e43662d1dd349ddae1237924
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
Backed out changeset e85a00771f86 (bug 1322273) for assertion failures
js/xpconnect/tests/unit/test_nuke_sandbox.js
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/tests/unit/test_nuke_sandbox.js
+++ b/js/xpconnect/tests/unit/test_nuke_sandbox.js
@@ -1,54 +1,29 @@
 /* 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/. */
 
 /* See https://bugzilla.mozilla.org/show_bug.cgi?id=769273 */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-const global = this;
-
 function run_test()
 {
-  var ifacePointer = Cc["@mozilla.org/supports-interface-pointer;1"]
-      .createInstance(Ci.nsISupportsInterfacePointer);
-
-  var sb = Cu.Sandbox(global);
+  var sb = Components.utils.Sandbox("http://www.blah.com");
   sb.prop = "prop"
-  sb.ifacePointer = ifacePointer
-
-  var refToObjFromSb = Cu.evalInSandbox(`
-    Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-    ifacePointer.data = {
-      QueryInterface: XPCOMUtils.generateQI([]),
-      wrappedJSObject: {foo: "bar"},
-    };
-
-    var a = {prop2:'prop2'};
-    a
-  `, sb);
-
-  equal(ifacePointer.data.wrappedJSObject.foo, "bar",
-        "Got expected wrapper into sandbox")
-
-  Cu.nukeSandbox(sb);
-  ok(Cu.isDeadWrapper(sb), "sb should be dead");
-  ok(Cu.isDeadWrapper(ifacePointer.data.wrappedJSObject),
-     "Wrapper retrieved via XPConnect should be dead");
-
+  var refToObjFromSb = Components.utils.evalInSandbox("var a = {prop2:'prop2'}; a", sb); 
+  Components.utils.nukeSandbox(sb);
+  do_check_true(Components.utils.isDeadWrapper(sb), "sb should be dead");
   try{
     sb.prop;
     do_check_true(false);
   } catch (e) {
     do_check_true(e.toString().indexOf("can't access dead object") > -1);
   }
-
+  
   Components.utils.isDeadWrapper(refToObjFromSb, "ref to object from sb should be dead");
   try{
     refToObjFromSb.prop2;
     do_check_true(false);
   } catch (e) {
     do_check_true(e.toString().indexOf("can't access dead object") > -1);
   }
+  
 }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -176,34 +176,16 @@ WrapperFactory::PrepareForWrapping(JSCon
         }
         MOZ_ASSERT(js::IsWindowProxy(obj));
         // We crossed a compartment boundary there, so may now have a gray
         // object.  This function is not allowed to return gray objects, so
         // don't do that.
         ExposeObjectToActiveJS(obj);
     }
 
-    // If we've somehow gotten to this point after either the source or target
-    // compartment has been nuked, return a DeadObjectProxy to prevent further
-    // access.
-    JSCompartment* origin = js::GetObjectCompartment(obj);
-    JSCompartment* target = js::GetObjectCompartment(scope);
-    if (CompartmentPrivate::Get(origin)->wasNuked ||
-        CompartmentPrivate::Get(target)->wasNuked) {
-        NS_WARNING("Trying to create a wrapper into or out of a nuked compartment");
-
-        RootedObject ccw(cx, Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton));
-
-        NukeCrossCompartmentWrapper(cx, ccw);
-
-        retObj.set(ccw);
-        return;
-    }
-
-
     // If we've got a WindowProxy, there's nothing special that needs to be
     // done here, and we can move on to the next phase of wrapping. We handle
     // this case first to allow us to assert against wrappers below.
     if (js::IsWindowProxy(obj)) {
         retObj.set(waive ? WaiveXray(cx, obj) : obj);
         return;
     }
 
@@ -345,20 +327,18 @@ WrapperFactory::PrepareForWrapping(JSCon
 }
 
 #ifdef DEBUG
 static void
 DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper* handler,
                         JSCompartment* origin, JSCompartment* target)
 {
     if (CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked) {
-        // If either compartment has already been nuked, we should have returned
-        // a dead wrapper from our prewrap callback, and this function should
-        // not be called.
-        MOZ_ASSERT_UNREACHABLE("CheckUnwrapSafety called for a dead wrapper");
+        // If either compartment has already been nuked, we should have an opaque wrapper.
+        MOZ_ASSERT(handler->hasSecurityPolicy());
     } else if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) {
         // If the caller is chrome (or effectively so), unwrap should always be allowed.
         MOZ_ASSERT(!handler->hasSecurityPolicy());
     } else if (CompartmentPrivate::Get(origin)->forcePermissiveCOWs) {
         // Similarly, if this is a privileged scope that has opted to make itself
         // accessible to the world (allowed only during automation), unwrap should
         // be allowed.
         MOZ_ASSERT(!handler->hasSecurityPolicy());
@@ -472,19 +452,31 @@ WrapperFactory::Rewrap(JSContext* cx, Ha
     bool sameOrigin = targetSubsumesOrigin && originSubsumesTarget;
 
     const Wrapper* wrapper;
 
     //
     // First, handle the special cases.
     //
 
+    // If we've somehow gotten to this point after either the source or target
+    // compartment has been nuked, return an opaque wrapper to prevent further
+    // access.
+    // Ideally, we should return a DeadProxyObject instead of a wrapper in this
+    // case (bug 1322273).
+    if (CompartmentPrivate::Get(origin)->wasNuked ||
+        CompartmentPrivate::Get(target)->wasNuked) {
+        NS_WARNING("Trying to create a wrapper into or out of a nuked compartment");
+
+        wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
+    }
+
     // If UniversalXPConnect is enabled, this is just some dumb mochitest. Use
     // a vanilla CCW.
-    if (xpc::IsUniversalXPConnectEnabled(target)) {
+    else if (xpc::IsUniversalXPConnectEnabled(target)) {
         CrashIfNotInAutomation();
         wrapper = &CrossCompartmentWrapper::singleton;
     }
 
     // Let the SpecialPowers scope make its stuff easily accessible to content.
     else if (CompartmentPrivate::Get(origin)->forcePermissiveCOWs) {
         CrashIfNotInAutomation();
         wrapper = &CrossCompartmentWrapper::singleton;