bug 580128 - Implement deep wrapping for .wrappedJSObject. r=mrbkap

This commit is contained in:
Andreas Gal 2010-10-10 15:48:29 -07:00
Родитель e0c094ee12
Коммит d57858e03c
5 изменённых файлов: 65 добавлений и 26 удалений

Просмотреть файл

@ -37,12 +37,13 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "CrossOriginWrapper.h"
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "XPCWrapper.h" #include "XPCWrapper.h"
#include "CrossOriginWrapper.h"
#include "WrapperFactory.h"
namespace xpc { namespace xpc {
CrossOriginWrapper::CrossOriginWrapper(uintN flags) : JSCrossCompartmentWrapper(flags) CrossOriginWrapper::CrossOriginWrapper(uintN flags) : JSCrossCompartmentWrapper(flags)
@ -59,6 +60,30 @@ GetCompartmentPrincipal(JSCompartment *compartment)
return static_cast<nsJSPrincipals *>(compartment->principals)->nsIPrincipalPtr; return static_cast<nsJSPrincipals *>(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 bool
CrossOriginWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act) CrossOriginWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act)
{ {

Просмотреть файл

@ -50,6 +50,13 @@ class CrossOriginWrapper : public JSCrossCompartmentWrapper {
CrossOriginWrapper(uintN flags); CrossOriginWrapper(uintN flags);
virtual ~CrossOriginWrapper(); 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 bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act);
virtual void leave(JSContext *cx, JSObject *wrapper); virtual void leave(JSContext *cx, JSObject *wrapper);

Просмотреть файл

@ -282,4 +282,29 @@ WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj)
return wrapperObj; 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);
}
} }

Просмотреть файл

@ -86,6 +86,9 @@ class WrapperFactory {
// Wrap a location object. // Wrap a location object.
static JSObject *WrapLocationObject(JSContext *cx, JSObject *obj); 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; extern JSWrapper WaiveXrayWrapperWrapper;

Просмотреть файл

@ -342,32 +342,11 @@ holder_enumerate(JSContext *cx, JSObject *holder)
} }
static JSBool 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()) *vp = OBJECT_TO_JSVAL(wrapper);
holder = GetHolder(holder);
// If the caller intentionally waives the X-ray wrapper we usually return WrapperFactory::WaiveXrayAndWrap(cx, vp);
// 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);
} }
static JSBool static JSBool