@@ -14,7 +14,7 @@ import { ObjectId } from '../objectid';
1414import { BSONRegExp } from '../regexp' ;
1515import { BSONSymbol } from '../symbol' ;
1616import { Timestamp } from '../timestamp' ;
17- import { BSONDataView , ByteUtils } from '../utils/byte_utils' ;
17+ import { ByteUtils } from '../utils/byte_utils' ;
1818import { validateUtf8 } from '../validate_utf8' ;
1919
2020/** @public */
@@ -128,6 +128,9 @@ export function internalDeserialize(
128128
129129const allowedDBRefKeys = / ^ \$ r e f $ | ^ \$ i d $ | ^ \$ d b $ / ;
130130
131+ const FLOAT = new Float64Array ( 1 ) ;
132+ const FLOAT_BYTES = new Uint8Array ( FLOAT . buffer , 0 , 8 ) ;
133+
131134function deserializeObject (
132135 buffer : Uint8Array ,
133136 index : number ,
@@ -218,8 +221,6 @@ function deserializeObject(
218221
219222 let isPossibleDBRef = isArray ? false : null ;
220223
221- let dataView ;
222-
223224 // While we have more left data left keep parsing
224225 while ( ! done ) {
225226 // Read the type
@@ -286,14 +287,17 @@ function deserializeObject(
286287 ( buffer [ index ++ ] << 8 ) |
287288 ( buffer [ index ++ ] << 16 ) |
288289 ( buffer [ index ++ ] << 24 ) ;
289- } else if ( elementType === constants . BSON_DATA_NUMBER && promoteValues === false ) {
290- dataView ??= new DataView ( buffer . buffer , buffer . byteOffset , buffer . byteLength ) ;
291- value = new Double ( dataView . getFloat64 ( index , true ) ) ;
292- index = index + 8 ;
293290 } else if ( elementType === constants . BSON_DATA_NUMBER ) {
294- dataView ??= new DataView ( buffer . buffer , buffer . byteOffset , buffer . byteLength ) ;
295- value = dataView . getFloat64 ( index , true ) ;
296- index = index + 8 ;
291+ FLOAT_BYTES [ 0 ] = buffer [ index ++ ] ;
292+ FLOAT_BYTES [ 1 ] = buffer [ index ++ ] ;
293+ FLOAT_BYTES [ 2 ] = buffer [ index ++ ] ;
294+ FLOAT_BYTES [ 3 ] = buffer [ index ++ ] ;
295+ FLOAT_BYTES [ 4 ] = buffer [ index ++ ] ;
296+ FLOAT_BYTES [ 5 ] = buffer [ index ++ ] ;
297+ FLOAT_BYTES [ 6 ] = buffer [ index ++ ] ;
298+ FLOAT_BYTES [ 7 ] = buffer [ index ++ ] ;
299+ value = FLOAT [ 0 ] ;
300+ if ( promoteValues === false ) value = new Double ( value ) ;
297301 } else if ( elementType === constants . BSON_DATA_DATE ) {
298302 const lowBits =
299303 buffer [ index ++ ] |
@@ -363,30 +367,43 @@ function deserializeObject(
363367 } else if ( elementType === constants . BSON_DATA_NULL ) {
364368 value = null ;
365369 } else if ( elementType === constants . BSON_DATA_LONG ) {
366- // Unpack the low and high bits
367- const dataview = BSONDataView . fromUint8Array ( buffer . subarray ( index , index + 8 ) ) ;
368-
369- const lowBits =
370- buffer [ index ++ ] |
371- ( buffer [ index ++ ] << 8 ) |
372- ( buffer [ index ++ ] << 16 ) |
373- ( buffer [ index ++ ] << 24 ) ;
374- const highBits =
375- buffer [ index ++ ] |
376- ( buffer [ index ++ ] << 8 ) |
377- ( buffer [ index ++ ] << 16 ) |
378- ( buffer [ index ++ ] << 24 ) ;
379- const long = new Long ( lowBits , highBits ) ;
380370 if ( useBigInt64 ) {
381- value = dataview . getBigInt64 ( 0 , true ) ;
382- } else if ( promoteLongs && promoteValues === true ) {
383- // Promote the long if possible
384- value =
385- long . lessThanOrEqual ( JS_INT_MAX_LONG ) && long . greaterThanOrEqual ( JS_INT_MIN_LONG )
386- ? long . toNumber ( )
387- : long ;
371+ const lo =
372+ buffer [ index ] +
373+ buffer [ index + 1 ] * 2 ** 8 +
374+ buffer [ index + 2 ] * 2 ** 16 +
375+ buffer [ index + 3 ] * 2 ** 24 ;
376+ const hi =
377+ buffer [ index + 4 ] +
378+ buffer [ index + 5 ] * 2 ** 8 +
379+ buffer [ index + 6 ] * 2 ** 16 +
380+ ( buffer [ index + 7 ] << 24 ) ; // Overflow
381+
382+ /* eslint-disable-next-line no-restricted-globals -- This is allowed here as useBigInt64=true */
383+ value = ( BigInt ( hi ) << BigInt ( 32 ) ) + BigInt ( lo ) ;
384+ index += 8 ;
388385 } else {
389- value = long ;
386+ // Unpack the low and high bits
387+ const lowBits =
388+ buffer [ index ++ ] |
389+ ( buffer [ index ++ ] << 8 ) |
390+ ( buffer [ index ++ ] << 16 ) |
391+ ( buffer [ index ++ ] << 24 ) ;
392+ const highBits =
393+ buffer [ index ++ ] |
394+ ( buffer [ index ++ ] << 8 ) |
395+ ( buffer [ index ++ ] << 16 ) |
396+ ( buffer [ index ++ ] << 24 ) ;
397+ const long = new Long ( lowBits , highBits ) ;
398+ // Promote the long if possible
399+ if ( promoteLongs && promoteValues === true ) {
400+ value =
401+ long . lessThanOrEqual ( JS_INT_MAX_LONG ) && long . greaterThanOrEqual ( JS_INT_MIN_LONG )
402+ ? long . toNumber ( )
403+ : long ;
404+ } else {
405+ value = long ;
406+ }
390407 }
391408 } else if ( elementType === constants . BSON_DATA_DECIMAL128 ) {
392409 // Buffer to contain the decimal bytes
0 commit comments