Skip to content

Commit

Permalink
prevent possible almost infinite loop in non-standard implementations…
Browse files Browse the repository at this point in the history
… of some backward iteration array methods
  • Loading branch information
zloirock committed Jan 12, 2020
1 parent 04218dc commit 9e13025
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## Changelog
##### Unreleased
- Prevented a possible almost infinite loop in non-standard implementations of some backward iteration array methods

##### 3.6.3 - 2020.01.11
- Fixed replacement of substitutes of undefined capture groups in `.replace` in Safari 13.0-, [#471](https://github.com/zloirock/core-js/issues/471), [#745](https://github.com/zloirock/core-js/issues/745), thanks [@mattclough1](https://github.com/mattclough1)
- Improved compat data for old engines
Expand Down
3 changes: 2 additions & 1 deletion packages/core-js/internals/array-last-index-of.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ var min = Math.min;
var nativeLastIndexOf = [].lastIndexOf;
var NEGATIVE_ZERO = !!nativeLastIndexOf && 1 / [1].lastIndexOf(1, -0) < 0;
var STRICT_METHOD = arrayMethodIsStrict('lastIndexOf');
var USES_TO_LENGTH = arrayMethodUsesToLength('lastIndexOf', { ACCESSORS: true, 1: 2147483647 });
// For preventing possible almost infinite loop in non-standard implementations, test the forward version of the method
var USES_TO_LENGTH = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });
var FORCED = NEGATIVE_ZERO || !STRICT_METHOD || !USES_TO_LENGTH;

// `Array.prototype.lastIndexOf` method implementation
Expand Down
13 changes: 5 additions & 8 deletions packages/core-js/internals/array-method-uses-to-length.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,25 @@ var fails = require('../internals/fails');
var has = require('../internals/has');

var defineProperty = Object.defineProperty;
var cache = {};

var thrower = function (it) { throw it; };

module.exports = function (METHOD_NAME, options) {
if (has(cache, METHOD_NAME)) return cache[METHOD_NAME];
if (!options) options = {};
var method = [][METHOD_NAME];
var ACCESSORS = has(options, 'ACCESSORS') ? options.ACCESSORS : false;
var argument0 = has(options, 0) ? options[0] : thrower;
var argument1 = has(options, 1) ? options[1] : undefined;

return !!method && !fails(function () {
return cache[METHOD_NAME] = !!method && !fails(function () {
if (ACCESSORS && !DESCRIPTORS) return true;
var O = { length: -1 };

var addTrap = function (key) {
if (ACCESSORS) defineProperty(O, key, { enumerable: true, get: thrower });
else O[key] = 1;
};
if (ACCESSORS) defineProperty(O, 1, { enumerable: true, get: thrower });
else O[1] = 1;

addTrap(1);
addTrap(2147483646);
addTrap(4294967294);
method.call(O, argument0, argument1);
});
};
3 changes: 2 additions & 1 deletion packages/core-js/modules/es.array.reduce-right.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ var arrayMethodIsStrict = require('../internals/array-method-is-strict');
var arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');

var STRICT_METHOD = arrayMethodIsStrict('reduceRight');
var USES_TO_LENGTH = arrayMethodUsesToLength('reduceRight', { 1: 0 });
// For preventing possible almost infinite loop in non-standard implementations, test the forward version of the method
var USES_TO_LENGTH = arrayMethodUsesToLength('reduce', { 1: 0 });

// `Array.prototype.reduceRight` method
// https://tc39.github.io/ecma262/#sec-array.prototype.reduceright
Expand Down
16 changes: 5 additions & 11 deletions tests/compat/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,10 @@ GLOBAL.tests = {
return true;
},
'es.array.last-index-of': function () {
[].lastIndexOf.call(Object.defineProperties({ length: -1 }, {
2147483646: {
enumerable: true,
get: function (it) { throw it; }
},
4294967294: {
enumerable: true,
get: function (it) { throw it; }
}
}), 2147483647);
[].indexOf.call(Object.defineProperty({ length: -1 }, 0, {
enumerable: true,
get: function (it) { throw it; }
}), 0);
try {
[].lastIndexOf.call(null);
} catch (error) {
Expand Down Expand Up @@ -359,7 +353,7 @@ GLOBAL.tests = {
}
},
'es.array.reduce-right': function () {
[].reduceRight.call({ length: -1, 2147483646: 1, 4294967294: 1 }, function (it) { throw it; }, 1);
[].reduce.call({ length: -1, 0: 1 }, function (it) { throw it; }, 0);
try {
Array.prototype.reduceRight.call(null, function () { /* empty */ }, 1);
} catch (error) {
Expand Down

0 comments on commit 9e13025

Please sign in to comment.