freeze all primordials, including the anonymous ones
We're still missing AsyncFunction and AsyncGenerator
MODIFY
src/bundle/createSES.js
src/bundle/createSES.js
@@ -19,6 +19,8 @@ import tameError from './tame-error.js';
import tameRegExp from './tame-regexp.js';
import removeProperties from './removeProperties.js';
import getAnonIntrinsics from './anonIntrinsics.js';
+import { deepFreeze } from './deepFreeze.js';
+import hardenPrimordials from './hardenPrimordials.js';
import whitelist from './whitelist.js';
export function createSESWithRealmConstructor(creatorStrings, Realm) {
@@ -87,7 +89,12 @@ export function createSESWithRealmConstructor(creatorStrings, Realm) {
r.global.def = b.def;
r.global.Nat = b.Nat;
- b.deepFreezePrimordials(r.global);
+ const hardenPrimordialsSrc = `
+ const deepFreeze = (${deepFreeze});
+ const getAnonIntrinsics = (${getAnonIntrinsics});
+ (${hardenPrimordials})`;
+ r.evaluate(hardenPrimordialsSrc)(r.global);
+ //b.deepFreezePrimordials(r.global);
return r;
}
const SES = {

ADD
src/bundle/hardenPrimordials.js
+/* global def getAnonIntrinsics deepFreeze */
+
+export default function hardenPrimoridals(global) {
+ "use strict";
+ const root = {
+ global, // global plus all the namedIntrinsics
+ anonIntrinsics: getAnonIntrinsics(global),
+ };
+ // todo: re-examine exactly which "global" we're freezing
+
+ // this will change when we redefine def() into a harden() with a different
+ // API (which does not traverse .__proto__)
+ deepFreeze(root);
+}

ADD
test/test-freeze.js
+import test from 'tape';
+import SES from '../src/index.js';
+
+test('SESRealm global is frozen', function(t) {
+ const s = SES.makeSESRootRealm();
+ t.throws(() => s.evaluate('this.a = 10;'), TypeError);
+ t.equal(s.evaluate('this.a'), undefined);
+ t.end();
+});
+
+test('SESRealm named intrinsics are frozen', function(t) {
+ const s = SES.makeSESRootRealm();
+ t.throws(() => s.evaluate('Object.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('Number.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('Date.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('Array.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('Array.push = 10;'), TypeError);
+ t.throws(() => s.evaluate('WeakSet.a = 10;'), TypeError);
+ t.end();
+});
+
+test('SESRealm anonymous intrinsics are frozen', function(t) {
+ const s = SES.makeSESRootRealm();
+ // these two will be frozen once #41 is fixed
+ //t.throws(() => s.evaluate('(async function() {}).constructor.a = 10;'), TypeError);
+ //t.throws(() => s.evaluate('(async function*() {}).constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('(function*() {}).constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('[][Symbol.iterator]().constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('new Map()[Symbol.iterator]().constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('new Set()[Symbol.iterator]().constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('new WeakMap()[Symbol.iterator]().constructor.a = 10;'), TypeError);
+ t.throws(() => s.evaluate('new WeakSet()[Symbol.iterator]().constructor.a = 10;'), TypeError);
+ t.end();
+});

ADD
test/test-nesting.js
+import test from 'tape';
+import SES from '../src/index.js';
+
+test('nested realms should work at all', function(t) {
+ const s1 = SES.makeSESRootRealm();
+ const s2 = s1.evaluate('SES.makeSESRootRealm()');
+ t.equal(s2.evaluate('1+2'), 3);
+ const s3 = s2.evaluate('SES.makeSESRootRealm()');
+ t.equal(s3.evaluate('1+2'), 3);
+ t.end();
+});

MODIFY
test/test.js
test/test.js
@@ -65,13 +65,6 @@ test('SESRealm.SES wraps exceptions', function(t) {
t.end();
});
-test('SESRealm is frozen', function(t) {
- const s = SES.makeSESRootRealm();
- t.throws(() => s.evaluate('this.a = 10;'), TypeError);
- t.equal(s.evaluate('this.a'), undefined);
- t.end();
-});
-
test('primal realm SES does not have confine', function(t) {
t.equal(Object.hasOwnProperty('SES'), false);
t.end();

freeze all primordials, including the anonymous ones

We're still missing AsyncFunction and AsyncGenerator (#41).