Bug 568885 - Put Cu.Sandbox globals in a separate compartment from non-sandbox objects in the same domain. r=gal, sr=mrbkap.

This commit is contained in:
Jason Orendorff 2010-06-24 18:08:52 -05:00
parent 4119c39520
commit 285e13d2c5

View File

@ -3236,11 +3236,6 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop)
if(NS_FAILED(rv))
return NS_ERROR_XPC_UNEXPECTED;
JSObject *sandbox = JS_NewGlobalObject(cx, &SandboxClass);
if (!sandbox)
return NS_ERROR_XPC_UNEXPECTED;
js::AutoValueRooter tvr(cx, sandbox);
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(prinOrSop));
if (!sop) {
@ -3265,19 +3260,35 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop)
return NS_ERROR_OUT_OF_MEMORY;
}
// Pass on ownership of sop to |sandbox|.
if (!JS_SetPrivate(cx, sandbox, sop.forget().get())) {
return NS_ERROR_XPC_UNEXPECTED;
}
rv = xpc->InitClasses(cx, sandbox);
if (NS_SUCCEEDED(rv) &&
!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
rv = NS_ERROR_FAILURE;
}
JSPrincipals *jsPrincipals;
rv = sop->GetPrincipal()->GetJSPrincipals(cx, &jsPrincipals);
if (NS_FAILED(rv))
return rv;
JSObject *sandbox = JS_NewCompartmentAndGlobalObject(cx, &SandboxClass, jsPrincipals);
if (jsPrincipals)
JSPRINCIPALS_DROP(cx, jsPrincipals);
if (!sandbox)
return NS_ERROR_XPC_UNEXPECTED;
js::AutoValueRooter tvr(cx, sandbox);
{
JSAutoCrossCompartmentCall ac;
if (!ac.enter(cx, sandbox))
return NS_ERROR_XPC_UNEXPECTED;
// Pass on ownership of sop to |sandbox|.
if (!JS_SetPrivate(cx, sandbox, sop.forget().get())) {
return NS_ERROR_XPC_UNEXPECTED;
}
rv = xpc->InitClasses(cx, sandbox);
if (NS_SUCCEEDED(rv) &&
!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv))
return NS_ERROR_XPC_UNEXPECTED;
}
if (vp) {
*vp = OBJECT_TO_JSVAL(sandbox);
@ -3661,20 +3672,9 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
jsval exn;
if (JS_GetPendingException(sandcx->GetJSContext(), &exn)) {
// Stash the exception in |cx| so we can execute code on
// Root the exception temporarily so we can execute code on
// sandcx without a pending exception.
// Note that, even if wrapped, |exn| is rooted.
{
JSAutoTransferRequest transfer(sandcx->GetJSContext(), cx);
if (!JSVAL_IS_PRIMITIVE(exn) &&
XPCWrapper::RewrapObject(cx, callingScope,
JSVAL_TO_OBJECT(exn),
XPCWrapper::SJOW, &exn)) {
JS_SetPendingException(cx, exn);
}
}
js::AutoValueRooter exnroot(sandcx->GetJSContext(), exn);
JS_ClearPendingException(sandcx->GetJSContext());
if (returnStringOnly) {
// The caller asked for strings only, convert the
@ -3690,8 +3690,18 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
JS_ClearPendingException(cx);
rv = NS_ERROR_FAILURE;
}
} else {
JSAutoTransferRequest transfer(sandcx->GetJSContext(), cx);
if (!JSVAL_IS_PRIMITIVE(exn) &&
XPCWrapper::RewrapObject(cx, callingScope,
JSVAL_TO_OBJECT(exn),
XPCWrapper::SJOW, &exn)) {
JS_SetPendingException(cx, exn);
}
}
// Clear str so we don't confuse callers.
str = nsnull;
} else {