Skip to content

Commit 9526e66

Browse files
committed
fix(discriminator): shallow clone Schema.prototype.obj before merging schemas to avoid modifying original obj
Fix #14827
1 parent 16df3da commit 9526e66

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

lib/helpers/model/discriminator.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
115115
}
116116
}
117117

118+
// Shallow clone `obj` so we can add additional properties without modifying original
119+
// schema. `Schema.prototype.clone()` copies `obj` by reference, no cloning.
120+
schema.obj = { ...schema.obj };
118121
mergeDiscriminatorSchema(schema, baseSchema);
119122

120123
// Clean up conflicting paths _after_ merging re: gh-6076

test/model.discriminator.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,23 @@ describe('model', function() {
620620
Person.discriminator('Parent2', parentSchema.clone());
621621
});
622622

623+
it('clone() does not modify original schema `obj` (gh-14821)', function() {
624+
const personSchema = new Schema({
625+
name: String
626+
}, { discriminatorKey: 'kind' });
627+
628+
const parentSchema = new Schema({
629+
child: String
630+
});
631+
632+
const Person = db.model('Person', personSchema);
633+
const Parent = Person.discriminator('Parent', parentSchema.clone());
634+
635+
assert.ok(!Person.schema.obj.child);
636+
assert.ok(!personSchema.obj.child);
637+
assert.ok(Parent.schema.obj.child);
638+
});
639+
623640
it('clone() allows reusing with different models (gh-5721)', async function() {
624641
const schema = new mongoose.Schema({
625642
name: String

0 commit comments

Comments
 (0)