Skip to content

Commit eb35714

Browse files
committed
Do not report "constructor" es duplicate key
Check only own object keys for duplicates. Not keys from the prototype. Fixes the original part of #23.
1 parent 923f37f commit eb35714

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

src/custom-parser.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ const unescapeMap = {
3535
'/': '/'
3636
}
3737

38+
const ownsProperty = Object.prototype.hasOwnProperty
39+
3840
function parseInternal (input, options) {
3941
if (typeof input !== 'string' || !(input instanceof String)) {
4042
input = String(input)
@@ -318,7 +320,7 @@ function parseInternal (input, options) {
318320
while (position < inputLength) {
319321
skipWhiteSpace()
320322
const key = parseKey()
321-
if (allowDuplicateObjectKeys === false && result[key]) {
323+
if (allowDuplicateObjectKeys === false && ownsProperty.call(result, key)) {
322324
fail(`Duplicate key: "${key}"`)
323325
}
324326
skipWhiteSpace()

test/parse2.js

+11
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ test('duplicate keys', function () {
157157
})
158158
})
159159

160+
test('no duplicate key "constructor"', function () {
161+
assert.deepEqual(parse('{ "constructor": 1 }'), { constructor: 1 })
162+
parse('{ "constructor": 1 }', { allowDuplicateObjectKeys: false })
163+
})
164+
165+
test('no prototype pollution', function () {
166+
const parsed = parse('{ "__proto__": { "polluted": true } }')
167+
assert.deepEqual(parsed, JSON.parse('{ "__proto__": { "polluted": true } }'))
168+
assert.notDeepEqual(parsed, { polluted: true })
169+
})
170+
160171
test('random numbers', function () {
161172
for (let i = 0; i < 100; ++i) {
162173
const str = '-01.e'.split('')

0 commit comments

Comments
 (0)