Fixing bug 294795. Don't leave references from cloned member functions to the scope where xpconnect creates the functions (safe context). r=bzbarsky@mit.edu, sr=brendan@mozilla.org, a=brendan@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@174082 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
e7a2bd369e
commit
08a7614911
@ -418,20 +418,13 @@ JSBool XPCDispObject::Invoke(XPCCallContext & ccx, CallMode mode)
|
||||
static
|
||||
JSBool GetMember(XPCCallContext& ccx, JSObject* funobj, XPCNativeInterface*& iface, XPCDispInterface::Member*& member)
|
||||
{
|
||||
// We expect funobj to be a clone, we need the real funobj.
|
||||
JSFunction* fun = (JSFunction*) JS_GetPrivate(ccx, funobj);
|
||||
if(!fun)
|
||||
return JS_FALSE;
|
||||
JSObject* realFunObj = JS_GetFunctionObject(fun);
|
||||
if(!realFunObj)
|
||||
return JS_FALSE;
|
||||
jsval val;
|
||||
if(!JS_GetReservedSlot(ccx, realFunObj, 1, &val))
|
||||
if(!JS_GetReservedSlot(ccx, funobj, 1, &val))
|
||||
return JS_FALSE;
|
||||
if(!JSVAL_IS_INT(val))
|
||||
return JS_FALSE;
|
||||
iface = NS_REINTERPRET_CAST(XPCNativeInterface*,JSVAL_TO_PRIVATE(val));
|
||||
if(!JS_GetReservedSlot(ccx, realFunObj, 0, &val))
|
||||
if(!JS_GetReservedSlot(ccx, funobj, 0, &val))
|
||||
return JS_FALSE;
|
||||
if(!JSVAL_IS_INT(val))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -266,7 +266,7 @@ JSBool XPCIDispatchExtension::DefineProperty(XPCCallContext & ccx,
|
||||
// Protect the jsval
|
||||
AUTO_MARK_JSVAL(ccx, funval);
|
||||
// clone a function we can use for this object
|
||||
JSObject* funobj = JS_CloneFunctionObject(ccx, JSVAL_TO_OBJECT(funval), obj);
|
||||
JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(funval), obj);
|
||||
if(!funobj)
|
||||
return JS_FALSE;
|
||||
jsid id;
|
||||
|
||||
@ -476,8 +476,8 @@ XPC_NW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||
AUTO_MARK_JSVAL(ccx, memberval);
|
||||
|
||||
// clone a function we can use for this object
|
||||
JSObject* funobj = ::JS_CloneFunctionObject(cx, JSVAL_TO_OBJECT(memberval),
|
||||
wrapper->GetFlatJSObject());
|
||||
JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(memberval),
|
||||
wrapper->GetFlatJSObject());
|
||||
if (!funobj) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -701,9 +701,8 @@ XPC_NW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||
// use for this object. NB: cx's newborn roots will protect funobj
|
||||
// and funWrapper and its object from GC.
|
||||
|
||||
JSObject* funobj =
|
||||
::JS_CloneFunctionObject(cx, JSVAL_TO_OBJECT(memberval),
|
||||
wrapper->GetFlatJSObject());
|
||||
JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(memberval),
|
||||
wrapper->GetFlatJSObject());
|
||||
if (!funobj) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -2092,8 +2092,8 @@ NS_IMETHODIMP nsXPCComponents::LookupMethod()
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
|
||||
// clone a function we can use for this object
|
||||
JSObject* funobj = JS_CloneFunctionObject(cx, JSVAL_TO_OBJECT(funval),
|
||||
wrapper->GetFlatJSObject());
|
||||
JSObject* funobj = xpc_CloneJSFunction(inner_cc, JSVAL_TO_OBJECT(funval),
|
||||
wrapper->GetFlatJSObject());
|
||||
if(!funobj)
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ const char* XPCJSRuntime::mStrings[] = {
|
||||
"Components", // IDX_COMPONENTS
|
||||
"wrappedJSObject", // IDX_WRAPPED_JSOBJECT
|
||||
"Object", // IDX_OBJECT
|
||||
"Function", // IDX_FUNCTION
|
||||
"prototype", // IDX_PROTOTYPE
|
||||
"createInstance", // IDX_CREATE_INSTANCE
|
||||
"item" // IDX_ITEM
|
||||
|
||||
@ -558,6 +558,7 @@ public:
|
||||
IDX_COMPONENTS ,
|
||||
IDX_WRAPPED_JSOBJECT ,
|
||||
IDX_OBJECT ,
|
||||
IDX_FUNCTION ,
|
||||
IDX_PROTOTYPE ,
|
||||
IDX_CREATE_INSTANCE ,
|
||||
IDX_ITEM ,
|
||||
@ -1014,6 +1015,9 @@ public:
|
||||
JSObject*
|
||||
GetPrototypeJSObject() const {return mPrototypeJSObject;}
|
||||
|
||||
JSObject*
|
||||
GetPrototypeJSFunction() const {return mPrototypeJSFunction;}
|
||||
|
||||
void RemoveWrappedNativeProtos();
|
||||
|
||||
static XPCWrappedNativeScope*
|
||||
@ -1076,6 +1080,7 @@ private:
|
||||
XPCWrappedNativeScope* mNext;
|
||||
JSObject* mGlobalJSObject;
|
||||
JSObject* mPrototypeJSObject;
|
||||
JSObject* mPrototypeJSFunction;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -3311,6 +3316,9 @@ protected:
|
||||
|
||||
JSBool xpc_IsReportableErrorCode(nsresult code);
|
||||
|
||||
JSObject* xpc_CloneJSFunction(XPCCallContext &ccx, JSObject *funobj,
|
||||
JSObject *parent);
|
||||
|
||||
/***************************************************************************/
|
||||
// Inlined utilities.
|
||||
|
||||
|
||||
@ -43,6 +43,44 @@
|
||||
#include "xpcprivate.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Helper that clones JS Function objects along with both of its
|
||||
* reserved slots.
|
||||
*/
|
||||
|
||||
JSObject *
|
||||
xpc_CloneJSFunction(XPCCallContext &ccx, JSObject *funobj, JSObject *parent)
|
||||
{
|
||||
JSObject *clone = JS_CloneFunctionObject(ccx, funobj, parent);
|
||||
if(!clone)
|
||||
return nsnull;
|
||||
|
||||
XPCWrappedNativeScope *scope =
|
||||
XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
|
||||
|
||||
if (!scope) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Make sure to break the prototype chain to the function object
|
||||
// we cloned to prevent its scope from leaking into the clones
|
||||
// scope.
|
||||
JS_SetPrototype(ccx, clone, scope->GetPrototypeJSFunction());
|
||||
|
||||
// Copy the reserved slots to the clone.
|
||||
jsval ifaceVal, memberVal;
|
||||
if(!JS_GetReservedSlot(ccx, funobj, 0, &ifaceVal) ||
|
||||
!JS_GetReservedSlot(ccx, funobj, 1, &memberVal))
|
||||
return nsnull;
|
||||
|
||||
if(!JS_SetReservedSlot(ccx, clone, 0, ifaceVal) ||
|
||||
!JS_SetReservedSlot(ccx, clone, 1, memberVal))
|
||||
return nsnull;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
// XPCNativeMember
|
||||
|
||||
// static
|
||||
@ -52,19 +90,11 @@ XPCNativeMember::GetCallInfo(XPCCallContext& ccx,
|
||||
XPCNativeInterface** pInterface,
|
||||
XPCNativeMember** pMember)
|
||||
{
|
||||
JSFunction* fun;
|
||||
JSObject* realFunObj;
|
||||
|
||||
// We expect funobj to be a clone, we need the real funobj.
|
||||
|
||||
fun = (JSFunction*) JS_GetPrivate(ccx, funobj);
|
||||
realFunObj = JS_GetFunctionObject(fun);
|
||||
|
||||
jsval ifaceVal;
|
||||
jsval memberVal;
|
||||
|
||||
if(!JS_GetReservedSlot(ccx, realFunObj, 0, &ifaceVal) ||
|
||||
!JS_GetReservedSlot(ccx, realFunObj, 1, &memberVal) ||
|
||||
if(!JS_GetReservedSlot(ccx, funobj, 0, &ifaceVal) ||
|
||||
!JS_GetReservedSlot(ccx, funobj, 1, &memberVal) ||
|
||||
!JSVAL_IS_INT(ifaceVal) || !JSVAL_IS_INT(memberVal))
|
||||
{
|
||||
return JS_FALSE;
|
||||
|
||||
@ -447,7 +447,7 @@ DefinePropertyIfFound(XPCCallContext& ccx,
|
||||
|
||||
AUTO_MARK_JSVAL(ccx, funval);
|
||||
|
||||
funobj = JS_CloneFunctionObject(ccx, JSVAL_TO_OBJECT(funval), obj);
|
||||
funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(funval), obj);
|
||||
if(!funobj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -183,6 +183,7 @@ XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal)
|
||||
|
||||
jsval val;
|
||||
jsid idObj = mRuntime->GetStringID(XPCJSRuntime::IDX_OBJECT);
|
||||
jsid idFun = mRuntime->GetStringID(XPCJSRuntime::IDX_FUNCTION);
|
||||
jsid idProto = mRuntime->GetStringID(XPCJSRuntime::IDX_PROTOTYPE);
|
||||
|
||||
if(OBJ_GET_PROPERTY(ccx, aGlobal, idObj, &val) &&
|
||||
@ -196,6 +197,18 @@ XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal)
|
||||
{
|
||||
NS_ERROR("Can't get globalObject.Object.prototype");
|
||||
}
|
||||
|
||||
if(OBJ_GET_PROPERTY(ccx, aGlobal, idFun, &val) &&
|
||||
!JSVAL_IS_PRIMITIVE(val) &&
|
||||
OBJ_GET_PROPERTY(ccx, JSVAL_TO_OBJECT(val), idProto, &val) &&
|
||||
!JSVAL_IS_PRIMITIVE(val))
|
||||
{
|
||||
mPrototypeJSFunction = JSVAL_TO_OBJECT(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ERROR("Can't get globalObject.Function.prototype");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user