Bug 738874 - Don't allow non-classinfo XPCWNs to be wrapped cross-compartment. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Sun, 25 Mar 2012 22:35:50 -0700
changeset 90288 597edb1cfe21
parent 90287 28cc6bf92f1f
child 90289 178fcd971e59
push id22336
push usermbrubeck@mozilla.com
push date2012-03-26 18:22 +0000
Treeherderresults
reviewersmrbkap
bugs738874
milestone14.0a1
Bug 738874 - Don't allow non-classinfo XPCWNs to be wrapped cross-compartment. r=mrbkap
js/xpconnect/tests/chrome/test_doublewrappedcompartments.xul
js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/tests/chrome/test_doublewrappedcompartments.xul
+++ b/js/xpconnect/tests/chrome/test_doublewrappedcompartments.xul
@@ -23,22 +23,24 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
       const Ci = Components.interfaces;
       const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
                           .getInterface(Ci.nsIDOMWindowUtils);
 
       function go() {
         var wrappedWin = $('ifr').contentWindow;
+        is(typeof wrappedWin.expando, 'undefined', "Shouldn't be able to see the expando");
+
         var unwrapped = wrappedWin.wrappedJSObject;
 
-        var filter = unwrapped.filter;
-        is(utils.getClassName(filter), 'Proxy', 'properly wrapped');
-        is(typeof filter.QueryInterface, 'function', 'double wrapped');
+        var expando = unwrapped.expando;
+        is(utils.getClassName(expando), 'Proxy', 'properly wrapped');
+        is(typeof expando.QueryInterface, 'function', 'double wrapped');
 
-        ok(unwrapped.testme(filter),
+        ok(unwrapped.testme(expando),
            "content didn't get a proxy, but another double wrapped object");
         SimpleTest.finish();
       }
 
       SimpleTest.waitForExplicitFinish();
   ]]></script>
 </window>
--- a/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html
+++ b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html
@@ -1,14 +1,16 @@
 <html>
     <head>
         <script>
-            var fcn = function() {};
-            var iter = document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, fcn, false);
-            var filter = iter.filter;
+            // We want to put an expando on the object, but we want this object
+            // to be wrapped in other compartments. This means that the expando
+            // must implement precreate, which happens (in general) for nodes.
+            // So we just do a cyclic reference to the document body.
+            window.expando = document.documentElement;
 
             function testme(obj) {
                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
                 const Ci = Components.interfaces;
                 const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
                                     .getInterface(Ci.nsIDOMWindowUtils);
 
                 return utils.getClassName(obj) != "Proxy" &&
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -182,21 +182,16 @@ WrapperFactory::PrepareForWrapping(JSCon
     // those objects in a security wrapper, then we need to hand back the
     // wrapper for the new scope instead. Also, global objects don't move
     // between scopes so for those we also want to return the wrapper. So...
     if (!IS_WN_WRAPPER(obj) || !js::GetObjectParent(obj))
         return DoubleWrap(cx, obj, flags);
 
     XPCWrappedNative *wn = static_cast<XPCWrappedNative *>(xpc_GetJSPrivate(obj));
 
-    // If the object doesn't have classinfo we want to return the same
-    // XPCWrappedNative so that we keep the same set of interfaces.
-    if (!wn->GetClassInfo())
-        return DoubleWrap(cx, obj, flags);
-
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
         return nsnull;
     XPCCallContext ccx(JS_CALLER, cx, obj);
 
     {
         if (NATIVE_HAS_FLAG(&ccx, WantPreCreate)) {
             // We have a precreate hook. This object might enforce that we only