Bug 1291142. Ensure that we don't return gray objects when getting child windows by name or index. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 02 Aug 2016 11:06:25 -0700
changeset 307859 aa02a3d17d12fc6b730170815a1169da987b1bb8
parent 307858 7fe1c4a7fdef23c4a12acd4be45be2e9d482eec7
child 307860 0981a42d17c4f84fc927124ae701355887773ab1
push id30521
push usercbook@mozilla.com
push dateWed, 03 Aug 2016 15:04:18 +0000
treeherdermozilla-central@7f1b2e71efdc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1291142
milestone51.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 1291142. Ensure that we don't return gray objects when getting child windows by name or index. r=bholley
dom/base/nsGlobalWindow.cpp
dom/base/nsIGlobalObject.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1067,17 +1067,17 @@ nsOuterWindowProxy::GetSubframeWindow(JS
   frame->EnsureInnerWindow();
   JSObject* obj = global->FastGetGlobalJSObject();
   // This null check fixes a hard-to-reproduce crash that occurs when we
   // get here when we're mid-call to nsDocShell::Destroy. See bug 640904
   // comment 105.
   if (MOZ_UNLIKELY(!obj)) {
     return xpc::Throw(cx, NS_ERROR_FAILURE);
   }
-
+  JS::ExposeObjectToActiveJS(obj);
   vp.setObject(*obj);
   return JS_WrapValue(cx, vp);
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsOuterWindowProxy::GetSubframeWindow(JSContext *cx,
                                       JS::Handle<JSObject*> proxy,
                                       JS::Handle<jsid> id) const
--- a/dom/base/nsIGlobalObject.h
+++ b/dom/base/nsIGlobalObject.h
@@ -52,17 +52,18 @@ public:
   {
     return mIsDying;
   }
 
   // GetGlobalJSObject may return a gray object.  If this ever changes so that
   // it stops doing that, please simplify the code in FindAssociatedGlobal in
   // BindingUtils.h that does JS::ExposeObjectToActiveJS on the return value of
   // GetGlobalJSObject.  Also, in that case the JS::ExposeObjectToActiveJS in
-  // AutoJSAPI::InitInternal can probably be removed.
+  // AutoJSAPI::InitInternal can probably be removed.  And also the similar
+  // calls in XrayWrapper and nsGlobalWindow.
   virtual JSObject* GetGlobalJSObject() = 0;
 
   // This method is not meant to be overridden.
   nsIPrincipal* PrincipalOrNull();
 
   void RegisterHostObjectURI(const nsACString& aURI);
 
   void UnregisterHostObjectURI(const nsACString& aURI);
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -1637,16 +1637,17 @@ DOMXrayTraits::resolveOwnProperty(JSCont
             if (subframe) {
                 subframe->EnsureInnerWindow();
                 nsGlobalWindow* global = nsGlobalWindow::Cast(subframe);
                 JSObject* obj = global->FastGetGlobalJSObject();
                 if (MOZ_UNLIKELY(!obj)) {
                     // It's gone?
                     return xpc::Throw(cx, NS_ERROR_FAILURE);
                 }
+                ExposeObjectToActiveJS(obj);
                 desc.value().setObject(*obj);
                 FillPropertyDescriptor(desc, wrapper, true);
                 return JS_WrapPropertyDescriptor(cx, desc);
             }
         }
     }
 
     if (!JS_GetOwnPropertyDescriptorById(cx, holder, id, desc))
@@ -1969,16 +1970,17 @@ XrayWrapper<Base, Traits>::getPropertyDe
         nsAutoJSString name;
         if (!name.init(cx, JSID_TO_STRING(id)))
             return false;
         if (nsCOMPtr<nsPIDOMWindowOuter> childDOMWin = win->GetChildWindow(name)) {
             auto* cwin = nsGlobalWindow::Cast(childDOMWin);
             JSObject* childObj = cwin->FastGetGlobalJSObject();
             if (MOZ_UNLIKELY(!childObj))
                 return xpc::Throw(cx, NS_ERROR_FAILURE);
+            ExposeObjectToActiveJS(childObj);
             FillPropertyDescriptor(desc, wrapper, ObjectValue(*childObj),
                                    /* readOnly = */ true);
             return JS_WrapPropertyDescriptor(cx, desc);
         }
     }
 
     // If we still have nothing, we're done.
     if (!desc.object())