Bug 1062418 part 2. Clean up the bits that got moved from nsWindowSH. r=mystor
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 21 Mar 2018 23:18:51 -0400
changeset 409455 2f2b7d7d2805c1c22e5d9deda4556f6a2886f256
parent 409454 f36074b393300a3e8053943e0a91453550ca8075
child 409456 912c50cd3b665c2048174079b817bf6381cf7803
push id33687
push userapavel@mozilla.com
push dateThu, 22 Mar 2018 09:31:48 +0000
treeherdermozilla-central@7771df14ea18 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1062418
milestone61.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 1062418 part 2. Clean up the bits that got moved from nsWindowSH. r=mystor MozReview-Commit-ID: HGy6CHx4sCP
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -2918,69 +2918,80 @@ const InterfaceShimEntry kInterfaceShimM
   { "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
   { "nsIDOMOfflineResourceList", "OfflineResourceList" },
   { "nsIDOMRange", "Range" },
   { "nsIDOMSVGLength", "SVGLength" },
   // Think about whether Ci.nsINodeFilter can just go away for websites!
   { "nsIDOMNodeFilter", "NodeFilter" },
   { "nsIDOMXPathResult", "XPathResult" } };
 
-static nsresult
-LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
-                     nsPIDOMWindowInner *win,
-                     JS::MutableHandle<JS::PropertyDescriptor> desc)
+bool
+nsGlobalWindowInner::ResolveComponentsShim(
+  JSContext *aCx,
+  JS::Handle<JSObject*> aGlobal,
+  JS::MutableHandle<JS::PropertyDescriptor> aDesc)
 {
   // Keep track of how often this happens.
   Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
 
   // Warn once.
-  nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
+  nsCOMPtr<nsIDocument> doc = GetExtantDoc();
   if (doc) {
     doc->WarnOnceAbout(nsIDocument::eComponents, /* asError = */ true);
   }
 
   // Create a fake Components object.
-  AssertSameCompartment(cx, global);
-  JS::Rooted<JSObject*> components(cx, JS_NewPlainObject(cx));
-  NS_ENSURE_TRUE(components, NS_ERROR_OUT_OF_MEMORY);
+  AssertSameCompartment(aCx, aGlobal);
+  JS::Rooted<JSObject*> components(aCx, JS_NewPlainObject(aCx));
+  if (NS_WARN_IF(!components)) {
+    return false;
+  }
 
   // Create a fake interfaces object.
-  JS::Rooted<JSObject*> interfaces(cx, JS_NewPlainObject(cx));
-  NS_ENSURE_TRUE(interfaces, NS_ERROR_OUT_OF_MEMORY);
+  JS::Rooted<JSObject*> interfaces(aCx, JS_NewPlainObject(aCx));
+  if (NS_WARN_IF(!interfaces)) {
+    return false;
+  }
   bool ok =
-    JS_DefineProperty(cx, components, "interfaces", interfaces,
+    JS_DefineProperty(aCx, components, "interfaces", interfaces,
                       JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
-  NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
+  if (NS_WARN_IF(!ok)) {
+    return false;
+  }
 
   // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
   // interfaces with constants.
   for (uint32_t i = 0; i < ArrayLength(kInterfaceShimMap); ++i) {
 
     // Grab the names from the table.
     const char *geckoName = kInterfaceShimMap[i].geckoName;
     const char *domName = kInterfaceShimMap[i].domName;
 
     // Look up the appopriate interface object on the global.
-    JS::Rooted<JS::Value> v(cx, JS::UndefinedValue());
-    ok = JS_GetProperty(cx, global, domName, &v);
-    NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
+    JS::Rooted<JS::Value> v(aCx, JS::UndefinedValue());
+    ok = JS_GetProperty(aCx, aGlobal, domName, &v);
+    if (NS_WARN_IF(!ok)) {
+      return false;
+    }
     if (!v.isObject()) {
       NS_WARNING("Unable to find interface object on global");
       continue;
     }
 
     // Define the shim on the interfaces object.
-    ok = JS_DefineProperty(cx, interfaces, geckoName, v,
+    ok = JS_DefineProperty(aCx, interfaces, geckoName, v,
                            JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
-    NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
-  }
-
-  FillPropertyDescriptor(desc, global, JS::ObjectValue(*components), false);
-
-  return NS_OK;
+    if (NS_WARN_IF(!ok)) {
+      return false;
+    }
+  }
+
+  FillPropertyDescriptor(aDesc, aGlobal, JS::ObjectValue(*components), false);
+
+  return true;
 }
 
 #ifdef RELEASE_OR_BETA
 #define USE_CONTROLLERS_SHIM
 #endif
 
 #ifdef USE_CONTROLLERS_SHIM
 static const JSClass ControllersShimClass = {
@@ -3007,24 +3018,25 @@ nsGlobalWindowInner::DoResolve(JSContext
   if (!WebIDLGlobalNameHash::DefineIfEnabled(aCx, aObj, aId, aDesc, &found)) {
     return false;
   }
 
   if (found) {
     return true;
   }
 
+  // We support a cut-down Components.interfaces in case websites are
+  // using Components.interfaces.nsIFoo.CONSTANT_NAME for the ones
+  // that have constants.
   if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)) {
-    nsresult rv = LookupComponentsShim(aCx, aObj, this, aDesc);
-    if (NS_FAILED(rv)) {
-      return Throw(aCx, rv);
-    }
-    return true;
-  }
-
+    return ResolveComponentsShim(aCx, aObj, aDesc);
+  }
+
+  // We also support a "window.controllers" thing; apparently some
+  // sites use it for browser-sniffing.  See bug 1010577.
 #ifdef USE_CONTROLLERS_SHIM
   // Note: We use |aObj| rather than |this| to get the principal here, because
   // this is called during Window setup when the Document isn't necessarily
   // hooked up yet.
   if ((aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS) ||
        aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS_CLASS)) &&
       !xpc::IsXrayWrapper(aObj) &&
       !nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aObj)))
@@ -3036,17 +3048,17 @@ nsGlobalWindowInner::DoResolve(JSContext
     if (aId == XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_CONTROLLERS)) {
       clazz = &XULControllersShimClass;
     } else {
       clazz = &ControllersShimClass;
     }
     MOZ_ASSERT(JS_IsGlobalObject(aObj));
     JS::Rooted<JSObject*> shim(cx, JS_NewObject(cx, clazz));
     if (NS_WARN_IF(!shim)) {
-      return Throw(aCx, NS_ERROR_OUT_OF_MEMORY);
+      return false;
     }
     FillPropertyDescriptor(aDesc, aObj, JS::ObjectValue(*shim),
                            /* readOnly = */ false);
     return true;
   }
 #endif
 
   return true;
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -1264,16 +1264,20 @@ protected:
                       JS::Handle<JS::Value> aTransfer,
                       nsIPrincipal& aSubjectPrincipal,
                       mozilla::ErrorResult& aError);
 
 private:
   // Fire the JS engine's onNewGlobalObject hook.  Only used on inner windows.
   void FireOnNewGlobalObject();
 
+  // Helper for resolving the components shim.
+  bool ResolveComponentsShim(JSContext* aCx, JS::Handle<JSObject*> aObj,
+                             JS::MutableHandle<JS::PropertyDescriptor> aDesc);
+
   // nsPIDOMWindow{Inner,Outer} should be able to see these helper methods.
   friend class nsPIDOMWindowInner;
   friend class nsPIDOMWindowOuter;
 
   mozilla::dom::TabGroup* TabGroupInner();
 
   bool IsBackgroundInternal() const;