diff --git a/package.json b/package.json index 3cec7832..dc7ac3c5 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "build:bundle": "rollup -c rollup.config.mjs", "build": "npm run build:dts && npm run build:bundle", "check:lint": "ESLINT_USE_FLAT_CONFIG=false eslint -v && ESLINT_USE_FLAT_CONFIG=false eslint --ext '.js,.ts' --max-warnings=0 src test && npm run build:dts && npm run check:tsd", - "format": "eslint --ext '.js,.ts' src test --fix", + "format": "ESLINT_USE_FLAT_CONFIG=false eslint --ext '.js,.ts' src test --fix", "check:coverage": "nyc --check-coverage npm run check:node", "prepare": "node etc/prepare.js", "release": "standard-version -i HISTORY.md" diff --git a/src/utils/number_utils.ts b/src/utils/number_utils.ts index 02f4dbeb..5970a963 100644 --- a/src/utils/number_utils.ts +++ b/src/utils/number_utils.ts @@ -83,14 +83,23 @@ export const NumberUtils: NumberUtils = { /** Reads a little-endian 64-bit integer from source */ getBigInt64LE(source: Uint8Array, offset: number): bigint { - const lo = NumberUtils.getUint32LE(source, offset); - const hi = NumberUtils.getUint32LE(source, offset + 4); - - /* - eslint-disable-next-line no-restricted-globals - -- This is allowed since this helper should not be called unless bigint features are enabled - */ - return (BigInt(hi) << BigInt(32)) + BigInt(lo); + // eslint-disable-next-line no-restricted-globals + const hi = BigInt( + source[offset + 4] + + source[offset + 5] * 256 + + source[offset + 6] * 65536 + + (source[offset + 7] << 24) + ); // Overflow + + // eslint-disable-next-line no-restricted-globals + const lo = BigInt( + source[offset] + + source[offset + 1] * 256 + + source[offset + 2] * 65536 + + source[offset + 3] * 16777216 + ); + // eslint-disable-next-line no-restricted-globals + return (hi << BigInt(32)) + lo; }, /** Reads a little-endian 64-bit float from source */ diff --git a/test/node/bigint.test.ts b/test/node/bigint.test.ts index 9532859f..3ffca593 100644 --- a/test/node/bigint.test.ts +++ b/test/node/bigint.test.ts @@ -105,6 +105,46 @@ describe('BSON BigInt support', function () { it(description, test); } + + it('correctly deserializes min 64 bit int (-2n**63n)', function () { + expect( + BSON.deserialize(Buffer.from('10000000126100000000000000008000', 'hex'), { + useBigInt64: true + }) + ).to.deep.equal({ a: -(2n ** 63n) }); + }); + + it('correctly deserializes -1n', function () { + expect( + BSON.deserialize(Buffer.from('10000000126100FFFFFFFFFFFFFFFF00', 'hex'), { + useBigInt64: true + }) + ).to.deep.equal({ a: -1n }); + }); + + it('correctly deserializes 0n', function () { + expect( + BSON.deserialize(Buffer.from('10000000126100000000000000000000', 'hex'), { + useBigInt64: true + }) + ).to.deep.equal({ a: 0n }); + }); + + it('correctly deserializes 1n', function () { + expect( + BSON.deserialize(Buffer.from('10000000126100010000000000000000', 'hex'), { + useBigInt64: true + }) + ).to.deep.equal({ a: 1n }); + }); + + it('correctly deserializes max 64 bit int (2n**63n -1n)', function () { + expect( + BSON.deserialize(Buffer.from('10000000126100FFFFFFFFFFFFFF7F00', 'hex'), { + useBigInt64: true + }) + ).to.deep.equal({ a: 2n ** 63n - 1n }); + }); }); describe('BSON.serialize()', function () {