@@ -13,8 +13,16 @@ export type BSONElement = [
13
13
length : number
14
14
] ;
15
15
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
+
16
24
/**
17
- * Searches for null terminator.
25
+ * Searches for null terminator of a BSON element's value (Never the document null terminator)
18
26
* **Does not** bounds check since this should **ONLY** be used within parseToElements which has asserted that `bytes` ends with a `0x00`.
19
27
* So this will at most iterate to the document's terminator and error if that is the offset reached.
20
28
*/
@@ -24,6 +32,7 @@ function findNull(bytes: Uint8Array, offset: number): number {
24
32
for ( ; bytes [ nullTerminatorOffset ] !== 0x00 ; nullTerminatorOffset ++ ) ;
25
33
26
34
if ( nullTerminatorOffset === bytes . length - 1 ) {
35
+ // We reached the null terminator of the document, not a value's
27
36
throw new BSONOffsetError ( 'Null terminator not found' , offset ) ;
28
37
}
29
38
@@ -42,7 +51,7 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
42
51
) ;
43
52
}
44
53
45
- const documentSize = NumberUtils . getSize ( bytes , startOffset ) ;
54
+ const documentSize = getSize ( bytes , startOffset ) ;
46
55
47
56
if ( documentSize > bytes . length - startOffset ) {
48
57
throw new BSONOffsetError (
@@ -75,6 +84,7 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
75
84
76
85
let length : number ;
77
86
87
+ // The following values are left as literals intentionally
78
88
if ( type === 1 || type === 18 || type === 9 || type === 17 ) {
79
89
// double, long, date, timestamp
80
90
length = 8 ;
@@ -100,10 +110,10 @@ export function parseToElements(bytes: Uint8Array, startOffset = 0): Iterable<BS
100
110
length = findNull ( bytes , findNull ( bytes , offset ) + 1 ) + 1 - offset ;
101
111
} else if ( type === 3 || type === 4 || type === 15 ) {
102
112
// object, array, code_w_scope
103
- length = NumberUtils . getSize ( bytes , offset ) ;
113
+ length = getSize ( bytes , offset ) ;
104
114
} else if ( type === 2 || type === 5 || type === 12 || type === 13 || type === 14 ) {
105
115
// string, binary, dbpointer, code, symbol
106
- length = NumberUtils . getSize ( bytes , offset ) + 4 ;
116
+ length = getSize ( bytes , offset ) + 4 ;
107
117
if ( type === 5 ) {
108
118
// binary subtype
109
119
length += 1 ;
0 commit comments