Skip to content

Commit

Permalink
Merge pull request #15230 from Automattic/vkarpov15/gh-15200
Browse files Browse the repository at this point in the history
fix(bigint): throw error when casting BigInt that's outside of the bounds of what MongoDB can safely store
  • Loading branch information
vkarpov15 authored Feb 6, 2025
2 parents 3501adf + 0c83096 commit 02091cb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
16 changes: 13 additions & 3 deletions lib/cast/bigint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';

const assert = require('assert');
const { Long } = require('bson');

/**
Expand All @@ -13,6 +12,10 @@ const { Long } = require('bson');
* @api private
*/

const MAX_BIGINT = 9223372036854775807n;
const MIN_BIGINT = -9223372036854775808n;
const ERROR_MESSAGE = `Mongoose only supports BigInts between ${MIN_BIGINT} and ${MAX_BIGINT} because MongoDB does not support arbitrary precision integers`;

module.exports = function castBigInt(val) {
if (val == null) {
return val;
Expand All @@ -21,6 +24,9 @@ module.exports = function castBigInt(val) {
return null;
}
if (typeof val === 'bigint') {
if (val > MAX_BIGINT || val < MIN_BIGINT) {
throw new Error(ERROR_MESSAGE);
}
return val;
}

Expand All @@ -29,8 +35,12 @@ module.exports = function castBigInt(val) {
}

if (typeof val === 'string' || typeof val === 'number') {
return BigInt(val);
val = BigInt(val);
if (val > MAX_BIGINT || val < MIN_BIGINT) {
throw new Error(ERROR_MESSAGE);
}
return val;
}

assert.ok(false);
throw new Error(`Cannot convert value to BigInt: "${val}"`);
};
10 changes: 5 additions & 5 deletions test/bigint.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,22 @@ describe('BigInt', function() {
});

it('is stored as a long in MongoDB', async function() {
await Test.create({ myBigInt: 42n });
await Test.create({ myBigInt: 9223372036854775807n });

const doc = await Test.findOne({ myBigInt: { $type: 'long' } });
assert.ok(doc);
assert.strictEqual(doc.myBigInt, 42n);
assert.strictEqual(doc.myBigInt, 9223372036854775807n);
});

it('becomes a bigint with lean using useBigInt64', async function() {
await Test.create({ myBigInt: 7n });
await Test.create({ myBigInt: 9223372036854775807n });

const doc = await Test.
findOne({ myBigInt: 7n }).
findOne({ myBigInt: 9223372036854775807n }).
setOptions({ useBigInt64: true }).
lean();
assert.ok(doc);
assert.strictEqual(doc.myBigInt, 7n);
assert.strictEqual(doc.myBigInt, 9223372036854775807n);
});

it('can query with comparison operators', async function() {
Expand Down

0 comments on commit 02091cb

Please sign in to comment.