Skip to content

Commit

Permalink
Bug 1522314 - Apply realm checks for newGlobal() also to evalcx(). r=…
Browse files Browse the repository at this point in the history
…jorendorff

Differential Revision: https://phabricator.services.mozilla.com/D17509

--HG--
extra : moz-landing-system : lando
  • Loading branch information
jandem committed Jan 28, 2019
1 parent 2b3de8f commit 80b43f6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 21 deletions.
11 changes: 11 additions & 0 deletions js/src/jit-test/tests/realms/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,16 @@ function testEvalcx() {
var g = newGlobal();
evalcx("this.x = 7", g);
assertEq(g.x, 7);

g = newGlobal({newCompartment: true, invisibleToDebugger: true});
var ex, sb;
try {
sb = g.eval("evalcx('')");
} catch(e) {
ex = e;
}
// Check for either an exception or CCW (with --more-compartments).
assertEq((sb && objectGlobal(sb) === null) ||
ex.toString().includes("visibility"), true);
}
testEvalcx();
62 changes: 41 additions & 21 deletions js/src/shell/js.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3762,6 +3762,39 @@ static void SetStandardRealmOptions(JS::RealmOptions& options) {
.setStreamsEnabled(enableStreams);
}

static MOZ_MUST_USE bool CheckRealmOptions(JSContext* cx,
JS::RealmOptions& options,
JSPrincipals* principals) {
JS::RealmCreationOptions& creationOptions = options.creationOptions();
if (creationOptions.compartmentSpecifier() !=
JS::CompartmentSpecifier::ExistingCompartment) {
return true;
}

JS::Compartment* comp = creationOptions.compartment();

// All realms in a compartment must be either system or non-system.
bool isSystem =
principals && principals == cx->runtime()->trustedPrincipals();
if (isSystem != IsSystemCompartment(comp)) {
JS_ReportErrorASCII(cx,
"Cannot create system and non-system realms in the "
"same compartment");
return false;
}

// Debugger visibility is per-compartment, not per-realm, so make sure the
// requested visibility matches the existing compartment's.
if (creationOptions.invisibleToDebugger() != comp->invisibleToDebugger()) {
JS_ReportErrorASCII(cx,
"All the realms in a compartment must have "
"the same debugger visibility");
return false;
}

return true;
}

static JSObject* NewSandbox(JSContext* cx, bool lazy) {
JS::RealmOptions options;
SetStandardRealmOptions(options);
Expand All @@ -3772,8 +3805,13 @@ static JSObject* NewSandbox(JSContext* cx, bool lazy) {
options.creationOptions().setNewCompartmentAndZone();
}

JSPrincipals* principals = nullptr;
if (!CheckRealmOptions(cx, options, principals)) {
return nullptr;
}

RootedObject obj(cx,
JS_NewGlobalObject(cx, &sandbox_class, nullptr,
JS_NewGlobalObject(cx, &sandbox_class, principals,
JS::DontFireOnNewGlobalHook, options));
if (!obj) {
return nullptr;
Expand Down Expand Up @@ -6260,26 +6298,8 @@ static bool NewGlobal(JSContext* cx, unsigned argc, Value* vp) {
}
}

if (creationOptions.compartmentSpecifier() ==
JS::CompartmentSpecifier::ExistingCompartment) {
JS::Compartment* comp = creationOptions.compartment();
bool isSystem =
principals && principals == cx->runtime()->trustedPrincipals();
if (isSystem != IsSystemCompartment(comp)) {
JS_ReportErrorASCII(cx,
"Cannot create system and non-system realms in the "
"same compartment");
return false;
}

// Debugger visibility is per-compartment, not per-realm, so make sure the
// requested visibility matches the existing compartment's.
if (creationOptions.invisibleToDebugger() != comp->invisibleToDebugger()) {
JS_ReportErrorASCII(cx,
"All the realms in a compartment must have "
"the same debugger visibility");
return false;
}
if (!CheckRealmOptions(cx, options, principals)) {
return false;
}

RootedObject global(cx, NewGlobalObject(cx, options, principals));
Expand Down

0 comments on commit 80b43f6

Please sign in to comment.