@@ -13,8 +13,16 @@ export type BSONElement = [
1313 length : number
1414] ;
1515
16+ /** Parses a int32 little-endian at offset, throws if it is negative */
17+ function getSize ( source : Uint8Array , offset : number ) : number {
18+ if ( source [ offset + 3 ] > 127 ) {
19+ throw new BSONOffsetError ( 'BSON size cannot be negative' , offset ) ;
20+ }
21+ return NumberUtils . getInt32LE ( source , offset ) ;
22+ }
23+
1624/**
17- * Searches for null terminator.
25+ * Searches for null terminator of a BSON element's value (Never the document null terminator)
1826 * **Does not** bounds check since this should **ONLY** be used within parseToElements which has asserted that `bytes` ends with a `0x00`.
1927 * So this will at most iterate to the document's terminator and error if that is the offset reached.
2028 */
@@ -24,6 +32,7 @@ function findNull(bytes: Uint8Array, offset: number): number {
2432 for ( ; bytes [ nullTerminatorOffset ] !== 0x00 ; nullTerminatorOffset ++ ) ;
2533
2634 if ( nullTerminatorOffset === bytes . length - 1 ) {
35+ // We reached the null terminator of the document, not a value's
2736 throw new BSONOffsetError ( 'Null terminator not found' , offset ) ;
2837 }
2938
@@ -42,7 +51,7 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
4251 ) ;
4352 }
4453
45- const documentSize = NumberUtils . getSize ( bytes , startOffset ) ;
54+ const documentSize = getSize ( bytes , startOffset ) ;
4655
4756 if ( documentSize > bytes . length - startOffset ) {
4857 throw new BSONOffsetError (
@@ -75,6 +84,7 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
7584
7685 let length : number ;
7786
87+ // The following values are left as literals intentionally
7888 if ( type === 1 || type === 18 || type === 9 || type === 17 ) {
7989 // double, long, date, timestamp
8090 length = 8 ;
@@ -100,10 +110,10 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
100110 length = findNull ( bytes , findNull ( bytes , offset ) + 1 ) + 1 - offset ;
101111 } else if ( type === 3 || type === 4 || type === 15 ) {
102112 // object, array, code_w_scope
103- length = NumberUtils . getSize ( bytes , offset ) ;
113+ length = getSize ( bytes , offset ) ;
104114 } else if ( type === 2 || type === 5 || type === 12 || type === 13 || type === 14 ) {
105115 // string, binary, dbpointer, code, symbol
106- length = NumberUtils . getSize ( bytes , offset ) + 4 ;
116+ length = getSize ( bytes , offset ) + 4 ;
107117 if ( type === 5 ) {
108118 // binary subtype
109119 length += 1 ;
0 commit comments