@@ -14,7 +14,8 @@ 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' ;
18+ import { NumberUtils } from '../utils/number_utils' ;
1819import { validateUtf8 } from '../validate_utf8' ;
1920
2021/** @public */
@@ -91,11 +92,7 @@ export function internalDeserialize(
9192 options = options == null ? { } : options ;
9293 const index = options && options . index ? options . index : 0 ;
9394 // Read the document size
94- const size =
95- buffer [ index ] |
96- ( buffer [ index + 1 ] << 8 ) |
97- ( buffer [ index + 2 ] << 16 ) |
98- ( buffer [ index + 3 ] << 24 ) ;
95+ const size = NumberUtils . getInt32LE ( buffer , index ) ;
9996
10097 if ( size < 5 ) {
10198 throw new BSONError ( `bson size must be >= 5, is ${ size } ` ) ;
@@ -204,8 +201,8 @@ function deserializeObject(
204201 if ( buffer . length < 5 ) throw new BSONError ( 'corrupt bson message < 5 bytes long' ) ;
205202
206203 // Read the document size
207- const size =
208- buffer [ index ++ ] | ( buffer [ index ++ ] << 8 ) | ( buffer [ index ++ ] << 16 ) | ( buffer [ index ++ ] << 24 ) ;
204+ const size = NumberUtils . getInt32LE ( buffer , index ) ;
205+ index += 4 ;
209206
210207 // Ensure buffer is valid size
211208 if ( size < 5 || size > buffer . length ) throw new BSONError ( 'corrupt bson message' ) ;
@@ -218,8 +215,6 @@ function deserializeObject(
218215
219216 let isPossibleDBRef = isArray ? false : null ;
220217
221- let dataView ;
222-
223218 // While we have more left data left keep parsing
224219 while ( ! done ) {
225220 // Read the type
@@ -257,11 +252,8 @@ function deserializeObject(
257252 index = i + 1 ;
258253
259254 if ( elementType === constants . BSON_DATA_STRING ) {
260- const stringSize =
261- buffer [ index ++ ] |
262- ( buffer [ index ++ ] << 8 ) |
263- ( buffer [ index ++ ] << 16 ) |
264- ( buffer [ index ++ ] << 24 ) ;
255+ const stringSize = NumberUtils . getInt32LE ( buffer , index ) ;
256+ index += 4 ;
265257 if (
266258 stringSize <= 0 ||
267259 stringSize > buffer . length - index ||
@@ -277,34 +269,19 @@ function deserializeObject(
277269 value = new ObjectId ( oid ) ;
278270 index = index + 12 ;
279271 } else if ( elementType === constants . BSON_DATA_INT && promoteValues === false ) {
280- value = new Int32 (
281- buffer [ index ++ ] | ( buffer [ index ++ ] << 8 ) | ( buffer [ index ++ ] << 16 ) | ( buffer [ index ++ ] << 24 )
282- ) ;
272+ value = new Int32 ( NumberUtils . getInt32LE ( buffer , index ) ) ;
273+ index += 4 ;
283274 } else if ( elementType === constants . BSON_DATA_INT ) {
284- value =
285- buffer [ index ++ ] |
286- ( buffer [ index ++ ] << 8 ) |
287- ( buffer [ index ++ ] << 16 ) |
288- ( 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 ;
275+ value = NumberUtils . getInt32LE ( buffer , index ) ;
276+ index += 4 ;
293277 } 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 ;
278+ value = NumberUtils . getFloat64LE ( buffer , index ) ;
279+ index += 8 ;
280+ if ( promoteValues === false ) value = new Double ( value ) ;
297281 } else if ( elementType === constants . BSON_DATA_DATE ) {
298- const lowBits =
299- buffer [ index ++ ] |
300- ( buffer [ index ++ ] << 8 ) |
301- ( buffer [ index ++ ] << 16 ) |
302- ( buffer [ index ++ ] << 24 ) ;
303- const highBits =
304- buffer [ index ++ ] |
305- ( buffer [ index ++ ] << 8 ) |
306- ( buffer [ index ++ ] << 16 ) |
307- ( buffer [ index ++ ] << 24 ) ;
282+ const lowBits = NumberUtils . getInt32LE ( buffer , index ) ;
283+ const highBits = NumberUtils . getInt32LE ( buffer , index + 4 ) ;
284+ index += 8 ;
308285
309286 value = new Date ( new Long ( lowBits , highBits ) . toNumber ( ) ) ;
310287 } else if ( elementType === constants . BSON_DATA_BOOLEAN ) {
@@ -313,11 +290,8 @@ function deserializeObject(
313290 value = buffer [ index ++ ] === 1 ;
314291 } else if ( elementType === constants . BSON_DATA_OBJECT ) {
315292 const _index = index ;
316- const objectSize =
317- buffer [ index ] |
318- ( buffer [ index + 1 ] << 8 ) |
319- ( buffer [ index + 2 ] << 16 ) |
320- ( buffer [ index + 3 ] << 24 ) ;
293+ const objectSize = NumberUtils . getInt32LE ( buffer , index ) ;
294+
321295 if ( objectSize <= 0 || objectSize > buffer . length - index )
322296 throw new BSONError ( 'bad embedded document length in bson' ) ;
323297
@@ -335,11 +309,7 @@ function deserializeObject(
335309 index = index + objectSize ;
336310 } else if ( elementType === constants . BSON_DATA_ARRAY ) {
337311 const _index = index ;
338- const objectSize =
339- buffer [ index ] |
340- ( buffer [ index + 1 ] << 8 ) |
341- ( buffer [ index + 2 ] << 16 ) |
342- ( buffer [ index + 3 ] << 24 ) ;
312+ const objectSize = NumberUtils . getInt32LE ( buffer , index ) ;
343313 let arrayOptions : DeserializeOptions = options ;
344314
345315 // Stop index
@@ -363,30 +333,25 @@ function deserializeObject(
363333 } else if ( elementType === constants . BSON_DATA_NULL ) {
364334 value = null ;
365335 } 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 ) ;
380336 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 ;
337+ value = NumberUtils . getBigInt64LE ( buffer , index ) ;
338+ index += 8 ;
388339 } else {
389- value = long ;
340+ // Unpack the low and high bits
341+ const lowBits = NumberUtils . getInt32LE ( buffer , index ) ;
342+ const highBits = NumberUtils . getInt32LE ( buffer , index + 4 ) ;
343+ index += 8 ;
344+
345+ const long = new Long ( lowBits , highBits ) ;
346+ // Promote the long if possible
347+ if ( promoteLongs && promoteValues === true ) {
348+ value =
349+ long . lessThanOrEqual ( JS_INT_MAX_LONG ) && long . greaterThanOrEqual ( JS_INT_MIN_LONG )
350+ ? long . toNumber ( )
351+ : long ;
352+ } else {
353+ value = long ;
354+ }
390355 }
391356 } else if ( elementType === constants . BSON_DATA_DECIMAL128 ) {
392357 // Buffer to contain the decimal bytes
@@ -398,11 +363,8 @@ function deserializeObject(
398363 // Assign the new Decimal128 value
399364 value = new Decimal128 ( bytes ) ;
400365 } else if ( elementType === constants . BSON_DATA_BINARY ) {
401- let binarySize =
402- buffer [ index ++ ] |
403- ( buffer [ index ++ ] << 8 ) |
404- ( buffer [ index ++ ] << 16 ) |
405- ( buffer [ index ++ ] << 24 ) ;
366+ let binarySize = NumberUtils . getInt32LE ( buffer , index ) ;
367+ index += 4 ;
406368 const totalBinarySize = binarySize ;
407369 const subType = buffer [ index ++ ] ;
408370
@@ -417,11 +379,8 @@ function deserializeObject(
417379 if ( buffer [ 'slice' ] != null ) {
418380 // If we have subtype 2 skip the 4 bytes for the size
419381 if ( subType === Binary . SUBTYPE_BYTE_ARRAY ) {
420- binarySize =
421- buffer [ index ++ ] |
422- ( buffer [ index ++ ] << 8 ) |
423- ( buffer [ index ++ ] << 16 ) |
424- ( buffer [ index ++ ] << 24 ) ;
382+ binarySize = NumberUtils . getInt32LE ( buffer , index ) ;
383+ index += 4 ;
425384 if ( binarySize < 0 )
426385 throw new BSONError ( 'Negative binary type element size found for subtype 0x02' ) ;
427386 if ( binarySize > totalBinarySize - 4 )
@@ -442,11 +401,8 @@ function deserializeObject(
442401 const _buffer = ByteUtils . allocate ( binarySize ) ;
443402 // If we have subtype 2 skip the 4 bytes for the size
444403 if ( subType === Binary . SUBTYPE_BYTE_ARRAY ) {
445- binarySize =
446- buffer [ index ++ ] |
447- ( buffer [ index ++ ] << 8 ) |
448- ( buffer [ index ++ ] << 16 ) |
449- ( buffer [ index ++ ] << 24 ) ;
404+ binarySize = NumberUtils . getInt32LE ( buffer , index ) ;
405+ index += 4 ;
450406 if ( binarySize < 0 )
451407 throw new BSONError ( 'Negative binary type element size found for subtype 0x02' ) ;
452408 if ( binarySize > totalBinarySize - 4 )
@@ -545,11 +501,8 @@ function deserializeObject(
545501 // Set the object
546502 value = new BSONRegExp ( source , regExpOptions ) ;
547503 } else if ( elementType === constants . BSON_DATA_SYMBOL ) {
548- const stringSize =
549- buffer [ index ++ ] |
550- ( buffer [ index ++ ] << 8 ) |
551- ( buffer [ index ++ ] << 16 ) |
552- ( buffer [ index ++ ] << 24 ) ;
504+ const stringSize = NumberUtils . getInt32LE ( buffer , index ) ;
505+ index += 4 ;
553506 if (
554507 stringSize <= 0 ||
555508 stringSize > buffer . length - index ||
@@ -561,31 +514,18 @@ function deserializeObject(
561514 value = promoteValues ? symbol : new BSONSymbol ( symbol ) ;
562515 index = index + stringSize ;
563516 } else if ( elementType === constants . BSON_DATA_TIMESTAMP ) {
564- // We intentionally **do not** use bit shifting here
565- // Bit shifting in javascript coerces numbers to **signed** int32s
566- // We need to keep i, and t unsigned
567- const i =
568- buffer [ index ++ ] +
569- buffer [ index ++ ] * ( 1 << 8 ) +
570- buffer [ index ++ ] * ( 1 << 16 ) +
571- buffer [ index ++ ] * ( 1 << 24 ) ;
572- const t =
573- buffer [ index ++ ] +
574- buffer [ index ++ ] * ( 1 << 8 ) +
575- buffer [ index ++ ] * ( 1 << 16 ) +
576- buffer [ index ++ ] * ( 1 << 24 ) ;
577-
578- value = new Timestamp ( { i, t } ) ;
517+ value = new Timestamp ( {
518+ i : NumberUtils . getUint32LE ( buffer , index ) ,
519+ t : NumberUtils . getUint32LE ( buffer , index + 4 )
520+ } ) ;
521+ index += 8 ;
579522 } else if ( elementType === constants . BSON_DATA_MIN_KEY ) {
580523 value = new MinKey ( ) ;
581524 } else if ( elementType === constants . BSON_DATA_MAX_KEY ) {
582525 value = new MaxKey ( ) ;
583526 } else if ( elementType === constants . BSON_DATA_CODE ) {
584- const stringSize =
585- buffer [ index ++ ] |
586- ( buffer [ index ++ ] << 8 ) |
587- ( buffer [ index ++ ] << 16 ) |
588- ( buffer [ index ++ ] << 24 ) ;
527+ const stringSize = NumberUtils . getInt32LE ( buffer , index ) ;
528+ index += 4 ;
589529 if (
590530 stringSize <= 0 ||
591531 stringSize > buffer . length - index ||
@@ -605,23 +545,17 @@ function deserializeObject(
605545 // Update parse index position
606546 index = index + stringSize ;
607547 } else if ( elementType === constants . BSON_DATA_CODE_W_SCOPE ) {
608- const totalSize =
609- buffer [ index ++ ] |
610- ( buffer [ index ++ ] << 8 ) |
611- ( buffer [ index ++ ] << 16 ) |
612- ( buffer [ index ++ ] << 24 ) ;
548+ const totalSize = NumberUtils . getInt32LE ( buffer , index ) ;
549+ index += 4 ;
613550
614551 // Element cannot be shorter than totalSize + stringSize + documentSize + terminator
615552 if ( totalSize < 4 + 4 + 4 + 1 ) {
616553 throw new BSONError ( 'code_w_scope total size shorter minimum expected length' ) ;
617554 }
618555
619556 // Get the code string size
620- const stringSize =
621- buffer [ index ++ ] |
622- ( buffer [ index ++ ] << 8 ) |
623- ( buffer [ index ++ ] << 16 ) |
624- ( buffer [ index ++ ] << 24 ) ;
557+ const stringSize = NumberUtils . getInt32LE ( buffer , index ) ;
558+ index += 4 ;
625559 // Check if we have a valid string
626560 if (
627561 stringSize <= 0 ||
@@ -643,11 +577,7 @@ function deserializeObject(
643577 // Parse the element
644578 const _index = index ;
645579 // Decode the size of the object document
646- const objectSize =
647- buffer [ index ] |
648- ( buffer [ index + 1 ] << 8 ) |
649- ( buffer [ index + 2 ] << 16 ) |
650- ( buffer [ index + 3 ] << 24 ) ;
580+ const objectSize = NumberUtils . getInt32LE ( buffer , index ) ;
651581 // Decode the scope object
652582 const scopeObject = deserializeObject ( buffer , _index , options , false ) ;
653583 // Adjust the index
@@ -666,11 +596,8 @@ function deserializeObject(
666596 value = new Code ( functionString , scopeObject ) ;
667597 } else if ( elementType === constants . BSON_DATA_DBPOINTER ) {
668598 // Get the code string size
669- const stringSize =
670- buffer [ index ++ ] |
671- ( buffer [ index ++ ] << 8 ) |
672- ( buffer [ index ++ ] << 16 ) |
673- ( buffer [ index ++ ] << 24 ) ;
599+ const stringSize = NumberUtils . getInt32LE ( buffer , index ) ;
600+ index += 4 ;
674601 // Check if we have a valid string
675602 if (
676603 stringSize <= 0 ||
0 commit comments