bug 580128 - Make xpcconvert trust cx->compartment when called from JS. r=peterv

This commit is contained in:
Blake Kaplan 2010-09-22 16:35:10 -07:00
parent 03cb31a09c
commit 420eda056d

View File

@ -1079,46 +1079,32 @@ CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
return JS_TRUE;
}
static void
ComputeWrapperInfo(const XPCCallContext &ccx,
JSObject **callee,
JSScript **script)
static PRBool
ComputeWrapperInfo(const XPCCallContext &ccx, XPCWrappedNativeScope *scope,
JSObject **callee)
{
*callee = nsnull;
*script = nsnull;
if(ccx.GetXPCContext()->CallerTypeIsJavaScript())
{
// Called from JS. We're going to hand the resulting
// JSObject to said JS, so look for the script we want on
// the stack.
JSStackFrame* fp = JS_GetScriptedCaller(ccx, NULL);
if(fp)
{
*script = fp->maybeScript();
*callee = fp->isFunctionFrame()
? &fp->callee()
: &fp->scopeChain();
}
// Called from JS. We're going to hand the resulting JSObject
// to said JS. The correct compartment must already be pushed
// on cx, so return true and don't give back a callee.
*callee = nsnull;
return PR_TRUE;
}
else if(ccx.GetXPCContext()->CallerTypeIsNative())
if(ccx.GetXPCContext()->CallerTypeIsNative())
{
// Calling from JS -> C++, return false to indicate that we need
// to push a compartment and return the callee.
*callee = ccx.GetCallee();
if(*callee && JS_ObjectIsFunction(ccx, *callee))
if(!*callee || !JS_ObjectIsFunction(ccx, *callee))
{
// Called from c++, and calling out to |callee|, which is a JS
// function object. Look for the script for this function.
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(*callee);
NS_ASSERTION(fun, "Must have JSFunction for a Function object");
*script = JS_GetFunctionScript(ccx, fun);
}
else
{
// Else we don't know whom we're calling, so don't
// create XPCNativeWrappers.
*callee = nsnull;
*callee = scope->GetGlobalJSObject();
OBJ_TO_INNER_OBJECT(ccx, *callee);
}
}
return PR_FALSE;
}
/***************************************************************************/
@ -1171,7 +1157,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
nsWrapperCache *cache = aHelper.GetWrapperCache();
JSObject *callee;
JSScript *script;
PRBool tryConstructSlimWrapper = PR_FALSE;
JSObject *flat;
@ -1187,17 +1172,14 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
if(!flat)
flat = ConstructProxyObject(ccx, aHelper, xpcscope);
ComputeWrapperInfo(ccx, &callee, &script);
if(!callee)
JSAutoEnterCompartment ac;
if(!ComputeWrapperInfo(ccx, xpcscope, &callee) &&
!ac.enter(ccx, callee))
{
callee = xpcscope->GetGlobalJSObject();
OBJ_TO_INNER_OBJECT(ccx, callee);
if(!callee)
return JS_FALSE;
return JS_FALSE;
}
JSAutoEnterCompartment ac;
if(!ac.enter(ccx, callee) || !JS_WrapObject(ccx, &flat))
if(!JS_WrapObject(ccx, &flat))
return JS_FALSE;
return CreateHolderIfNeeded(ccx, flat, d, dest);
@ -1353,31 +1335,29 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
if(!ccx.IsValid())
return JS_FALSE;
ComputeWrapperInfo(ccx, &callee, &script);
if(!callee)
JSAutoEnterCompartment ac;
if(!ComputeWrapperInfo(ccx, xpcscope, &callee) &&
!ac.enter(ccx, callee))
{
callee = xpcscope->GetGlobalJSObject();
OBJ_TO_INNER_OBJECT(cx, callee);
if(!callee)
return JS_FALSE;
return JS_FALSE;
}
JSAutoEnterCompartment ac;
if(!ac.enter(ccx, callee) || !JS_WrapObject(ccx, &flat))
JSObject *original = flat;
if(!JS_WrapObject(ccx, &flat))
return JS_FALSE;
*d = OBJECT_TO_JSVAL(flat);
if(dest)
{
// The strongWrapper still holds the original flat object.
if(OBJECT_TO_JSVAL(flat) == *d)
if(flat == original)
{
*dest = strongWrapper.forget().get();
}
else
{
nsRefPtr<XPCJSObjectHolder> objHolder =
XPCJSObjectHolder::newHolder(ccx, JSVAL_TO_OBJECT(*d));
XPCJSObjectHolder::newHolder(ccx, flat);
if(!objHolder)
return JS_FALSE;