From 6286438bbce7695e5c489af3b299ae0ce009e144 Mon Sep 17 00:00:00 2001 From: Jordan Tucker Date: Thu, 15 Dec 2022 21:16:27 -0600 Subject: [PATCH] fix: add __proto__ to objects and arrays --- CHANGELOG.md | 4 ++++ lib/parse.js | 41 ++++++++++++++++++++++++++++++++++------- test/parse.js | 7 +++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a20fa52c..7ab8a954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ [c-unreleased]: https://github.com/json5/json5/tree/main [d-unreleased]: https://github.com/json5/json5/compare/v2.2.1...HEAD +- Fix: Properties with the name `__proto__` are added to objects and arrays. + ([#199]) + ### v2.2.1 [[code][c2.2.1], [diff][d2.2.1]] [c2.2.1]: https://github.com/json5/json5/tree/v2.2.1 @@ -360,6 +363,7 @@ parser for the regular JSON format. [#182]: https://github.com/json5/json5/issues/182 [#187]: https://github.com/json5/json5/issues/187 [#196]: https://github.com/json5/json5/issues/196 +[#199]: https://github.com/json5/json5/issues/199 [#208]: https://github.com/json5/json5/issues/208 [#210]: https://github.com/json5/json5/issues/210 [#222]: https://github.com/json5/json5/issues/222 diff --git a/lib/parse.js b/lib/parse.js index c01646fc..da2078a6 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -42,12 +42,34 @@ module.exports = 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 570e72bf..e305767e 100644 --- a/test/parse.js +++ b/test/parse.js @@ -48,6 +48,13 @@ t.test('parse(text)', t => { 'parses escaped property names' ) + t.strictSame( + // eslint-disable-next-line no-proto + JSON5.parse('{"__proto__":1}').__proto__, + 1, + 'preserves __proto__ property names' + ) + t.strictSame( JSON5.parse('{abc:1,def:2}'), {abc: 1, def: 2},