From 2262a7709fe72ea255d23e1aea4ac84e9627e523 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 19 Jul 2022 20:16:53 -0400 Subject: [PATCH] fix(document): avoid mutating original object passed to $set() when applying defaults to nested properties Fix #12102 --- lib/document.js | 2 +- test/document.test.js | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/document.js b/lib/document.js index 72c12c75442..e6f73aeb774 100644 --- a/lib/document.js +++ b/lib/document.js @@ -1149,8 +1149,8 @@ Document.prototype.$set = function $set(path, val, type, options) { } if (utils.isNonBuiltinObject(valForKey) && pathtype === 'nested') { - $applyDefaultsToNested(path[key], prefix + key, this); this.$set(prefix + key, path[key], constructing, Object.assign({}, options, { _skipMarkModified: true })); + $applyDefaultsToNested(this.$get(prefix + key), prefix + key, this); continue; } else if (strict) { // Don't overwrite defaults with undefined keys (gh-3981) (gh-9039) diff --git a/test/document.test.js b/test/document.test.js index 160b14fbe3d..359a0ee050d 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -8831,7 +8831,7 @@ describe('document', function() { assert.ok(!user.updatedAt); }); - it('Sets default when passing undefined as value for a key in a nested subdoc (gh-9039)', async function() { + it('Sets default when passing undefined as value for a key in a nested subdoc (gh-12102) (gh-9039)', async function() { const Test = db.model('Test', { nested: { prop: { @@ -8841,9 +8841,11 @@ describe('document', function() { } }); - - const doc = await Test.create({ nested: { prop: undefined } }); + const obj = { nested: { prop: undefined } }; + const doc = await Test.create(obj); assert.equal(doc.nested.prop, 'some default value'); + + assert.deepStrictEqual(obj, { nested: { prop: undefined } }); }); it('allows accessing $locals when initializing (gh-9098)', function() {