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