Bug 1398601 - Fix subscript loader when using JSM global sharing r=kmag

When using the subscript loader with JSM global sharing, it was possible
that subscript would pollute the global of all JSMs in the sharing.

MozReview-Commit-ID: 1ah5JUAZwBA

--HG--
extra : rebase_source : 45a3974cb80ede0cb3beea92f895679c5ea7aa4b
This commit is contained in:
Ted Campbell 2017-09-10 14:23:32 -04:00
parent 0388c3314f
commit 8b2e8b3fe5
2 changed files with 35 additions and 14 deletions

View File

@ -446,9 +446,14 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
{
aTargetObject.set(js::GetJSMEnvironmentOfScriptedCaller(aCx));
// The above could fail if the scripted caller is not a
// component/JSM (it could be a DOM scope, for instance).
if (!aTargetObject) {
// The above could fail if the scripted caller is not a component/JSM (it
// could be a DOM scope, for instance).
//
// If the target object was not in the JSM shared global, return the global
// instead. This is needed when calling the subscript loader within a frame
// script, since it the FrameScript NSVO will have been found.
if (!aTargetObject ||
!IsLoaderGlobal(js::GetGlobalForObjectCrossCompartment(aTargetObject))) {
aTargetObject.set(CurrentGlobalOrNull(aCx));
}
}

View File

@ -193,24 +193,40 @@ EvalScript(JSContext* cx,
if (!JS::CloneAndExecuteScript(cx, script, retval)) {
return false;
}
} else if (js::IsJSMEnvironment(targetObj)) {
if (!ExecuteInJSMEnvironment(cx, script, targetObj)) {
return false;
}
retval.setUndefined();
} else {
JS::AutoObjectVector envChain(cx);
if (!envChain.append(targetObj)) {
return false;
}
if (loadScope != targetObj &&
loadScope &&
!JS_IsGlobalObject(loadScope))
{
MOZ_DIAGNOSTIC_ASSERT(js::GetObjectCompartment(loadScope) ==
js::GetObjectCompartment(targetObj));
if (!envChain.append(loadScope)) {
if (!loadScope) {
// A null loadScope means we are cross-compartment. In this case, we
// should check the target isn't in the JSM loader shared-global or
// we will contaiminate all JSMs in the compartment.
//
// NOTE: If loadScope is already a shared-global JSM, we can't
// determine which JSM the target belongs to and have to assume it
// is in our JSM.
JSObject* targetGlobal = js::GetGlobalForObjectCrossCompartment(targetObj);
MOZ_DIAGNOSTIC_ASSERT(!mozJSComponentLoader::Get()->IsLoaderGlobal(targetGlobal),
"Don't load subscript into target in a shared-global JSM");
if (!JS::CloneAndExecuteScript(cx, envChain, script, retval)) {
return false;
}
}
if (!JS::CloneAndExecuteScript(cx, envChain, script, retval)) {
return false;
} else if (JS_IsGlobalObject(loadScope)) {
if (!JS::CloneAndExecuteScript(cx, envChain, script, retval)) {
return false;
}
} else {
MOZ_ASSERT(js::IsJSMEnvironment(loadScope));
if (!js::ExecuteInJSMEnvironment(cx, script, loadScope, envChain)) {
return false;
}
retval.setUndefined();
}
}