Skip to content

Commit 768d460

Browse files
committed
Merge branch 'vkarpov15/sift-where'
2 parents b76ca9d + c9e86bf commit 768d460

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

lib/helpers/populate/assignVals.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ function numDocs(v) {
249249

250250
function valueFilter(val, assignmentOpts, populateOptions, allIds) {
251251
const userSpecifiedTransform = typeof populateOptions.transform === 'function';
252-
const transform = userSpecifiedTransform ? populateOptions.transform : noop;
252+
const transform = userSpecifiedTransform ? populateOptions.transform : v => v;
253253
if (Array.isArray(val)) {
254254
// find logic
255255
const ret = [];
@@ -341,7 +341,3 @@ function isPopulatedObject(obj) {
341341
obj.$__ != null ||
342342
leanPopulateMap.has(obj);
343343
}
344-
345-
function noop(v) {
346-
return v;
347-
}

lib/helpers/populate/getModelsMapForPopulate.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,15 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
184184
if (hasMatchFunction) {
185185
match = match.call(doc, doc);
186186
}
187+
if (Array.isArray(match)) {
188+
for (const item of match) {
189+
if (item != null && item.$where) {
190+
throw new MongooseError('Cannot use $where filter with populate() match');
191+
}
192+
}
193+
} else if (match != null && match.$where != null) {
194+
throw new MongooseError('Cannot use $where filter with populate() match');
195+
}
187196
data.match = match;
188197
data.hasMatchFunction = hasMatchFunction;
189198
data.isRefPath = isRefPath;
@@ -447,6 +456,16 @@ function _virtualPopulate(model, docs, options, _virtualRes) {
447456
data.match = match;
448457
data.hasMatchFunction = hasMatchFunction;
449458

459+
if (Array.isArray(match)) {
460+
for (const item of match) {
461+
if (item != null && item.$where) {
462+
throw new MongooseError('Cannot use $where filter with populate() match');
463+
}
464+
}
465+
} else if (match != null && match.$where != null) {
466+
throw new MongooseError('Cannot use $where filter with populate() match');
467+
}
468+
450469
// Get local fields
451470
const ret = _getLocalFieldValues(doc, localField, model, options, virtual);
452471

test/model.populate.test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,6 +3641,52 @@ describe('model: populate:', function() {
36413641
assert.deepEqual(band.members.map(b => b.name).sort(), ['AA', 'AB']);
36423642
});
36433643

3644+
it('match prevents using $where', async function() {
3645+
const ParentSchema = new Schema({
3646+
name: String,
3647+
child: {
3648+
type: mongoose.Schema.Types.ObjectId,
3649+
ref: 'Child'
3650+
},
3651+
children: [{
3652+
type: mongoose.Schema.Types.ObjectId,
3653+
ref: 'Child'
3654+
}]
3655+
});
3656+
3657+
const ChildSchema = new Schema({
3658+
name: String
3659+
});
3660+
ChildSchema.virtual('parent', {
3661+
ref: 'Parent',
3662+
localField: '_id',
3663+
foreignField: 'parent'
3664+
});
3665+
3666+
const Parent = db.model('Parent', ParentSchema);
3667+
const Child = db.model('Child', ChildSchema);
3668+
3669+
const child = await Child.create({ name: 'Luke' });
3670+
const parent = await Parent.create({ name: 'Anakin', child: child._id });
3671+
3672+
await assert.rejects(
3673+
() => Parent.findOne().populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3674+
/Cannot use \$where filter with populate\(\) match/
3675+
);
3676+
await assert.rejects(
3677+
() => Parent.find().populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3678+
/Cannot use \$where filter with populate\(\) match/
3679+
);
3680+
await assert.rejects(
3681+
() => parent.populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3682+
/Cannot use \$where filter with populate\(\) match/
3683+
);
3684+
await assert.rejects(
3685+
() => Child.find().populate({ path: 'parent', match: { $where: 'console.log("oops!");' } }),
3686+
/Cannot use \$where filter with populate\(\) match/
3687+
);
3688+
});
3689+
36443690
it('multiple source docs', async function() {
36453691
const PersonSchema = new Schema({
36463692
name: String,

0 commit comments

Comments
 (0)