diff --git a/src/realm.js b/src/realm.js index d03b9bf..6f03266 100644 --- a/src/realm.js +++ b/src/realm.js @@ -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. @@ -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; @@ -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); diff --git a/src/scopeHandler.js b/src/scopeHandler.js index 2f5ad13..2bfae5e 100644 --- a/src/scopeHandler.js +++ b/src/scopeHandler.js @@ -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; }, @@ -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. diff --git a/test/module/evaluators.js b/test/module/evaluators.js index f412ca3..9bced53 100644 --- a/test/module/evaluators.js +++ b/test/module/evaluators.js @@ -90,7 +90,7 @@ test('createSafeEvaluatorWhichTakesEndowments - options.sloppyGlobals', t => { }); const realmTransforms = []; - const sloppyGlobals = {}; + const sloppyGlobals = true; const safeEval = createSafeEvaluatorWhichTakesEndowments( createSafeEvaluatorFactory( @@ -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(); diff --git a/test/module/scopeHandler.js b/test/module/scopeHandler.js index b2411c7..cf7c1e5 100644 --- a/test/module/scopeHandler.js +++ b/test/module/scopeHandler.js @@ -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(); @@ -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: {} }; @@ -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: {} }; @@ -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 = {};