From d57858e03cfea560f174214d7419d0f82e85100c Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Sun, 10 Oct 2010 15:48:29 -0700 Subject: [PATCH] bug 580128 - Implement deep wrapping for .wrappedJSObject. r=mrbkap --- .../xpconnect/wrappers/CrossOriginWrapper.cpp | 29 +++++++++++++++++-- .../xpconnect/wrappers/CrossOriginWrapper.h | 7 +++++ js/src/xpconnect/wrappers/WrapperFactory.cpp | 25 ++++++++++++++++ js/src/xpconnect/wrappers/WrapperFactory.h | 3 ++ js/src/xpconnect/wrappers/XrayWrapper.cpp | 27 ++--------------- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp b/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp index 9e949945bf1..75158eb5778 100644 --- a/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp +++ b/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp @@ -37,12 +37,13 @@ * * ***** END LICENSE BLOCK ***** */ -#include "CrossOriginWrapper.h" - #include "nsJSPrincipals.h" #include "XPCWrapper.h" +#include "CrossOriginWrapper.h" +#include "WrapperFactory.h" + namespace xpc { CrossOriginWrapper::CrossOriginWrapper(uintN flags) : JSCrossCompartmentWrapper(flags) @@ -59,6 +60,30 @@ GetCompartmentPrincipal(JSCompartment *compartment) return static_cast(compartment->principals)->nsIPrincipalPtr; } +bool +CrossOriginWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, + bool set, js::PropertyDescriptor *desc) +{ + return JSCrossCompartmentWrapper::getPropertyDescriptor(cx, wrapper, id, set, desc) && + WrapperFactory::WaiveXrayAndWrap(cx, js::Jsvalify(&desc->value)); +} + +bool +CrossOriginWrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, + bool set, js::PropertyDescriptor *desc) +{ + return JSCrossCompartmentWrapper::getOwnPropertyDescriptor(cx, wrapper, id, set, desc) && + WrapperFactory::WaiveXrayAndWrap(cx, js::Jsvalify(&desc->value)); +} + +bool +CrossOriginWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, + js::Value *vp) +{ + return JSCrossCompartmentWrapper::get(cx, wrapper, receiver, id, vp) && + WrapperFactory::WaiveXrayAndWrap(cx, js::Jsvalify(vp)); +} + bool CrossOriginWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act) { diff --git a/js/src/xpconnect/wrappers/CrossOriginWrapper.h b/js/src/xpconnect/wrappers/CrossOriginWrapper.h index d61476f4a33..9bf2c4acb8e 100644 --- a/js/src/xpconnect/wrappers/CrossOriginWrapper.h +++ b/js/src/xpconnect/wrappers/CrossOriginWrapper.h @@ -50,6 +50,13 @@ class CrossOriginWrapper : public JSCrossCompartmentWrapper { CrossOriginWrapper(uintN flags); virtual ~CrossOriginWrapper(); + virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, + bool set, js::PropertyDescriptor *desc); + virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, + bool set, js::PropertyDescriptor *desc); + virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, + js::Value *vp); + virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act); virtual void leave(JSContext *cx, JSObject *wrapper); diff --git a/js/src/xpconnect/wrappers/WrapperFactory.cpp b/js/src/xpconnect/wrappers/WrapperFactory.cpp index 2cc65388403..99251519469 100644 --- a/js/src/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/src/xpconnect/wrappers/WrapperFactory.cpp @@ -282,4 +282,29 @@ WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj) return wrapperObj; } +bool +WrapperFactory::WaiveXrayAndWrap(JSContext *cx, jsval *vp) +{ + if (!JSVAL_IS_OBJECT(*vp)) + return true; + + JSObject *obj = JSVAL_TO_OBJECT(*vp)->unwrap(); + + // We have to make sure that if we're wrapping an outer window, that + // the .wrappedJSObject also wraps the outer window. + OBJ_TO_OUTER_OBJECT(cx, obj); + if (!obj) + return false; + + { + js::SwitchToCompartment sc(cx, obj->compartment()); + obj = JSWrapper::New(cx, obj, NULL, obj->getParent(), &WaiveXrayWrapperWrapper); + if (!obj) + return false; + } + + *vp = OBJECT_TO_JSVAL(obj); + return JS_WrapValue(cx, vp); +} + } diff --git a/js/src/xpconnect/wrappers/WrapperFactory.h b/js/src/xpconnect/wrappers/WrapperFactory.h index 44c30d11bff..275721870be 100644 --- a/js/src/xpconnect/wrappers/WrapperFactory.h +++ b/js/src/xpconnect/wrappers/WrapperFactory.h @@ -86,6 +86,9 @@ class WrapperFactory { // Wrap a location object. static JSObject *WrapLocationObject(JSContext *cx, JSObject *obj); + + // Wrap wrapped object into a waiver wrapper and then re-wrap it. + static bool WaiveXrayAndWrap(JSContext *cx, jsval *vp); }; extern JSWrapper WaiveXrayWrapperWrapper; diff --git a/js/src/xpconnect/wrappers/XrayWrapper.cpp b/js/src/xpconnect/wrappers/XrayWrapper.cpp index 162d006f7ab..66a6b60b577 100644 --- a/js/src/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/src/xpconnect/wrappers/XrayWrapper.cpp @@ -342,32 +342,11 @@ holder_enumerate(JSContext *cx, JSObject *holder) } static JSBool -wrappedJSObject_getter(JSContext *cx, JSObject *holder, jsid id, jsval *vp) +wrappedJSObject_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp) { - if (holder->isWrapper()) - holder = GetHolder(holder); + *vp = OBJECT_TO_JSVAL(wrapper); - // If the caller intentionally waives the X-ray wrapper we usually - // apply for wrapped natives, use a special wrapper to make sure the - // membrane will not automatically apply an X-ray wrapper. - JSObject *wn = GetWrappedNativeObjectFromHolder(cx, holder); - - // We have to make sure that if we're wrapping an outer window, that - // the .wrappedJSObject also wraps the outer window. - OBJ_TO_OUTER_OBJECT(cx, wn); - if (!wn) - return false; - - JSObject *obj; - { - SwitchToCompartment sc(cx, wn->compartment()); - obj = JSWrapper::New(cx, wn, NULL, holder->getParent(), &WaiveXrayWrapperWrapper); - if (!obj) - return false; - } - *vp = OBJECT_TO_JSVAL(obj); - - return JS_WrapValue(cx, vp); + return WrapperFactory::WaiveXrayAndWrap(cx, vp); } static JSBool