From 307531531b12e97126db6c8b0900514a998de4f6 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Fri, 18 Oct 2013 13:22:08 +0200 Subject: [PATCH] Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, move some code around. r=bholley. --HG-- extra : rebase_source : 713a35d4bc7ffa4a25561823dbb0301a22565cb5 --- dom/bindings/BindingUtils.cpp | 156 ++++++++++++++++---------- dom/bindings/BindingUtils.h | 6 + js/xpconnect/wrappers/XrayWrapper.cpp | 91 +++++---------- 3 files changed, 127 insertions(+), 126 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 8713da7cf832..94e12adffd90 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -941,16 +941,6 @@ GetNativePropertyHooks(JSContext *cx, JS::Handle obj, return ifaceAndProtoJSClass->mNativeHooks; } -// Try to resolve a property as an unforgeable property from the given -// NativeProperties, if it's there. nativeProperties is allowed to be null (in -// which case we of course won't resolve anything). -static bool -XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle wrapper, - JS::Handle obj, JS::Handle id, - JS::MutableHandle desc, - bool& cacheOnHolder, - const NativeProperties* nativeProperties); - static bool XrayResolveNativeProperty(JSContext* cx, JS::Handle wrapper, const NativePropertyHooks* nativePropertyHooks, @@ -959,58 +949,6 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle wrapper, JS::MutableHandle desc, bool& cacheOnHolder); -bool -XrayResolveOwnProperty(JSContext* cx, JS::Handle wrapper, - JS::Handle obj, JS::Handle id, - JS::MutableHandle desc, - bool& cacheOnHolder) -{ - cacheOnHolder = false; - - DOMObjectType type; - bool isGlobal; - const NativePropertyHooks *nativePropertyHooks = - GetNativePropertyHooks(cx, obj, type, isGlobal); - - if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) { - // For prototype objects and interface objects, just return their - // 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; - } - if (desc.object()) { - return true; - } - if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder, - nativeProperties.chromeOnly)) { - return false; - } - if (desc.object()) { - return true; - } - - return !nativePropertyHooks->mResolveOwnProperty || - nativePropertyHooks->mResolveOwnProperty(cx, wrapper, obj, id, desc); -} - static bool XrayResolveAttribute(JSContext* cx, JS::Handle wrapper, JS::Handle obj, JS::Handle id, @@ -1113,6 +1051,9 @@ XrayResolveMethod(JSContext* cx, JS::Handle wrapper, return true; } +// Try to resolve a property as an unforgeable property from the given +// NativeProperties, if it's there. nativeProperties is allowed to be null (in +// which case we of course won't resolve anything). /* static */ bool XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle wrapper, JS::Handle obj, JS::Handle id, @@ -1264,6 +1205,97 @@ ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle wrapper, return JS_WrapPropertyDescriptor(cx, desc); } +#ifdef DEBUG + +static void +DEBUG_CheckXBLCallable(JSContext *cx, JSObject *obj) +{ + // In general, we shouldn't have cross-compartment wrappers here, because + // we should be running in an XBL scope, and the content prototype should + // contain wrappers to functions defined in the XBL scope. But if the node + // has been adopted into another compartment, those prototypes will now point + // to a different XBL scope (which is ok). + MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(obj), + xpc::IsContentXBLScope(js::GetObjectCompartment(js::UncheckedUnwrap(obj)))); + MOZ_ASSERT(JS::IsCallable(obj)); +} + +void +DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc) +{ + if (!desc->obj) + return; + if (!desc->value.isUndefined()) { + MOZ_ASSERT(desc->value.isObject()); + DEBUG_CheckXBLCallable(cx, &desc->value.toObject()); + } + if (desc->getter) { + MOZ_ASSERT(desc->attrs & JSPROP_GETTER); + DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->getter)); + } + if (desc->setter) { + MOZ_ASSERT(desc->attrs & JSPROP_SETTER); + DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->setter)); + } +} +#else +#define DEBUG_CheckXBLLookup(a, b) {} +#endif + +bool +XrayResolveOwnProperty(JSContext* cx, JS::Handle wrapper, + JS::Handle obj, JS::Handle id, + JS::MutableHandle desc, + bool& cacheOnHolder) +{ + cacheOnHolder = false; + + DOMObjectType type; + bool isGlobal; + const NativePropertyHooks *nativePropertyHooks = + GetNativePropertyHooks(cx, obj, type, isGlobal); + + if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) { + // For prototype objects and interface objects, just return their + // 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; + } + if (desc.object()) { + return true; + } + if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder, + nativeProperties.chromeOnly)) { + return false; + } + if (desc.object()) { + return true; + } + } + + return !nativePropertyHooks->mResolveOwnProperty || + nativePropertyHooks->mResolveOwnProperty(cx, wrapper, obj, id, desc); +} + /* static */ bool XrayResolveNativeProperty(JSContext* cx, JS::Handle wrapper, const NativePropertyHooks* nativePropertyHooks, diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index b31269feb29d..5fcc4935cdf5 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -2954,6 +2954,12 @@ GlobalPropertiesAreOwn() void AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo, JS::Handle aValue); + +extern void +DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc); +#else +#define DEBUG_CheckXBLLookup(a, b) {} + #endif // Returns true if aObj's global has any of the permissions named in aPermissions diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 351e803a4d05..15252785ccc9 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1454,33 +1454,6 @@ XPCWrappedNativeXrayTraits::construct(JSContext *cx, HandleObject wrapper, } -bool -DOMXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wrapper, - HandleObject holder, HandleId id, - MutableHandle desc) -{ - bool unused; - RootedObject obj(cx, getTargetObject(wrapper)); - if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc, unused)) - return false; - - if (!desc.object() && - id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING)) - { - - JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString"); - if (!toString) - return false; - - FillPropertyDescriptor(desc, wrapper, 0, - ObjectValue(*JS_GetFunctionObject(toString))); - } - - MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?"); - - return true; -} - bool DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, HandleObject wrapper, HandleObject holder, HandleId id, @@ -1536,6 +1509,33 @@ DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, Handl JS_GetPropertyDescriptorById(cx, holder, id, desc); } +bool +DOMXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wrapper, + HandleObject holder, HandleId id, + MutableHandle desc) +{ + bool unused; + RootedObject obj(cx, getTargetObject(wrapper)); + if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc, unused)) + return false; + + if (!desc.object() && + id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING)) + { + + JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString"); + if (!toString) + return false; + + FillPropertyDescriptor(desc, wrapper, 0, + ObjectValue(*JS_GetFunctionObject(toString))); + } + + MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?"); + + return true; +} + bool DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandle desc, @@ -1771,43 +1771,6 @@ XrayToString(JSContext *cx, unsigned argc, Value *vp) return true; } -#ifdef DEBUG - -static void -DEBUG_CheckXBLCallable(JSContext *cx, JSObject *obj) -{ - // In general, we shouldn't have cross-compartment wrappers here, because - // we should be running in an XBL scope, and the content prototype should - // contain wrappers to functions defined in the XBL scope. But if the node - // has been adopted into another compartment, those prototypes will now point - // to a different XBL scope (which is ok). - MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(obj), - xpc::IsContentXBLScope(js::GetObjectCompartment(js::UncheckedUnwrap(obj)))); - MOZ_ASSERT(JS::IsCallable(obj)); -} - -static void -DEBUG_CheckXBLLookup(JSContext *cx, JSPropertyDescriptor *desc) -{ - if (!desc->obj) - return; - if (!desc->value.isUndefined()) { - MOZ_ASSERT(desc->value.isObject()); - DEBUG_CheckXBLCallable(cx, &desc->value.toObject()); - } - if (desc->getter) { - MOZ_ASSERT(desc->attrs & JSPROP_GETTER); - DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->getter)); - } - if (desc->setter) { - MOZ_ASSERT(desc->attrs & JSPROP_SETTER); - DEBUG_CheckXBLCallable(cx, JS_FUNC_TO_DATA_PTR(JSObject *, desc->setter)); - } -} -#else -#define DEBUG_CheckXBLLookup(a, b) {} -#endif - template bool XrayWrapper::isExtensible(JSContext *cx, JS::Handle wrapper,