Skip to content

Commit 375f368

Browse files
authored
fix: Throw error on bigint usage and add helpers to Long (#426)
Adds helpers toBigInt and fromBigInt to the Long class to help support 64bit values. Throws an error when bigint is attempted to be serialized. NODE-2378
1 parent 290dd6a commit 375f368

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

lib/bson/long.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ Long.prototype.toNumber = function() {
7777
return this.high_ * Long.TWO_PWR_32_DBL_ + this.getLowBitsUnsigned();
7878
};
7979

80+
/** Converts the Long to a BigInt (arbitrary precision). */
81+
Long.prototype.toBigInt = function () {
82+
return BigInt(this.toString());
83+
}
84+
8085
/**
8186
* Return the JSON value.
8287
*
@@ -711,6 +716,15 @@ Long.fromNumber = function(value) {
711716
}
712717
};
713718

719+
/**
720+
* Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
721+
* @param {bigint} value - The number in question
722+
* @returns {Long} The corresponding Long value
723+
*/
724+
Long.fromBigInt = function(value) {
725+
return Long.fromString(value.toString(10), 10);
726+
}
727+
714728
/**
715729
* Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits.
716730
*

lib/bson/parser/serializer.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ var serializeInto = function serializeInto(
709709
index = serializeString(buffer, key, value, index, true);
710710
} else if (type === 'number') {
711711
index = serializeNumber(buffer, key, value, index, true);
712+
} else if(type === 'bigint') {
713+
throw new TypeError('Unsupported type BigInt, please use Decimal128');
712714
} else if (type === 'boolean') {
713715
index = serializeBoolean(buffer, key, value, index, true);
714716
} else if (value instanceof Date || isDate(value)) {
@@ -820,6 +822,8 @@ var serializeInto = function serializeInto(
820822
index = serializeString(buffer, key, value, index);
821823
} else if (type === 'number') {
822824
index = serializeNumber(buffer, key, value, index);
825+
} else if(type === 'bigint') {
826+
throw new TypeError('Unsupported type BigInt, please use Decimal128');
823827
} else if (type === 'boolean') {
824828
index = serializeBoolean(buffer, key, value, index);
825829
} else if (value instanceof Date || isDate(value)) {
@@ -923,6 +927,8 @@ var serializeInto = function serializeInto(
923927
index = serializeString(buffer, key, value, index);
924928
} else if (type === 'number') {
925929
index = serializeNumber(buffer, key, value, index);
930+
} else if(type === 'bigint') {
931+
throw new TypeError('Unsupported type BigInt, please use Decimal128');
926932
} else if (type === 'boolean') {
927933
index = serializeBoolean(buffer, key, value, index);
928934
} else if (value instanceof Date || isDate(value)) {

test/node/bigint_test.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/* globals BigInt */
2+
'use strict';
3+
4+
var createBSON = require('../utils');
5+
var BSON = require('../..');
6+
var bson = createBSON();
7+
8+
try {
9+
BigInt(0);
10+
11+
// will throw on the line above if BigInt is not supported in the runtime
12+
13+
exports['Should error on serialize bigint'] = function (test) {
14+
var testDoc = { b: BigInt(32) };
15+
try {
16+
bson.serialize(testDoc)
17+
test.ok(false);
18+
} catch (error) {
19+
test.ok(error instanceof TypeError);
20+
test.ok(error.message === 'Unsupported type BigInt, please use Decimal128');
21+
}
22+
test.done();
23+
};
24+
25+
exports['Should error on serialize bigint inside array'] = function (test) {
26+
var testDoc = { b: [0, 1, BigInt(0x1ffffffff)] };
27+
try {
28+
bson.serialize(testDoc)
29+
test.ok(false);
30+
} catch (error) {
31+
test.ok(error instanceof TypeError);
32+
test.ok(error.message === 'Unsupported type BigInt, please use Decimal128');
33+
}
34+
test.done();
35+
};
36+
37+
exports['Should error on serialize bigint inside subdocument'] = function (test) {
38+
var testDoc = { b: { a: BigInt(0x1ffffffff) } };
39+
try {
40+
bson.serialize(testDoc)
41+
test.ok(false);
42+
} catch (error) {
43+
test.ok(error instanceof TypeError);
44+
test.ok(error.message === 'Unsupported type BigInt, please use Decimal128');
45+
}
46+
test.done();
47+
};
48+
49+
exports['Should support conversion on Long type'] = function (test) {
50+
var long = BSON.Long.fromBigInt(BigInt(200));
51+
test.ok(long._bsontype === 'Long');
52+
test.ok(long.toNumber() === 200);
53+
test.ok(long.toBigInt() === BigInt(200));
54+
test.done();
55+
}
56+
57+
} catch (_) {
58+
// 'JS VM does not support BigInt'
59+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy