Avoid stack overflow with _.defaultsDeep.

This commit is contained in:
John-David Dalton
2015-08-13 01:30:24 -07:00
parent 9f0dd40b3b
commit dd472f489b
2 changed files with 24 additions and 6 deletions

View File

@@ -2313,7 +2313,8 @@
srcValue = source[key]; srcValue = source[key];
while (length--) { while (length--) {
if (stackA[length] == srcValue) { var stacked = stackA[length];
if (stacked == srcValue || stacked == oldValue) {
assignMergeValue(object, key, stackB[length]); assignMergeValue(object, key, stackB[length]);
return; return;
} }
@@ -4073,15 +4074,12 @@
* @returns {*} Returns the value to assign to the destination object. * @returns {*} Returns the value to assign to the destination object.
*/ */
function mergeDefaults(objectValue, sourceValue, key, object, source, stackA, stackB) { function mergeDefaults(objectValue, sourceValue, key, object, source, stackA, stackB) {
if (objectValue === undefined) {
return sourceValue;
}
if (isObject(objectValue)) { if (isObject(objectValue)) {
stackA.push(objectValue); stackA.push(objectValue);
stackB.push(objectValue); stackB.push(objectValue);
return baseMerge(objectValue, sourceValue, mergeDefaults, stackA, stackB); baseMerge(objectValue, sourceValue, mergeDefaults, stackA, stackB);
} }
return objectValue; return objectValue === undefined ? sourceValue : objectValue;
} }
/** /**

View File

@@ -3023,6 +3023,26 @@
strictEqual(actual.a.b, 2); strictEqual(actual.a.b, 2);
}); });
test('should merge sources containing circular references', 1, function() {
var object = {
'foo': { 'b': { 'c': { 'd': {} } } },
'bar': { 'a': 2 }
};
var source = {
'foo': { 'b': { 'c': { 'd': {} } } },
'bar': {}
};
object.foo.b.c.d = object;
source.foo.b.c.d = source;
source.bar.b = source.foo.b;
var actual = _.defaultsDeep(object, source);
console.log(actual.bar.b === actual.foo.b , actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
ok(actual.bar.b === source.foo.b && actual.foo.b.c.d === actual.foo.b.c.d.foo.b.c.d);
});
}()); }());
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/