Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, make global properties own on Xrays. r=bholley.
authorPeter Van der Beken <peterv@propagandism.org>
Mon, 15 Sep 2014 16:49:04 +0200
changeset 207606 6e8655117616
parent 207605 adfe4ac95437
child 207607 f2258c53e599
push id49735
push userpvanderbeken@mozilla.com
push dateMon, 29 Sep 2014 07:58:28 +0000
treeherdermozilla-inbound@090b62fdfd21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs787070
milestone35.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 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, make global properties own on Xrays. r=bholley.
dom/bindings/BindingUtils.cpp
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -966,21 +966,31 @@ XrayResolveOwnProperty(JSContext* cx, JS
 {
   cacheOnHolder = false;
 
   DOMObjectType type;
   bool isGlobal;
   const NativePropertyHooks *nativePropertyHooks =
     GetNativePropertyHooks(cx, obj, type, isGlobal);
 
-  if (type != eInstance) {
+  if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) {
     // For prototype objects and interface objects, just return their
-    // normal set of properties.
-    return XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
-                                     obj, id, desc, cacheOnHolder);
+    // normal set of properties. For global objects the WebIDL properties live
+    // on the instance objects, so resolve those here too.
+    if (!XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
+                                   obj, id, desc, cacheOnHolder)) {
+      return false;
+    }
+
+    // For non-global non-instance Xrays there are no other properties, so
+    // return here for them whether we resolved the property or not.
+    if (!isGlobal || desc.object()) {
+      cacheOnHolder = true;
+      return true;
+    }
   }
 
   // Check for unforgeable properties before doing mResolveOwnProperty weirdness
   const NativePropertiesHolder& nativeProperties =
     nativePropertyHooks->mNativeProperties;
   if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
                                       nativeProperties.regular)) {
     return false;
@@ -1323,32 +1333,40 @@ XrayResolveNativeProperty(JSContext* cx,
   cacheOnHolder = false;
 
   DOMObjectType type;
   bool isGlobal;
   const NativePropertyHooks* nativePropertyHooks =
     GetNativePropertyHooks(cx, obj, type, isGlobal);
 
   if (type == eInstance) {
+    // Global objects return their interfaces' properties from
+    // XrayResolveOwnProperty, so skip those.
+    if (isGlobal && GlobalPropertiesAreOwn()) {
+      nativePropertyHooks = nativePropertyHooks->mProtoHooks;
+    }
+
     // Force the type to be eInterfacePrototype, since we need to walk the
     // prototype chain.
     type = eInterfacePrototype;
   }
 
   if (type == eInterfacePrototype) {
-    do {
+    while (nativePropertyHooks) {
       if (!XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
                                      obj, id, desc, cacheOnHolder)) {
         return false;
       }
 
       if (desc.object()) {
         return true;
       }
-    } while ((nativePropertyHooks = nativePropertyHooks->mProtoHooks));
+
+      nativePropertyHooks = nativePropertyHooks->mProtoHooks;
+    }
 
     return true;
   }
 
   return XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type, obj,
                                    id, desc, cacheOnHolder);
 }
 
@@ -1498,17 +1516,19 @@ XrayEnumerateProperties(JSContext* cx, J
     }
 
     // Handle Unforgeable properties.
     if (!XrayEnumerateNativeProperties(cx, wrapper, nativePropertyHooks, type,
                                        isGlobal, obj, flags, props)) {
       return false;
     }
 
-    if (flags & JSITER_OWNONLY) {
+    // This will incorrectly return properties from EventTarget.prototype as own
+    // property names for Window.
+    if (!(isGlobal && GlobalPropertiesAreOwn()) && (flags & JSITER_OWNONLY)) {
       return true;
     }
 
     // Force the type to be eInterfacePrototype, since we need to walk the
     // prototype chain.
     type = eInterfacePrototype;
   }