From a75694897165925b986ed9e1b0d74f311fd112b6 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Mon, 15 Sep 2014 16:49:04 +0200 Subject: [PATCH] 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. --HG-- extra : rebase_source : dc238b6eeed8299adc3995c2b8647f68499efb58 --- dom/bindings/BindingUtils.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index ff341031c197..92d47d5f3bad 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -971,11 +971,21 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle wrapper, 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 @@ -1328,13 +1338,19 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle wrapper, 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; @@ -1343,7 +1359,9 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle wrapper, if (desc.object()) { return true; } - } while ((nativePropertyHooks = nativePropertyHooks->mProtoHooks)); + + nativePropertyHooks = nativePropertyHooks->mProtoHooks; + } return true; } @@ -1503,7 +1521,9 @@ XrayEnumerateProperties(JSContext* cx, JS::Handle wrapper, 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; }