Skip to content

Commit 5a056c3

Browse files
authored
Merge pull request Automattic#15183 from Automattic/vkarpov15/deno-upgrade
chore: use Deno 2.1 in tests
2 parents 67a30e7 + 556ea45 commit 5a056c3

File tree

10 files changed

+77
-30
lines changed

10 files changed

+77
-30
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
- name: Setup Deno
109109
uses: denoland/setup-deno@v2
110110
with:
111-
deno-version: v1.37.x
111+
deno-version: v2.1.x
112112
- run: deno --version
113113
- run: npm install
114114
- name: Run Deno tests

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
8.9.5 / 2025-01-13
2+
==================
3+
* fix: disallow nested $where in populate match
4+
* fix(schema): handle bitwise operators on Int32 #15176 #15170
5+
6+
7.8.4 / 2025-01-13
7+
===================
8+
* fix: disallow nested $where in populate match
9+
10+
6.13.6 / 2025-01-13
11+
===================
12+
* fix: disallow nested $where in populate match
13+
114
8.9.4 / 2025-01-09
215
==================
316
* fix(document): fix document not applying manual populate when using a function in schema.options.ref #15138 [IchirokuXVI](https://github.com/IchirokuXVI)

lib/helpers/populate/getModelsMapForPopulate.js

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
191191
if (hasMatchFunction) {
192192
match = match.call(doc, doc);
193193
}
194-
if (Array.isArray(match)) {
195-
for (const item of match) {
196-
if (item != null && item.$where) {
197-
throw new MongooseError('Cannot use $where filter with populate() match');
198-
}
199-
}
200-
} else if (match != null && match.$where != null) {
201-
throw new MongooseError('Cannot use $where filter with populate() match');
202-
}
194+
throwOn$where(match);
203195
data.match = match;
204196
data.hasMatchFunction = hasMatchFunction;
205197
data.isRefPath = isRefPath;
@@ -463,15 +455,7 @@ function _virtualPopulate(model, docs, options, _virtualRes) {
463455
data.match = match;
464456
data.hasMatchFunction = hasMatchFunction;
465457

466-
if (Array.isArray(match)) {
467-
for (const item of match) {
468-
if (item != null && item.$where) {
469-
throw new MongooseError('Cannot use $where filter with populate() match');
470-
}
471-
}
472-
} else if (match != null && match.$where != null) {
473-
throw new MongooseError('Cannot use $where filter with populate() match');
474-
}
458+
throwOn$where(match);
475459

476460
// Get local fields
477461
const ret = _getLocalFieldValues(doc, localField, model, options, virtual);
@@ -759,3 +743,24 @@ function _findRefPathForDiscriminators(doc, modelSchema, data, options, normaliz
759743

760744
return modelNames;
761745
}
746+
747+
/**
748+
* Throw an error if there are any $where keys
749+
*/
750+
751+
function throwOn$where(match) {
752+
if (match == null) {
753+
return;
754+
}
755+
if (typeof match !== 'object') {
756+
return;
757+
}
758+
for (const key of Object.keys(match)) {
759+
if (key === '$where') {
760+
throw new MongooseError('Cannot use $where filter with populate() match');
761+
}
762+
if (match[key] != null && typeof match[key] === 'object') {
763+
throwOn$where(match[key]);
764+
}
765+
}
766+
}

lib/schema/bigint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ SchemaBigInt.prototype.castForQuery = function($conditional, val, context) {
209209
return handler.call(this, val);
210210
}
211211

212-
return this.applySetters(null, val, context);
212+
return this.applySetters(val, context);
213213
}
214214

215215
try {

lib/schema/boolean.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ SchemaBoolean.prototype.castForQuery = function($conditional, val, context) {
253253
return handler.call(this, val);
254254
}
255255

256-
return this.applySetters(null, val, context);
256+
return this.applySetters(val, context);
257257
}
258258

