diff --git a/CHANGELOG.md b/CHANGELOG.md index 9448326954b5..4b4b82944999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Work with symbols made stricter: some missed before case of methods that should throw error on symbols now works as they should - Handling `@@toPrimitive` in some cases of `ToPrimitive` internal logic made stricter - Fixed work of `Request` with polyfilled `URLSearchParams`, [#965](https://github.com/zloirock/core-js/issues/965) +- Fixed possible exposing of collections elements metadata in some cases, [#427](https://github.com/zloirock/core-js/issues/427) - Fixed some cases of typed arrays subclassing logic - Fixed a minor bug related to string conversion in `RegExp#exec` - Fixed `Date.prototype.getYear` feature detection and compat data for IE8- diff --git a/packages/core-js-pure/override/internals/collection.js b/packages/core-js-pure/override/internals/collection.js index cfd655d2339d..ef11c2f635dd 100644 --- a/packages/core-js-pure/override/internals/collection.js +++ b/packages/core-js-pure/override/internals/collection.js @@ -30,7 +30,7 @@ module.exports = function (CONSTRUCTOR_NAME, wrapper, common) { ) { // create collection constructor Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); - InternalMetadataModule.REQUIRED = true; + InternalMetadataModule.enable(); } else { Constructor = wrapper(function (target, iterable) { setInternalState(anInstance(target, Constructor, CONSTRUCTOR_NAME), { diff --git a/packages/core-js/internals/collection.js b/packages/core-js/internals/collection.js index 775ab3d2291b..6cc578f38c1a 100644 --- a/packages/core-js/internals/collection.js +++ b/packages/core-js/internals/collection.js @@ -50,7 +50,7 @@ module.exports = function (CONSTRUCTOR_NAME, wrapper, common) { if (REPLACE) { // create collection constructor Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); - InternalMetadataModule.REQUIRED = true; + InternalMetadataModule.enable(); } else if (isForced(CONSTRUCTOR_NAME, true)) { var instance = new Constructor(); // early implementations not supports chaining diff --git a/packages/core-js/internals/internal-metadata.js b/packages/core-js/internals/internal-metadata.js index f8cb206b3875..15f6bae854d3 100644 --- a/packages/core-js/internals/internal-metadata.js +++ b/packages/core-js/internals/internal-metadata.js @@ -1,10 +1,14 @@ +var $ = require('../internals/export'); var hiddenKeys = require('../internals/hidden-keys'); var isObject = require('../internals/is-object'); var has = require('../internals/has'); var defineProperty = require('../internals/object-define-property').f; +var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names'); +var getOwnPropertyNamesExternalModule = require('../internals/object-get-own-property-names-external'); var uid = require('../internals/uid'); var FREEZING = require('../internals/freezing'); +var REQUIRED = false; var METADATA = uid('meta'); var id = 0; @@ -48,12 +52,38 @@ var getWeakData = function (it, create) { // add metadata on freeze-family methods calling var onFreeze = function (it) { - if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it); + if (FREEZING && REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it); return it; }; +var enable = function () { + meta.enable = function () { /* empty */ }; + REQUIRED = true; + var getOwnPropertyNames = getOwnPropertyNamesModule.f; + var splice = [].splice; + var test = {}; + test[METADATA] = 1; + + // prevent exposing of metadata key + if (getOwnPropertyNames(test).length) { + getOwnPropertyNamesModule.f = function (it) { + var result = getOwnPropertyNames(it); + for (var i = 0, length = result.length; i < length; i++) { + if (result[i] === METADATA) { + splice.call(result, i, 1); + break; + } + } return result; + }; + + $({ target: 'Object', stat: true, forced: true }, { + getOwnPropertyNames: getOwnPropertyNamesExternalModule.f + }); + } +}; + var meta = module.exports = { - REQUIRED: false, + enable: enable, fastKey: fastKey, getWeakData: getWeakData, onFreeze: onFreeze diff --git a/packages/core-js/modules/es.weak-map.js b/packages/core-js/modules/es.weak-map.js index 384de6571d24..24b5a6badfd9 100644 --- a/packages/core-js/modules/es.weak-map.js +++ b/packages/core-js/modules/es.weak-map.js @@ -28,7 +28,7 @@ var $WeakMap = module.exports = collection('WeakMap', wrapper, collectionWeak); // https://github.com/zloirock/core-js/issues/485 if (NATIVE_WEAK_MAP && IS_IE11) { InternalWeakMap = collectionWeak.getConstructor(wrapper, 'WeakMap', true); - InternalMetadataModule.REQUIRED = true; + InternalMetadataModule.enable(); var WeakMapPrototype = $WeakMap.prototype; var nativeDelete = WeakMapPrototype['delete']; var nativeHas = WeakMapPrototype.has; diff --git a/tests/pure/es.object.get-own-property-names.js b/tests/pure/es.object.get-own-property-names.js index 5fd043086c87..47410b83e3b0 100644 --- a/tests/pure/es.object.get-own-property-names.js +++ b/tests/pure/es.object.get-own-property-names.js @@ -1,6 +1,7 @@ import { GLOBAL } from '../helpers/constants'; import { includes } from '../helpers/helpers'; +import freeze from 'core-js-pure/features/object/freeze'; import getOwnPropertyNames from 'core-js-pure/features/object/get-own-property-names'; QUnit.test('Object.getOwnPropertyNames', assert => { @@ -24,6 +25,7 @@ QUnit.test('Object.getOwnPropertyNames', assert => { assert.ok(includes(getOwnPropertyNames(Array.prototype), 'toString')); assert.ok(includes(getOwnPropertyNames(Object.prototype), 'toString')); assert.ok(includes(getOwnPropertyNames(Object.prototype), 'constructor')); + assert.deepEqual(getOwnPropertyNames(freeze({})), [], 'frozen'); const primitives = [42, 'foo', false]; for (const value of primitives) { assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`); diff --git a/tests/tests/es.object.get-own-property-names.js b/tests/tests/es.object.get-own-property-names.js index b0c654c43670..39ee08abe906 100644 --- a/tests/tests/es.object.get-own-property-names.js +++ b/tests/tests/es.object.get-own-property-names.js @@ -2,7 +2,7 @@ import { GLOBAL } from '../helpers/constants'; import { includes } from '../helpers/helpers'; QUnit.test('Object.getOwnPropertyNames', assert => { - const { getOwnPropertyNames } = Object; + const { freeze, getOwnPropertyNames } = Object; assert.isFunction(getOwnPropertyNames); assert.arity(getOwnPropertyNames, 1); assert.name(getOwnPropertyNames, 'getOwnPropertyNames'); @@ -26,6 +26,7 @@ QUnit.test('Object.getOwnPropertyNames', assert => { assert.ok(includes(getOwnPropertyNames(Array.prototype), 'toString')); assert.ok(includes(getOwnPropertyNames(Object.prototype), 'toString')); assert.ok(includes(getOwnPropertyNames(Object.prototype), 'constructor')); + assert.deepEqual(getOwnPropertyNames(freeze({})), [], 'frozen'); const primitives = [42, 'foo', false]; for (const value of primitives) { assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`);