Let "window.eval" work again by always wrapping eval when it comes out of a cross origin wrapper. bug 389878, r+sr=jst

This commit is contained in:
mrbkap@gmail.com 2007-07-31 13:15:21 -07:00
parent 4b4cd4b8f1
commit 7713385300
4 changed files with 49 additions and 25 deletions

View File

@ -598,6 +598,12 @@ XPC_XOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
}
wrappedObj = JSVAL_TO_OBJECT(*vp);
if (JS_ObjectIsFunction(cx, wrappedObj) &&
JS_GetFunctionNative(cx, JS_ValueToFunction(cx, *vp)) ==
XPCWrapper::sEvalNative) {
return XPC_XOW_WrapFunction(cx, obj, wrappedObj, vp);
}
const char *name = JS_GET_CLASS(cx, wrappedObj)->name;
if (XPC_XOW_ClassNeedsXOW(name)) {
return XPC_XOW_WrapObject(cx, GetGlobalObject(cx, obj), vp);

View File

@ -82,8 +82,6 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
JS_STATIC_DLL_CALLBACK(JSBool)
XPC_SJOW_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
static JSNative sEvalNative;
static inline
JSBool
ThrowException(nsresult ex, JSContext *cx)
@ -881,7 +879,7 @@ XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (JS_GET_CLASS(cx, objToWrap) == &js_ScriptClass ||
(::JS_ObjectIsFunction(cx, objToWrap) &&
::JS_GetFunctionNative(cx, ::JS_ValueToFunction(cx, argv[0])) ==
sEvalNative)) {
XPCWrapper::sEvalNative)) {
return ThrowException(NS_ERROR_INVALID_ARG, cx);
}
@ -997,28 +995,11 @@ PRBool
XPC_SJOW_AttachNewConstructorObject(XPCCallContext &ccx,
JSObject *aGlobalObject)
{
// Initialize sEvalNative the first time we attach a constructor to
// a global that is an XPCWrappedNative (i.e. don't bother if the
// global is the one from the XPConnect safe context, since it
// doesn't have what it takes to do this)
if (!sEvalNative &&
XPCWrappedNative::GetWrappedNativeOfJSObject(ccx, aGlobalObject)) {
jsval eval_val;
if (!::JS_GetProperty(ccx, aGlobalObject, "eval", &eval_val)) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
if (JSVAL_IS_PRIMITIVE(eval_val) ||
!::JS_ObjectIsFunction(ccx, JSVAL_TO_OBJECT(eval_val))) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
sEvalNative =
::JS_GetFunctionNative(ccx, ::JS_ValueToFunction(ccx, eval_val));
if (!sEvalNative) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
// Initialize sEvalNative the first time we attach a constructor.
// NB: This always happens before any cross origin wrappers are
// created, so it's OK to do this here.
if (!XPCWrapper::FindEval(ccx, aGlobalObject)) {
return PR_FALSE;
}
JSObject *class_obj =

View File

@ -51,6 +51,9 @@ XPCWrapper::sResolvingSlot = 0;
const PRUint32
XPCWrapper::sNumSlots = 2;
JSNative
XPCWrapper::sEvalNative = nsnull;
// static
JSBool
XPCWrapper::AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)

View File

@ -116,6 +116,40 @@ public:
*/
static const PRUint32 sNumSlots;
/**
* Cross origin wrappers and safe JSObject wrappers both need to know
* which native is 'eval' for various purposes.
*/
static JSNative sEvalNative;
/**
* Given a context and a global object, fill our eval native.
*/
static JSBool FindEval(XPCCallContext &ccx, JSObject *obj) {
if (sEvalNative) {
return JS_TRUE;
}
jsval eval_val;
if (!::JS_GetProperty(ccx, obj, "eval", &eval_val)) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
if (JSVAL_IS_PRIMITIVE(eval_val) ||
!::JS_ObjectIsFunction(ccx, JSVAL_TO_OBJECT(eval_val))) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
sEvalNative =
::JS_GetFunctionNative(ccx, ::JS_ValueToFunction(ccx, eval_val));
if (!sEvalNative) {
return ThrowException(NS_ERROR_UNEXPECTED, ccx);
}
return JS_TRUE;
}
/**
* A useful function that throws an exception onto cx.
*/