259259
try {

lib/schema/int32.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
const CastError = require('../error/cast');
88
const SchemaType = require('../schemaType');
99
const castInt32 = require('../cast/int32');
10+
const handleBitwiseOperator = require('./operators/bitwise');
1011

1112
/**
1213
* Int32 SchemaType constructor.
@@ -200,7 +201,11 @@ SchemaInt32.$conditionalHandlers = {
200201
$gt: handleSingle,
201202
$gte: handleSingle,
202203
$lt: handleSingle,
203-
$lte: handleSingle
204+
$lte: handleSingle,
205+
$bitsAllClear: handleBitwiseOperator,
206+
$bitsAnyClear: handleBitwiseOperator,
207+
$bitsAllSet: handleBitwiseOperator,
208+
$bitsAnySet: handleBitwiseOperator
204209
};
205210

206211
/*!
@@ -228,7 +233,7 @@ SchemaInt32.prototype.castForQuery = function($conditional, val, context) {
228233
return handler.call(this, val);
229234
}
230235

231-
return this.applySetters(null, val, context);
236+
return this.applySetters(val, context);
232237
}
233238

234239
try {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "mongoose",
33
"description": "Mongoose MongoDB ODM",
4-
"version": "8.9.4",
4+
"version": "8.9.5",
55
"author": "Guillermo Rauch <[email protected]>",
66
"keywords": [
77
"mongodb",
@@ -17,6 +17,7 @@
1717
"orm",
1818
"db"
1919
],
20+
"type": "commonjs",
2021
"license": "MIT",
2122
"dependencies": {
2223
"bson": "^6.10.1",

test/cast.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ describe('cast: ', function() {
123123
{ x: { $bitsAnyClear: Buffer.from([3]) } });
124124
});
125125

126+
it('with int32 (gh-15170)', function() {
127+
const schema = new Schema({ x: 'Int32' });
128+
assert.deepEqual(cast(schema, { x: { $bitsAnySet: 3 } }),
129+
{ x: { $bitsAnySet: 3 } });
130+
});
131+
126132
it('throws when invalid', function() {
127133
const schema = new Schema({ x: Number });
128134
assert.throws(function() {
@@ -250,4 +256,10 @@ describe('cast: ', function() {
250256
'state.fieldFoo': '44'
251257
});
252258
});
259+
260+
it('treats unknown operators as passthrough (gh-15170)', function() {
261+
const schema = new Schema({ x: Boolean });
262+
assert.deepEqual(cast(schema, { x: { $someConditional: 'true' } }),
263+
{ x: { $someConditional: true } });
264+
});
253265
});

test/deno.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ const fixtures = require('./mocha-fixtures.js')
1616
await fixtures.mochaGlobalSetup();
1717

1818
const child_args = [
19-
// args is required to be set manually, because there is currently no way to get all arguments from deno
20-
'--allow-env', '--allow-read', '--allow-net', '--allow-run', '--allow-sys', '--allow-write',
2119
...Deno.args,
2220
resolve(fileURLToPath(import.meta.url), '../deno_mocha.js')
2321
];

test/model.populate.test.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3670,21 +3670,34 @@ describe('model: populate:', function() {
36703670
const parent = await Parent.create({ name: 'Anakin', child: child._id });
36713671

36723672
await assert.rejects(
3673-
() => Parent.findOne().populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3673+
() => Parent.findOne().populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
36743674
/Cannot use \$where filter with populate\(\) match/
36753675
);
36763676
await assert.rejects(
3677-
() => Parent.find().populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3677+
() => Parent.find().populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
36783678
/Cannot use \$where filter with populate\(\) match/
36793679
);
36803680
await assert.rejects(
3681-
() => parent.populate({ path: 'child', match: { $where: 'console.log("oops!");' } }),
3681+
() => parent.populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
36823682
/Cannot use \$where filter with populate\(\) match/
36833683
);
36843684
await assert.rejects(
3685-
() => Child.find().populate({ path: 'parent', match: { $where: 'console.log("oops!");' } }),
3685+
() => Child.find().populate({ path: 'parent', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
36863686
/Cannot use \$where filter with populate\(\) match/
36873687
);
3688+
await assert.rejects(
3689+
() => Child.find().populate({ path: 'parent', match: () => ({ $or: [{ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }] }) }),
3690+
/Cannot use \$where filter with populate\(\) match/
3691+
);
3692+
await assert.rejects(
3693+
() => Child.find().populate({ path: 'parent', match: () => ({ $and: [{ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }] }) }),
3694+
/Cannot use \$where filter with populate\(\) match/
3695+
);
3696+
3697+
class MyClass {}
3698+
MyClass.prototype.$where = 'typeof console !== "undefined" ? doesNotExist("foo") : true;';
3699+
// OK because sift only looks through own properties
3700+
await Child.find().populate({ path: 'parent', match: () => new MyClass() });
36883701
});
36893702

36903703
it('multiple source docs', async function() {

0 commit comments

Comments
 (0)