mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-01 07:47:49 +00:00
Add keyPrefix to avoid issues with __proto__. [closes #226]
Former-commit-id: 55dee782acdd5e28229b1fcb7587424d3fdfd445
This commit is contained in:
23
lodash.js
23
lodash.js
@@ -29,6 +29,9 @@
|
||||
/** Used internally to indicate various things */
|
||||
var indicatorObject = {};
|
||||
|
||||
/** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
|
||||
var keyPrefix = +new Date + '';
|
||||
|
||||
/** Used to match empty string literals in compiled template source */
|
||||
var reEmptyStringLeading = /\b__p \+= '';/g,
|
||||
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
|
||||
@@ -586,16 +589,14 @@
|
||||
index = fromIndex - 1;
|
||||
|
||||
while (++index < length) {
|
||||
// manually coerce `value` to a string because `hasOwnProperty`, in some
|
||||
// older versions of Firefox, coerces objects incorrectly
|
||||
var key = String(array[index]);
|
||||
(hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
|
||||
var key = keyPrefix + array[index];
|
||||
(cache[key] || (cache[key] = [])).push(array[index]);
|
||||
}
|
||||
}
|
||||
return function(value) {
|
||||
if (isLarge) {
|
||||
var key = String(value);
|
||||
return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
|
||||
var key = keyPrefix + value;
|
||||
return cache[key] && indexOf(cache[key], value) > -1;
|
||||
}
|
||||
return indexOf(array, value, fromIndex) > -1;
|
||||
}
|
||||
@@ -3623,8 +3624,8 @@
|
||||
while (++index < length) {
|
||||
var value = array[index];
|
||||
if (isLarge) {
|
||||
var key = String(value);
|
||||
var inited = hasOwnProperty.call(cache[0], key)
|
||||
var key = keyPrefix + value;
|
||||
var inited = cache[0][key]
|
||||
? !(seen = cache[0][key])
|
||||
: (seen = cache[0][key] = []);
|
||||
}
|
||||
@@ -4031,8 +4032,8 @@
|
||||
computed = callback ? callback(value, index, array) : value;
|
||||
|
||||
if (isLarge) {
|
||||
var key = String(computed);
|
||||
var inited = hasOwnProperty.call(cache, key)
|
||||
var key = keyPrefix + computed;
|
||||
var inited = cache[key]
|
||||
? !(seen = cache[key])
|
||||
: (seen = cache[key] = []);
|
||||
}
|
||||
@@ -4517,7 +4518,7 @@
|
||||
function memoize(func, resolver) {
|
||||
var cache = {};
|
||||
return function() {
|
||||
var key = String(resolver ? resolver.apply(this, arguments) : arguments[0]);
|
||||
var key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
|
||||
return hasOwnProperty.call(cache, key)
|
||||
? cache[key]
|
||||
: (cache[key] = func.apply(this, arguments));
|
||||
|
||||
30
test/test.js
30
test/test.js
@@ -1074,6 +1074,36 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('`__proto__` property bugs');
|
||||
|
||||
(function() {
|
||||
var stringLiteral = '__proto__',
|
||||
stringObject = Object(stringLiteral),
|
||||
expected = [stringLiteral, stringObject];
|
||||
|
||||
var array = _.times(100, function(count) {
|
||||
return count % 2 ? stringObject : stringLiteral;
|
||||
});
|
||||
|
||||
test('internal data objects should work with the `__proto__` key', function() {
|
||||
deepEqual(_.difference(array, array), []);
|
||||
deepEqual(_.intersection(array, array), expected);
|
||||
deepEqual(_.uniq(array), expected);
|
||||
deepEqual(_.without.apply(_, [array].concat(array)), []);
|
||||
});
|
||||
|
||||
test('lodash.memoize should memoize values resolved to the `__proto__` key', function() {
|
||||
var count = 0,
|
||||
memoized = _.memoize(function() { return ++count; });
|
||||
|
||||
memoized('__proto__');
|
||||
memoized('__proto__');
|
||||
strictEqual(count, 1);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.groupBy');
|
||||
|
||||
(function() {
|
||||
|
||||
Reference in New Issue
Block a user