-
Notifications
You must be signed in to change notification settings - Fork 216
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy own __proto__ safely
- Loading branch information
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
var merge = require('../') | ||
var test = require('tape') | ||
var isMergeableObject = require('is-mergeable-object') | ||
|
||
test('merging objects with own __proto__', function(t) { | ||
var user = {} | ||
var malicious = JSON.parse('{ "__proto__": { "admin": true } }') | ||
var mergedObject = merge(user, malicious) | ||
t.notOk(mergedObject.__proto__.admin, 'non-plain properties should not be merged') | ||
t.notOk(mergedObject.admin, 'the destination should have an unmodified prototype') | ||
t.end() | ||
}) | ||
|
||
test('merging objects with plain and non-plain properties', function(t) { | ||
var plainSymbolKey = Symbol('plainSymbolKey') | ||
var parent = { | ||
parentKey: 'should be undefined' | ||
} | ||
|
||
var target = Object.create(parent) | ||
target.plainKey = 'should be replaced' | ||
target[plainSymbolKey] = 'should also be replaced' | ||
|
||
var source = { | ||
parentKey: 'foo', | ||
plainKey: 'bar', | ||
newKey: 'baz', | ||
[plainSymbolKey]: 'qux' | ||
} | ||
|
||
var mergedObject = merge(target, source) | ||
t.equal(undefined, mergedObject.parentKey, 'inherited properties of target should be removed, not merged or ignored') | ||
t.equal('bar', mergedObject.plainKey, 'enumerable own properties of target should be merged') | ||
t.equal('baz', mergedObject.newKey, 'properties not yet on target should be merged') | ||
t.equal('qux', mergedObject[plainSymbolKey], 'enumerable own symbol properties of target should be merged') | ||
t.end() | ||
}) | ||
|
||
// the following cases come from the thread here: https://github.com/TehShrike/deepmerge/pull/164 | ||
test('merging strings works with a custom string merge', function(t) { | ||
var target = { name: "Alexander" } | ||
var source = { name: "Hamilton" } | ||
function customMerge(key, options) { | ||
if (key === 'name') { | ||
return function(target, source, options) { | ||
return target[0] + '. ' + source.substring(0, 3) | ||
} | ||
} else { | ||
return merge | ||
} | ||
} | ||
|
||
function mergeable(target) { | ||
return isMergeableObject(target) || (typeof target === 'string' && target.length > 1) | ||
} | ||
|
||
t.equal('A. Ham', merge(target, source, { customMerge: customMerge, isMergeableObject: mergeable }).name) | ||
t.end() | ||
}) | ||
|
||
test('merging objects with null prototype', function(t) { | ||
var target = Object.create(null) | ||
var source = Object.create(null) | ||
target.wheels = 4 | ||
target.trunk = { toolbox: ['hammer'] } | ||
source.trunk = { toolbox: ['wrench'] } | ||
source.engine = 'v8' | ||
var expected = { | ||
wheels: 4, | ||
engine: 'v8', | ||
trunk: { | ||
toolbox: ['hammer', 'wrench' ] | ||
} | ||
} | ||
|
||
t.deepEqual(expected, merge(target, source)) | ||
t.end() | ||
}) |