Fix bug 605167. r=peterv
authorBlake Kaplan <mrbkap@gmail.com>
Mon, 18 Oct 2010 15:21:50 -0700
changeset 56105 8851d28f1619c37b22f74c3b53aed21c5ddbbd0f
parent 56104 34d43093c1e0e81ea568eeebbf9c15ce0e712edf
child 56106 179e4661d61cf278eda29b7ae8dac1e08ce73559
push id16409
push usermrbkap@mozilla.com
push dateTue, 19 Oct 2010 17:57:57 +0000
treeherdermozilla-central@179e4661d61c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs605167
milestone2.0b8pre
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
Fix bug 605167. r=peterv
dom/base/nsDOMClassInfo.cpp
js/src/xpconnect/tests/mochitest/Makefile.in
js/src/xpconnect/tests/mochitest/test_bug605167.html
js/src/xpconnect/wrappers/WrapperFactory.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -7011,16 +7011,21 @@ nsWindowSH::OuterObject(nsIXPConnectWrap
 
   JSObject *winObj = win->FastGetGlobalJSObject();
   if (!winObj) {
     NS_ASSERTION(origWin->IsOuterWindow(), "What window is this?");
     *_retval = obj;
     return NS_OK;
   }
 
+  if (!JS_WrapObject(cx, &winObj)) {
+    *_retval = nsnull;
+    return NS_ERROR_UNEXPECTED;
+  }
+
   *_retval = winObj;
   return NS_OK;
 }
 
 // DOM Location helper
 
 NS_IMETHODIMP
 nsLocationSH::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
--- a/js/src/xpconnect/tests/mochitest/Makefile.in
+++ b/js/src/xpconnect/tests/mochitest/Makefile.in
@@ -69,14 +69,15 @@ include $(topsrcdir)/config/rules.mk
 		test_bug505915.html \
 		file_bug505915.html \
 		test_bug553407.html \
 		test_bug560351.html \
 		test_bug564330.html \
 		test_frameWrapping.html \
 		test_bug589028.html \
 		bug589028_helper.html \
+		test_bug605167.html \
 		$(NULL)
 
 		#test_bug484107.html \
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/mochitest/test_bug605167.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=505915
+-->
+<head>
+  <title>Test for Bug 505915</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505915">Mozilla Bug 505915</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 505915 **/
+var dataUrl = "data:text/html,<script>parent.f = function() { return this; };<" + "/script>";
+var targetUrl = "http://example.com";
+var f;
+
+var p = 0;
+function go() {
+        switch (++p) {
+        case 1:
+                frames[0].location = dataUrl;
+                break;
+        case 2:
+                frames[0].location = targetUrl;
+                break;
+        case 3:
+                try {
+                    f().cross_origin_property;
+                    ok(false, "should have thrown an exception");
+                } catch (e) {
+                    ok(/Permission denied/.test(e), "threw the correct exception");
+                }
+                SimpleTest.finish();
+                break;
+        }
+}
+
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+<iframe id="ifr" onload="go();"></iframe>
+
+</body>
+</html>
--- a/js/src/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/src/xpconnect/wrappers/WrapperFactory.cpp
@@ -72,16 +72,29 @@ DoubleWrap(JSContext *cx, JSObject *obj,
     if (flags & WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG) {
         js::SwitchToCompartment sc(cx, obj->compartment());
         return JSWrapper::New(cx, obj, NULL, obj->getParent(),
                               &WaiveXrayWrapperWrapper);
     }
     return obj;
 }
 
+static JSObject *
+GetCurrentOuter(JSContext *cx, JSObject *obj)
+{
+    OBJ_TO_OUTER_OBJECT(cx, obj);
+    if (obj->isWrapper() && !obj->getClass()->ext.innerObject) {
+        obj = obj->unwrap();
+        NS_ASSERTION(obj->getClass()->ext.innerObject,
+                     "weird object, expecting an outer window proxy");
+    }
+
+    return obj;
+}
+
 JSObject *
 WrapperFactory::PrepareForWrapping(JSContext *cx, JSObject *scope, JSObject *obj, uintN flags)
 {
     // Don't unwrap an outer window, just double wrap it if needed.
     if (obj->getClass()->ext.innerObject)
         return DoubleWrap(cx, obj, flags);
 
     // Here are the rules for wrapping:
@@ -89,19 +102,19 @@ WrapperFactory::PrepareForWrapping(JSCon
     JS_ASSERT(!obj->isWrapper());
 
     // As soon as an object is wrapped in a security wrapper, it morphs to be
     // a fat wrapper. (see also: bug XXX).
     if (IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj))
         return nsnull;
 
     // We only hand out outer objects to script.
-    OBJ_TO_OUTER_OBJECT(cx, obj);
-    if (!obj)
-        return nsnull;
+    GetCurrentOuter(cx, obj);
+    if (obj->getClass()->ext.innerObject)
+        return DoubleWrap(cx, obj, flags);
 
     // Now, our object is ready to be wrapped, but several objects (notably
     // nsJSIIDs) have a wrapper per scope. If we are about to wrap one of
     // 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) || !obj->getParent())
         return DoubleWrap(cx, obj, flags);
@@ -280,19 +293,17 @@ WrapperFactory::WaiveXrayAndWrap(JSConte
 {
     if (JSVAL_IS_PRIMITIVE(*vp))
         return JS_WrapValue(cx, vp);
 
     JSObject *obj = JSVAL_TO_OBJECT(*vp)->unwrap();
 
     // We have to make sure that if we're wrapping an outer window, that
     // the .wrappedJSObject also wraps the outer window.
-    OBJ_TO_OUTER_OBJECT(cx, obj);
-    if (!obj)
-        return false;
+    obj = GetCurrentOuter(cx, obj);
 
     {
         js::SwitchToCompartment sc(cx, obj->compartment());
         obj = JSWrapper::New(cx, obj, NULL, obj->getParent(), &WaiveXrayWrapperWrapper);
         if (!obj)
             return false;
     }