Bug 606709. Ensure that a traced inner window's outer window gets traced too, so that the inner doesn't outlive its outer window. r=mrbkap@gmail.com, a=blocker
authorJohnny Stenback <jst@mozilla.com>
Thu, 02 Dec 2010 16:55:38 -0800
changeset 58522 f1a5bea1d022eedf7cd4c4a4edd7ebc3cf1d29d2
parent 58521 37aefdd76a22e0f8ff5549cdd880efd497905e20
child 58523 95af6190017f0f997409fc07aae5c69d06d92086
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersmrbkap, blocker
bugs606709
milestone2.0b8pre
Bug 606709. Ensure that a traced inner window's outer window gets traced too, so that the inner doesn't outlive its outer window. r=mrbkap@gmail.com, a=blocker
dom/base/nsJSEnvironment.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3435,20 +3435,41 @@ nsJSContext::ClearScope(void *aGlobalObj
 
   if (aGlobalObj) {
     JSObject *obj = (JSObject *)aGlobalObj;
     JSAutoRequest ar(mContext);
 
     JSAutoEnterCompartment ac;
     ac.enterAndIgnoreErrors(mContext, obj);
 
+    // Grab a reference to the window property, which is the outer
+    // window, so that we can re-define it once we've cleared
+    // scope. This is what keeps the outer window alive in cases where
+    // nothing else does.
+    jsval window;
+    if (!JS_GetProperty(mContext, obj, "window", &window)) {
+      window = JSVAL_VOID;
+
+      JS_ClearPendingException(mContext);
+    }
+
     JS_ClearScope(mContext, obj);
     if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
       JS_ClearScope(mContext, &obj->getProxyExtra().toObject());
     }
+
+    if (window != JSVAL_VOID) {
+      if (!JS_DefineProperty(mContext, obj, "window", window,
+                             JS_PropertyStub, JS_PropertyStub,
+                             JSPROP_ENUMERATE | JSPROP_READONLY |
+                             JSPROP_PERMANENT)) {
+        JS_ClearPendingException(mContext);
+      }
+    }
+
     if (!obj->getParent()) {
       JS_ClearRegExpStatics(mContext, obj);
     }
 
     // Always clear watchpoints, to deal with two cases:
     // 1.  The first document for this window is loading, and a miscreant has
     //     preset watchpoints on the window object in order to attack the new
     //     document's privileged information.