Skip to content

Commit 4bda57d

Browse files
authored
fix(NODE-4381): handle __proto__ well in EJSON (#506)
1 parent a2a81bc commit 4bda57d

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/extended_json.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,17 @@ function serializeDocument(doc: any, options: EJSONSerializeOptions) {
285285
for (const name in doc) {
286286
options.seenObjects.push({ propertyName: name, obj: null });
287287
try {
288-
_doc[name] = serializeValue(doc[name], options);
288+
const value = serializeValue(doc[name], options);
289+
if (name === '__proto__') {
290+
Object.defineProperty(_doc, name, {
291+
value,
292+
writable: true,
293+
enumerable: true,
294+
configurable: true
295+
});
296+
} else {
297+
_doc[name] = value;
298+
}
289299
} finally {
290300
options.seenObjects.pop();
291301
}

test/node/bson_test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,12 @@ describe('BSON', function () {
17761776
assertBuffersEqual(done, serialized_data, serialized_data2, 0);
17771777

17781778
var doc1 = BSON.deserialize(serialized_data);
1779-
expect(Object.getOwnPropertyDescriptor(doc1, '__proto__').enumerable).to.equal(true);
1779+
expect(doc1).to.have.deep.ownPropertyDescriptor('__proto__', {
1780+
configurable: true,
1781+
enumerable: true,
1782+
writable: true,
1783+
value: { a: 42 }
1784+
});
17801785
expect(doc1.__proto__.a).to.equal(42);
17811786
done();
17821787
});

test/node/extended_json_tests.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,20 @@ describe('Extended JSON', function () {
509509
// expect(() => EJSON.serialize(badMap)).to.throw(); // uncomment when EJSON supports ES6 Map
510510
});
511511

512+
it('should correctly deserialize objects containing __proto__ keys', function () {
513+
const original = { ['__proto__']: { a: 42 } };
514+
const serialized = EJSON.stringify(original);
515+
expect(serialized).to.equal('{"__proto__":{"a":42}}');
516+
const deserialized = EJSON.parse(serialized);
517+
expect(deserialized).to.have.deep.ownPropertyDescriptor('__proto__', {
518+
configurable: true,
519+
enumerable: true,
520+
writable: true,
521+
value: { a: 42 }
522+
});
523+
expect(deserialized.__proto__.a).to.equal(42);
524+
});
525+
512526
context('circular references', () => {
513527
it('should throw a helpful error message for input with circular references', function () {
514528
const obj = {

0 commit comments

Comments
 (0)