Skip to content

Commit

Permalink
fix(ses): regexp taming
Browse files Browse the repository at this point in the history
Bad RegExp taming revealed by #237 

Exclude similar but new test failures
  • Loading branch information
erights committed Mar 23, 2020
1 parent f0f42f2 commit b010f8a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
18 changes: 9 additions & 9 deletions packages/ses/src/tame-global-reg-exp-object.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
const {
defineProperties,
getOwnPropertyDescriptors,
getOwnPropertyDescriptor,
} = Object;
const { defineProperties, getOwnPropertyDescriptor } = Object;

export default function tameGlobalRegExpObject() {
// Tame the %RegExp% intrinsic.
Expand All @@ -22,13 +18,17 @@ export default function tameGlobalRegExpObject() {
};

// Whitelist static properties.
// See https://github.com/Agoric/SES-shim/issues/239
const desc = getOwnPropertyDescriptor(unsafeRegExp, Symbol.species);
defineProperties(tamedRegExp, Symbol.species, desc);

// Copy prototype properties.
const prototypeDescs = getOwnPropertyDescriptors(unsafeRegExp.prototype);
prototypeDescs.constructor.value = tamedRegExp;
defineProperties(tamedRegExp.prototype, prototypeDescs);
const RegExpPrototype = unsafeRegExp.prototype;
defineProperties(tamedRegExp, {
prototype: { value: RegExpPrototype },
});
defineProperties(RegExpPrototype, {
constructor: { value: tamedRegExp },
});

// Done with RegExp constructor.
globalThis.RegExp = tamedRegExp;
Expand Down
57 changes: 55 additions & 2 deletions packages/ses/test/tame-global-reg-exp-object.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,60 @@ import tameGlobalRegExpObject from '../src/tame-global-reg-exp-object.js';

const { test } = tap;

test('tameGlobalRegExpObject - constructor', t => {
t.plan(8);
test('tameGlobalRegExpObject - unsafeRegExp denied', t => {
const unsafeRegExp = RegExp;
const restore = captureGlobals('RegExp');
tameGlobalRegExpObject();

t.ok(unsafeRegExp !== RegExp, 'constructor not replaced');
const regexp = /./;
t.ok(regexp.constructor === RegExp, 'tamed constructor not reached');
// Don't leak the unsafe constructor
// https://github.com/Agoric/SES-shim/issues/237
t.ok(regexp.constructor !== unsafeRegExp, 'unsafe constructor reachable!');

restore();
t.end();
});

test('tameGlobalRegExpObject - undeniable prototype', t => {
const restore = captureGlobals('RegExp');
tameGlobalRegExpObject();

// Don't try to deny the undeniable
// https://github.com/Agoric/SES-shim/issues/237
const regexp1 = new RegExp('.');
const regexp2 = RegExp('.');
const regexp3 = /./;
t.ok(
// eslint-disable-next-line no-proto
regexp1.__proto__ === regexp2.__proto__,
'new vs non-new instances differ',
);
t.ok(
// eslint-disable-next-line no-proto
regexp1.__proto__ === regexp3.__proto__,
'new vs literal instances differ',
);

t.ok(
regexp1 instanceof RegExp,
'new instance not instanceof tamed constructor',
);
t.ok(
regexp2 instanceof RegExp,
'non-new instance not instanceof tamed constructor',
);
t.ok(
regexp3 instanceof RegExp,
'literal instance not instanceof tamed constructor',
);

restore();
t.end();
});

test('tameGlobalRegExpObject - constructor', t => {
const restore = captureGlobals('RegExp');
tameGlobalRegExpObject();

Expand All @@ -20,6 +71,7 @@ test('tameGlobalRegExpObject - constructor', t => {
const properties = Reflect.ownKeys(RegExp);
t.deepEqual(
properties.sort(),
// See https://github.com/Agoric/SES-shim/issues/239
['length', 'name', 'prototype'].sort(),
'RegExp should not have static properties',
);
Expand All @@ -35,4 +87,5 @@ test('tameGlobalRegExpObject - constructor', t => {
t.equal(RegExp('foo').test('foobar'), true);

restore();
t.end();
});
3 changes: 3 additions & 0 deletions packages/ses/test262/tame-global-regexp-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ test262Runner({
'test/built-ins/RegExp/prototype/Symbol.split/last-index-exceeds-str-size.js',
'test/built-ins/RegExp/prototype/test/S15.10.6.3_A9.js',
'test/built-ins/RegExp/prototype/unicode/this-val-regexp-prototype.js',
'test/built-ins/RegExp/S15.10.3.1_A1_T1.js',
'test/built-ins/RegExp/S15.10.3.1_A1_T2.js',
'test/built-ins/RegExp/S15.10.3.1_A1_T3.js',
'test/built-ins/RegExp/S15.10.3.1_A1_T4.js',
'test/built-ins/RegExp/S15.10.3.1_A1_T5.js',
'test/built-ins/RegExp/S15.10.3.1_A2_T2.js',
'test/built-ins/RegExp/S15.10.3.1_A3_T1.js',
'test/built-ins/RegExp/S15.10.3.1_A3_T2.js',
Expand Down

0 comments on commit b010f8a

Please sign in to comment.