Skip to content

Commit

Permalink
Merge pull request #33 from Agoric/eval-sloppy-globals
Browse files Browse the repository at this point in the history
Eval sloppy globals
  • Loading branch information
michaelfig committed Aug 26, 2019
2 parents ac709c7 + a688e14 commit 9b8af86
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 36 deletions.
11 changes: 4 additions & 7 deletions src/realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function initRootRealm(parentUnsafeRec, self, options) {

// todo: investigate attacks via Array.species
// todo: this accepts newShims='string', but it should reject that
const { shims: newShims, transforms } = options;
const { shims: newShims, transforms, sloppyGlobals } = options;
const allShims = arrayConcat(parentUnsafeRec.allShims, newShims);

// The unsafe record is created already repaired.
Expand All @@ -108,7 +108,7 @@ function initRootRealm(parentUnsafeRec, self, options) {

// Creating the realmRec provides the global object, eval() and Function()
// to the realm.
const realmRec = createRealmRec(unsafeRec, transforms, options.sloppyGlobals);
const realmRec = createRealmRec(unsafeRec, transforms, sloppyGlobals);

// Apply all shims in the new RootRealm. We don't do this for compartments.
const { safeEvalWhichTakesEndowments } = realmRec;
Expand All @@ -127,11 +127,8 @@ function initRootRealm(parentUnsafeRec, self, options) {
function initCompartment(unsafeRec, self, options = {}) {
// note: 'self' is the instance of the Realm.

const realmRec = createRealmRec(
unsafeRec,
options.transforms,
options.sloppyGlobals
);
const { transforms, sloppyGlobals } = options;
const realmRec = createRealmRec(unsafeRec, transforms, sloppyGlobals);

// The realmRec acts as a private field on the realm instance.
registerRealmRecForRealmInstance(self, realmRec);
Expand Down
14 changes: 0 additions & 14 deletions src/scopeHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ export function createScopeHandler(unsafeRec, safeGlobal, sloppyGlobals) {
return target[prop];
}

// Sloppy global properties.
if (sloppyGlobals) {
if (prop in sloppyGlobals) {
return sloppyGlobals[prop];
}
throw ReferenceError(`${prop} is not defined`);
}

// Prevent the lookup for other properties.
return undefined;
},
Expand All @@ -98,12 +90,6 @@ export function createScopeHandler(unsafeRec, safeGlobal, sloppyGlobals) {
throw new TypeError(`do not modify endowments like ${String(prop)}`);
}

if (sloppyGlobals && !(prop in safeGlobal)) {
// We want to capture new assignments to the global scope.
sloppyGlobals[prop] = value;
return true;
}

safeGlobal[prop] = value;

// Return true after successful set.
Expand Down
23 changes: 12 additions & 11 deletions test/module/evaluators.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test('createSafeEvaluatorWhichTakesEndowments - options.sloppyGlobals', t => {
});

const realmTransforms = [];
const sloppyGlobals = {};
const sloppyGlobals = true;

const safeEval = createSafeEvaluatorWhichTakesEndowments(
createSafeEvaluatorFactory(
Expand All @@ -103,21 +103,22 @@ test('createSafeEvaluatorWhichTakesEndowments - options.sloppyGlobals', t => {

// Evaluate normally.
t.equal(safeEval('abc', { abc: 123 }), 123, 'endowment eval');
t.throws(
() => safeEval('def', { abc: 123 }),
ReferenceError,
'no such sloppy global'
);
t.assert(!('def' in sloppyGlobals), 'sloppy global does not yet exist');
t.equal(safeEval('typeof def', { abc: 123 }), 'undefined', 'typeof works');

// FIXME: We can't have both typeof work and a reference error if no such global.
t.equal(safeEval('def', { abc: 123 }), undefined, 'no such global');

t.assert(!('def' in safeGlobal), 'global does not yet exist');
t.equal(
safeEval('def = abc + 333', { abc: 123 }),
456,
'sloppy global assignment'
'sloppy global assignment works'
);
t.equal(safeEval('def', { abc: 123 }), 456, 'sloppy global persists');
t.equal(sloppyGlobals.def, 456, 'sloppy global uses our object');

t.equal(safeEval('def', { abc: 123 }), 456, 'assigned global persists');
t.equal(safeGlobal.def, 456, 'assigned global uses our safeGlobal');
} catch (e) {
t.isNot(e, e);
t.isNot(e, e, 'unexpected exception');
} finally {
// eslint-disable-next-line no-proto
Function.__proto__.constructor.restore();
Expand Down
8 changes: 4 additions & 4 deletions test/module/scopeHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import test from 'tape';
import sinon from 'sinon';
import { createScopeHandler } from '../../src/scopeHandler';

test('scope hander traps', t => {
test('scope handler traps', t => {
t.plan(13);

sinon.stub(console, 'error').callsFake();
Expand Down Expand Up @@ -31,7 +31,7 @@ test('scope hander traps', t => {
console.error.restore();
});

test('scope hander has', t => {
test('scope handler has', t => {
t.plan(9);

const unsafeGlobal = { foo: {} };
Expand All @@ -53,7 +53,7 @@ test('scope hander has', t => {
t.equal(handler.has(target, 'dummy'), false);
});

test('scope hander get', t => {
test('scope handler get', t => {
t.plan(13);

const unsafeGlobal = { foo: {} };
Expand Down Expand Up @@ -81,7 +81,7 @@ test('scope hander get', t => {
t.equal(handler.get(target, 'dummy'), undefined);
});

test('scope hander et', t => {
test('scope handler set', t => {
t.plan(4);

const unsafeGlobal = {};
Expand Down

0 comments on commit 9b8af86

Please sign in to comment.