Skip to content

Commit a813dd2

Browse files
authored
Merge pull request #5821 from Faibk/master
Fixed call stack overflow when using recursive embedded discriminators
2 parents a0ee8d8 + 76da92e commit a813dd2

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

lib/services/model/applyHooks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ function applyHooks(model, schema) {
2828
if (childModel.$appliedHooks) {
2929
continue;
3030
}
31+
applyHooks(childModel, schema.childSchemas[i].schema);
3132
if (childModel.discriminators != null) {
3233
keys = Object.keys(childModel.discriminators);
3334
for (j = 0; j < keys.length; ++j) {
3435
applyHooks(childModel.discriminators[keys[j]],
3536
childModel.discriminators[keys[j]].schema);
3637
}
3738
}
38-
applyHooks(childModel, schema.childSchemas[i].schema);
3939
}
4040

4141
if (!q.length) {

test/docs/discriminators.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,56 @@ describe('discriminator docs', function () {
352352
}).
353353
catch(done);
354354
});
355+
356+
/**
357+
* Recursive embedded discriminators
358+
*/
359+
it('Recursive embedded discriminators in arrays', function(done) {
360+
var singleEventSchema = new Schema({ message: String },
361+
{ discriminatorKey: 'kind', _id: false });
362+
363+
var eventListSchema = new Schema({ events: [singleEventSchema] });
364+
365+
var subEventSchema = new Schema({
366+
sub_events: [singleEventSchema]
367+
}, { _id: false });
368+
369+
var SubEvent = subEventSchema.path('sub_events').discriminator('SubEvent', subEventSchema)
370+
eventListSchema.path('events').discriminator('SubEvent', subEventSchema);
371+
372+
var Eventlist = db.model('EventList', eventListSchema);
373+
374+
// Create a new batch of events with different kinds
375+
var list = {
376+
events: [
377+
{ kind: 'SubEvent', sub_events: [{kind:'SubEvent', sub_events:[], message:'test1'}], message: 'hello' },
378+
{ kind: 'SubEvent', sub_events: [{kind:'SubEvent', sub_events:[{kind:'SubEvent', sub_events:[], message:'test3'}], message:'test2'}], message: 'world' }
379+
]
380+
};
381+
382+
Eventlist.create(list).
383+
then(function(doc) {
384+
assert.equal(doc.events.length, 2);
385+
386+
assert.equal(doc.events[0].sub_events[0].message, 'test1');
387+
assert.equal(doc.events[0].message, 'hello');
388+
assert.ok(doc.events[0].sub_events[0] instanceof SubEvent);
389+
390+
assert.equal(doc.events[1].sub_events[0].sub_events[0].message, 'test3');
391+
assert.equal(doc.events[1].message, 'world');
392+
assert.ok(doc.events[1].sub_events[0].sub_events[0] instanceof SubEvent);
393+
394+
doc.events.push({kind:'SubEvent', sub_events:[{kind:'SubEvent', sub_events:[], message:'test4'}], message:'pushed'});
395+
return doc.save();
396+
}).
397+
then(function(doc) {
398+
assert.equal(doc.events.length, 3);
399+
400+
assert.equal(doc.events[2].message, 'pushed');
401+
assert.ok(doc.events[2].sub_events[0] instanceof SubEvent);
402+
403+
done();
404+
}).
405+
catch(done);
406+
});
355407
});

0 commit comments

Comments
 (0)