Freeze Promise global on boot (#7309)
* freeze background and UI Promise globals on boot * add new tests * remove tapefeature/default_network_editable
parent
5f4cce13f0
commit
478d6563f2
@ -0,0 +1,41 @@ |
|||||||
|
|
||||||
|
/** |
||||||
|
* Freezes the Promise global and prevents its reassignment. |
||||||
|
*/ |
||||||
|
const deepFreeze = require('deep-freeze-strict') |
||||||
|
|
||||||
|
if ( |
||||||
|
process.env.IN_TEST !== 'true' && |
||||||
|
process.env.METAMASK_ENV !== 'test' |
||||||
|
) { |
||||||
|
freeze(global, 'Promise') |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Makes a key:value pair on a target object immutable, with limitations. |
||||||
|
* The key cannot be reassigned or deleted, and the value is recursively frozen |
||||||
|
* using Object.freeze. |
||||||
|
* |
||||||
|
* Because of JavaScript language limitations, this is does not mean that the |
||||||
|
* value is completely immutable. It is, however, better than nothing. |
||||||
|
* |
||||||
|
* @param {Object} target - The target object to freeze a property on. |
||||||
|
* @param {String} key - The key to freeze. |
||||||
|
* @param {any} [value] - The value to freeze, if different from the existing value on the target. |
||||||
|
* @param {boolean} [enumerable=true] - If given a value, whether the property is enumerable. |
||||||
|
*/ |
||||||
|
function freeze (target, key, value, enumerable = true) { |
||||||
|
|
||||||
|
const opts = { |
||||||
|
configurable: false, writable: false, |
||||||
|
} |
||||||
|
|
||||||
|
if (value !== undefined) { |
||||||
|
opts.value = deepFreeze(value) |
||||||
|
opts.enumerable = enumerable |
||||||
|
} else { |
||||||
|
target[key] = deepFreeze(target[key]) |
||||||
|
} |
||||||
|
|
||||||
|
Object.defineProperty(target, key, opts) |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
|
||||||
|
/* eslint-disable no-native-reassign */ |
||||||
|
|
||||||
|
// this is what we're testing
|
||||||
|
require('../../app/scripts/lib/freezeGlobals') |
||||||
|
|
||||||
|
const assert = require('assert') |
||||||
|
|
||||||
|
describe('Promise global is immutable', () => { |
||||||
|
|
||||||
|
it('throws when reassinging promise (syntax 1)', () => { |
||||||
|
try { |
||||||
|
Promise = {} |
||||||
|
assert.fail('did not throw error') |
||||||
|
} catch (err) { |
||||||
|
assert.ok(err, 'did throw error') |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it('throws when reassinging promise (syntax 2)', () => { |
||||||
|
try { |
||||||
|
global.Promise = {} |
||||||
|
assert.fail('did not throw error') |
||||||
|
} catch (err) { |
||||||
|
assert.ok(err, 'did throw error') |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it('throws when mutating existing Promise property', () => { |
||||||
|
try { |
||||||
|
Promise.all = () => {} |
||||||
|
assert.fail('did not throw error') |
||||||
|
} catch (err) { |
||||||
|
assert.ok(err, 'did throw error') |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it('throws when adding new Promise property', () => { |
||||||
|
try { |
||||||
|
Promise.foo = 'bar' |
||||||
|
assert.fail('did not throw error') |
||||||
|
} catch (err) { |
||||||
|
assert.ok(err, 'did throw error') |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
it('throws when deleting Promise from global', () => { |
||||||
|
try { |
||||||
|
delete global.Promise |
||||||
|
assert.fail('did not throw error') |
||||||
|
} catch (err) { |
||||||
|
assert.ok(err, 'did throw error') |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
Loading…
Reference in new issue