diff --git a/src/extended_json.ts b/src/extended_json.ts index b7bb1b03..90269623 100644 --- a/src/extended_json.ts +++ b/src/extended_json.ts @@ -285,7 +285,17 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) { for (const name in doc) { options.seenObjects.push({ propertyName: name, obj: null }); try { - _doc[name] = serializeValue(doc[name], options); + const value = serializeValue(doc[name], options); + if (name === '__proto__') { + Object.defineProperty(_doc, name, { + value, + writable: true, + enumerable: true, + configurable: true + }); + } else { + _doc[name] = value; + } } finally { options.seenObjects.pop(); } diff --git a/test/node/bson_test.js b/test/node/bson_test.js index 484d9c07..ac178000 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -1776,7 +1776,12 @@ describe('BSON', function () { assertBuffersEqual(done, serialized_data, serialized_data2, 0); var doc1 = BSON.deserialize(serialized_data); - expect(Object.getOwnPropertyDescriptor(doc1, '__proto__').enumerable).to.equal(true); + expect(doc1).to.have.deep.ownPropertyDescriptor('__proto__', { + configurable: true, + enumerable: true, + writable: true, + value: { a: 42 } + }); expect(doc1.__proto__.a).to.equal(42); done(); }); diff --git a/test/node/extended_json_tests.js b/test/node/extended_json_tests.js index f3e6cea8..e8f97457 100644 --- a/test/node/extended_json_tests.js +++ b/test/node/extended_json_tests.js @@ -509,6 +509,20 @@ describe('Extended JSON', function () { // expect(() => EJSON.serialize(badMap)).to.throw(); // uncomment when EJSON supports ES6 Map }); + it('should correctly deserialize objects containing __proto__ keys', function () { + const original = { ['__proto__']: { a: 42 } }; + const serialized = EJSON.stringify(original); + expect(serialized).to.equal('{"__proto__":{"a":42}}'); + const deserialized = EJSON.parse(serialized); + expect(deserialized).to.have.deep.ownPropertyDescriptor('__proto__', { + configurable: true, + enumerable: true, + writable: true, + value: { a: 42 } + }); + expect(deserialized.__proto__.a).to.equal(42); + }); + context('circular references', () => { it('should throw a helpful error message for input with circular references', function () { const obj = {