diff --git a/CHANGELOG.md b/CHANGELOG.md index be9e98d5..594de02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +### Unreleased [[code][c-unreleased], [diff][d-unreleased]] + +[c-unreleased]: https://github.com/json5/json5/tree/v1 +[d-unreleased]: https://github.com/json5/json5/compare/v1.0.1...v1 + +- Fix: Properties with the name `__proto__` are added to objects and arrays. + ([#199]) + + ### v1.0.1 [[code][c1.0.1], [diff][d1.0.1]] [c1.0.1]: https://github.com/json5/json5/tree/v1.0.1 @@ -272,3 +281,4 @@ parser for the regular JSON format. [#108]: https://github.com/json5/json5/pull/108 [#134]: https://github.com/json5/json5/pull/134 [#154]: https://github.com/json5/json5/issues/154 +[#199]: https://github.com/json5/json5/issues/199 diff --git a/src/parse.js b/src/parse.js index 675d4c32..2d62b29c 100644 --- a/src/parse.js +++ b/src/parse.js @@ -42,12 +42,34 @@ export default function parse (text, reviver) { function internalize (holder, name, reviver) { const value = holder[name] if (value != null && typeof value === 'object') { - for (const key in value) { - const replacement = internalize(value, key, reviver) - if (replacement === undefined) { - delete value[key] - } else { - value[key] = replacement + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const key = String(i) + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + } else { + for (const key in value) { + const replacement = internalize(value, key, reviver) + if (replacement === undefined) { + delete value[key] + } else { + Object.defineProperty(value, key, { + value: replacement, + writable: true, + enumerable: true, + configurable: true, + }) + } } } } @@ -973,7 +995,12 @@ function push () { if (Array.isArray(parent)) { parent.push(value) } else { - parent[key] = value + Object.defineProperty(parent, key, { + value, + writable: true, + enumerable: true, + configurable: true, + }) } } diff --git a/test/parse.js b/test/parse.js index 9d4f4e02..7229f038 100644 --- a/test/parse.js +++ b/test/parse.js @@ -33,6 +33,11 @@ describe('JSON5', () => { assert.deepStrictEqual(JSON5.parse('{\\u0061\\u0062:1,\\u0024\\u005F:2,\\u005F\\u0024:3}'), {ab: 1, $_: 2, _$: 3}) }) + it('preserves __proto__ property names', () => { + // eslint-disable-next-line no-proto + assert.strictEqual(JSON5.parse('{"__proto__":1}').__proto__, 1) + }) + it('parses multiple properties', () => { assert.deepStrictEqual(JSON5.parse('{abc:1,def:2}'), {abc: 1, def: 2}) })