From 98eb9e22353e300824b7aed777b554eddb2676ce Mon Sep 17 00:00:00 2001 From: Kaitlin Mahar Date: Thu, 28 Sep 2017 15:13:57 -0400 Subject: [PATCH] fix(dbref): only upgrade objects with allowed $keys to DBRefs --- lib/bson/parser/deserializer.js | 22 ++++++++++++++++++---- test/node/bson_test.js | 8 ++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/bson/parser/deserializer.js b/lib/bson/parser/deserializer.js index 0629bc5a..c9d864b8 100644 --- a/lib/bson/parser/deserializer.js +++ b/lib/bson/parser/deserializer.js @@ -404,6 +404,7 @@ var deserializeObject = function(buffer, index, options, isArray) { (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); + object[name] = new Timestamp(lowBits, highBits); } else if (elementType === BSON.BSON_DATA_MIN_KEY) { object[name] = new MinKey(); @@ -570,10 +571,23 @@ var deserializeObject = function(buffer, index, options, isArray) { throw new Error('corrupt object bson'); } - // Check if we have a db ref object - // this breaks one of the spec tests. should only become a dbref if it's explicitly - // wrapped, like a {dbref: {$ref: ...}} - // if (object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); + // check if object's $ keys are those of a DBRef + var dollarKeys = Object.keys(object).filter(k => k.startsWith('$')); + var valid = true; + dollarKeys.forEach(k => { + if (['$ref', '$id', '$db'].indexOf(k) === -1) valid = false; + }); + + // if a $key not in "$ref", "$id", "$db", don't make a DBRef + if (!valid) return object; + + if (object['$id'] != null && object['$ref'] != null) { + let copy = Object.assign({}, object); + delete copy.$ref; + delete copy.$id; + delete copy.$db; + return new DBRef(object.$ref, object.$id, object.$db || null, copy); + } return object; }; diff --git a/test/node/bson_test.js b/test/node/bson_test.js index aece4dac..6188b0cc 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -1111,8 +1111,8 @@ describe('BSON', function() { expect(serialized_data).to.deep.equal(serialized_data2); var doc2 = b.deserialize(serialized_data); - expect('namespace').to.equal(doc2.dbref.$ref); - expect(doc2.dbref.$id.toHexString()).to.deep.equal(oid.toHexString()); + expect(doc).to.deep.equal(doc2); + expect(doc2.dbref.oid.toHexString()).to.deep.equal(oid.toHexString()); done(); }); @@ -1131,8 +1131,8 @@ describe('BSON', function() { var doc2 = b.deserialize(serialized_data); expect('something').to.equal(doc2.name); - expect('username').to.equal(doc2.user.$ref); - expect(id.toString()).to.equal(doc2.user.$id.toString()); + expect('username').to.equal(doc2.user.collection); + expect(id.toString()).to.equal(doc2.user.oid.toString()); done(); });