Skip to content

Commit

Permalink
fix: mongoose schema default should not mutate original object
Browse files Browse the repository at this point in the history
  • Loading branch information
lpizzinidev committed Jul 16, 2022
1 parent 86f66b0 commit 49aa88d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
6 changes: 4 additions & 2 deletions lib/document.js
Expand Up @@ -1149,8 +1149,10 @@ 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 }));
// Create a copy of the object to avoid editing the original
const pathKey = { ...path[key] }
$applyDefaultsToNested(pathKey, prefix + key, this);
this.$set(prefix + key, pathKey, constructing, Object.assign({}, options, { _skipMarkModified: true }));
continue;
} else if (strict) {
// Don't overwrite defaults with undefined keys (gh-3981) (gh-9039)
Expand Down
25 changes: 25 additions & 0 deletions test/document.test.js
Expand Up @@ -2332,6 +2332,31 @@ describe('document', function() {
assert.equal(res.test, 'test');
assert.ok(!res.subDoc);
});

it('original object nested fields should not be mutated by mongoose schema defaults (gh-12102)', function() {
const schema = new mongoose.Schema({
topLevelField1: {
nestedField1: String,
nestedField2: {type: String, default: 'defValue'}
},
topLevelField2: {type: String, default: 'defValue'}
})

const Model = db.model('Test', schema);

const originalData = {
topLevelField1: {
nestedField1: 'provided'
}
}

const model = new Model(originalData);
assert.deepEqual(originalData, {
topLevelField1: {
nestedField1: 'provided'
}
})
});
});

describe('error processing (gh-2284)', async function() {
Expand Down

0 comments on commit 49aa88d

Please sign in to comment.