Addressing comments in PR 146 and 150
MODIFY
src/bundle/createSES.js
src/bundle/createSES.js
@@ -20,7 +20,9 @@ import tameError from './tame-error';
import tameRegExp from './tame-regexp';
import removeProperties from './removeProperties';
import getAnonIntrinsics from './anonIntrinsics';
+import getNamedIntrinsics from './namedIntrinsics';
import getAllPrimordials from './getAllPrimordials';
+import getAllIntrinsics from './getAllIntrinsics';
import whitelist from './whitelist';
import makeConsole from './make-console';
import makeMakeRequire from './make-require';
@@ -44,6 +46,9 @@ export function createSESWithRealmConstructor(creatorStrings, Realm) {
} = options;
const wl = JSON.parse(JSON.stringify(optWhitelist || whitelist));
+ const repairPlan = JSON.parse(
+ JSON.stringify(optDataPropertiesToRepair || dataPropertiesToRepair),
+ );
// Forward the designated Realms options.
const realmsOptions = {};
@@ -134,23 +139,28 @@ You probably want a Compartment instead, like:
r.global.console = r.evaluate(s)(console);
}
- // Gather the primordials and global.
+ // Extract the intrinsics from the global.
const anonIntrinsics = r.evaluate(`(${getAnonIntrinsics})`)(r.global);
- const allIntrinsics = r.evaluate(`(${getAllPrimordials})`)(
+ const namedIntrinsics = r.evaluate(`(${getNamedIntrinsics})`)(r.global);
+
+ // Gather the intrinsics only.
+ const allIntrinsics = r.evaluate(`(${getAllIntrinsics})`)(
+ namedIntrinsics,
+ anonIntrinsics,
+ );
+
+ // Gather the primordials and the globals.
+ const allPrimordials = r.evaluate(`(${getAllPrimordials})`)(
r.global,
anonIntrinsics,
);
- // Repair the override mistake on the primordials and global.
- const repairPlan =
- optDataPropertiesToRepair !== undefined
- ? optDataPropertiesToRepair
- : dataPropertiesToRepair;
+ // Repair the override mistake on the intrinsics only.
r.evaluate(`(${repairDataProperties})`)(allIntrinsics, repairPlan);
// Finally freeze all the primordials, and the global object. This must
// be the last thing we do that modifies the Realm's globals.
- harden(allIntrinsics);
+ harden(allPrimordials);
// build the makeRequire helper, glue it to the new Realm
r.makeRequire = harden(r.evaluate(`(${makeMakeRequire})`)(r, harden));

MODIFY
src/bundle/dataPropertiesToRepair.js
src/bundle/dataPropertiesToRepair.js
* repaired enviromment, compared to the non-repaired case. In order
* to maintain performance, we only repair the properties of objects
* for which hardening causes a breakage of their intended usage. There
- * are two cases:
+ * are three cases:
* <ul>Overriding properties on objects typically used as maps,
* namely {@code "Object"} and {@code "Array"}. In the case of arrays,
* a given program might not be aware that non-numerical properties are
* prototype that programs typically override by assignment, such as
* {@code "Error.prototype.message"} and {@code "Function.prototype.name"}
* (both default to "").
+ * <ul>Setting a prototype chain. The constructor is typically set by
+ * assignment, for example {@code "Child.prototype.constructor = Child"}.
*
* <p>Each JSON record enumerates the disposition of the properties on
* some corresponding primordial object, with the root record containing:
@@ -77,6 +79,7 @@ export default {
Function: {
prototype: {
+ constructor: t,
bind: t, // set by "underscore"
constructor: t, // set by "regenerator-runtime"
name: t,

ADD
src/bundle/getAllIntrinsics.js
+export default function getAllPrimordials(namedIntrinsics, anonIntrinsics) {
+ 'use strict';
+
+ const root = {
+ namedIntrinsics,
+ anonIntrinsics,
+ };
+
+ return root;
+}

ADD
src/bundle/namedIntrinsics.js
+
+export default function getNamedIntrinsics(unsafeGlobal) {
+ const { defineProperty, getOwnPropertyDescriptor } = Reflect;
+
+ const globalPropertyNames = [
+ // *** 18.1 Value Properties of the Global Object
+
+ 'Infinity',
+ 'NaN',
+ 'undefined',
+
+ // *** 18.2 Function Properties of the Global Object
+
+ 'eval',
+ 'isFinite',
+ 'isNaN',
+ 'parseFloat',
+ 'parseInt',
+
+ 'decodeURI',
+ 'decodeURIComponent',
+ 'encodeURI',
+ 'encodeURIComponent',
+
+ // *** 18.3 Constructor Properties of the Global Object
+
+ 'Array',
+ 'ArrayBuffer',
+ 'Boolean',
+ 'DataView',
+ 'Date',
+ 'Error',
+ 'EvalError',
+ 'Float32Array',
+ 'Float64Array',
+ 'Function',
+ 'Int8Array',
+ 'Int16Array',
+ 'Int32Array',
+ 'Map',
+ 'Number',
+ 'Object',
+ 'Promise',
+ 'Proxy',
+ 'RangeError',
+ 'ReferenceError',
+ 'RegExp',
+ 'Set',
+ // 'SharedArrayBuffer', // removed on Jan 5, 2018
+ 'String',
+ 'Symbol',
+ 'SyntaxError',
+ 'TypeError',
+ 'Uint8Array',
+ 'Uint8ClampedArray',
+ 'Uint16Array',
+ 'Uint32Array',
+ 'URIError',
+ 'WeakMap',
+ 'WeakSet',
+
+ // *** 18.4 Other Properties of the Global Object
+
+ // 'Atomics', // removed on Jan 5, 2018
+ 'JSON',
+ 'Math',
+ 'Reflect',
+
+ // *** Annex B
+
+ 'escape',
+ 'unescape',
+
+ // *** ECMA-402
+
+ 'Intl',
+
+ // *** ESNext
+
+ // 'Realm' // Comes from createRealmGlobalObject()
+ ];
+
+ const namedIntrinsics = {};
+
+ for (const name of globalPropertyNames) {
+ const desc = getOwnPropertyDescriptor(unsafeGlobal, name);
+ if (desc) {
+ // Abort if an accessor is found on the unsafe global object
+ // instead of a data property. We should never get into this
+ // non standard situation.
+ if ('get' in desc || 'set' in desc) {
+ throw new TypeError(`unexpected accessor on global property: ${name}`);
+ }
+
+ defineProperty(namedIntrinsics, name, desc);
+ }
+ }
+
+ return namedIntrinsics;
+}

MODIFY
src/bundle/repairDataProperties.js
src/bundle/repairDataProperties.js
@@ -13,6 +13,7 @@ export default function repairDataProperties(intrinsics, repairPlan) {
getOwnPropertyDescriptors,
prototype: { hasOwnProperty },
} = Object;
+
const { ownKeys } = Reflect;
/**
@@ -126,11 +127,6 @@ export default function repairDataProperties(intrinsics, repairPlan) {
});
}
- // Rename global -> namedIntrinsics to match the whitelist.js
- // convention.
- const { anonIntrinsics, global: namedIntrinsics } = intrinsics;
- const renamedIntrinsics = { anonIntrinsics, namedIntrinsics };
-
// Do the repair.
- walkRepairPlan(renamedIntrinsics, repairPlan);
+ walkRepairPlan(intrinsics, repairPlan);
}

Addressing comments in PR 146 and 150