@@ -44,11 +44,41 @@ use crate::{
44
44
Decimal128 ,
45
45
} ;
46
46
47
- use :: serde:: de:: { self , Error as _} ;
47
+ use :: serde:: {
48
+ de:: { Error as _, Unexpected } ,
49
+ Deserialize ,
50
+ } ;
48
51
49
52
const MAX_BSON_SIZE : i32 = 16 * 1024 * 1024 ;
53
+ pub ( crate ) const MIN_BSON_DOCUMENT_SIZE : i32 = 4 + 1 ; // 4 bytes for length, one byte for null terminator
54
+ const MIN_BSON_STRING_SIZE : i32 = 4 + 1 ; // 4 bytes for length, one byte for null terminator
55
+ const MIN_CODE_WITH_SCOPE_SIZE : i32 = 4 + MIN_BSON_STRING_SIZE + MIN_BSON_DOCUMENT_SIZE ;
56
+
57
+ /// Run the provided closure, ensuring that over the course of its execution, exactly `length` bytes
58
+ /// were read from the reader.
59
+ pub ( crate ) fn ensure_read_exactly < F , R > (
60
+ reader : & mut R ,
61
+ length : usize ,
62
+ error_message : & str ,
63
+ func : F ,
64
+ ) -> Result < ( ) >
65
+ where
66
+ F : FnOnce ( & mut std:: io:: Cursor < Vec < u8 > > ) -> Result < ( ) > ,
67
+ R : Read + ?Sized ,
68
+ {
69
+ let mut buf = vec ! [ 0u8 ; length] ;
70
+ reader. read_exact ( & mut buf) ?;
71
+ let mut cursor = std:: io:: Cursor :: new ( buf) ;
72
+
73
+ func ( & mut cursor) ?;
74
+
75
+ if cursor. position ( ) != length as u64 {
76
+ return Err ( Error :: invalid_length ( length, & error_message) ) ;
77
+ }
78
+ Ok ( ( ) )
79
+ }
50
80
51
- fn read_string < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> crate :: de :: Result < String > {
81
+ fn read_string < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> Result < String > {
52
82
let len = reader. read_i32 :: < LittleEndian > ( ) ?;
53
83
54
84
// UTF-8 String must have at least 1 byte (the last 0x00).
@@ -68,12 +98,19 @@ fn read_string<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> crate::de:
68
98
reader. take ( len as u64 - 1 ) . read_to_string ( & mut s) ?;
69
99
s
70
100
} ;
71
- reader. read_u8 ( ) ?; // The last 0x00
101
+
102
+ // read the null terminator
103
+ if reader. read_u8 ( ) ? != 0 {
104
+ return Err ( Error :: invalid_length (
105
+ len as usize ,
106
+ & "contents of string longer than provided length" ,
107
+ ) ) ;
108
+ }
72
109
73
110
Ok ( s)
74
111
}
75
112
76
- fn read_cstring < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < String > {
113
+ fn read_cstring < R : Read + ?Sized > ( reader : & mut R ) -> Result < String > {
77
114
let mut v = Vec :: new ( ) ;
78
115
79
116
loop {
@@ -88,28 +125,28 @@ fn read_cstring<R: Read + ?Sized>(reader: &mut R) -> crate::de::Result<String> {
88
125
}
89
126
90
127
#[ inline]
91
- pub ( crate ) fn read_i32 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < i32 > {
128
+ pub ( crate ) fn read_i32 < R : Read + ?Sized > ( reader : & mut R ) -> Result < i32 > {
92
129
reader. read_i32 :: < LittleEndian > ( ) . map_err ( From :: from)
93
130
}
94
131
95
132
#[ inline]
96
- fn read_i64 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < i64 > {
133
+ fn read_i64 < R : Read + ?Sized > ( reader : & mut R ) -> Result < i64 > {
97
134
reader. read_i64 :: < LittleEndian > ( ) . map_err ( From :: from)
98
135
}
99
136
100
137
/// Placeholder decoder for `Decimal128`. Reads 128 bits and just stores them, does no validation or
101
138
/// parsing.
102
139
#[ cfg( not( feature = "decimal128" ) ) ]
103
140
#[ inline]
104
- fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < Decimal128 > {
141
+ fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> Result < Decimal128 > {
105
142
let mut buf = [ 0u8 ; 128 / 8 ] ;
106
143
reader. read_exact ( & mut buf) ?;
107
144
Ok ( Decimal128 { bytes : buf } )
108
145
}
109
146
110
147
#[ cfg( feature = "decimal128" ) ]
111
148
#[ inline]
112
- fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> crate :: de :: Result < Decimal128 > {
149
+ fn read_f128 < R : Read + ?Sized > ( reader : & mut R ) -> Result < Decimal128 > {
113
150
use std:: mem;
114
151
115
152
let mut local_buf: [ u8 ; 16 ] = unsafe { mem:: MaybeUninit :: uninit ( ) . assume_init ( ) } ;
@@ -118,24 +155,27 @@ fn read_f128<R: Read + ?Sized>(reader: &mut R) -> crate::de::Result<Decimal128>
118
155
Ok ( val)
119
156
}
120
157
121
- fn deserialize_array < R : Read + ?Sized > (
122
- reader : & mut R ,
123
- utf8_lossy : bool ,
124
- ) -> crate :: de:: Result < Array > {
158
+ fn deserialize_array < R : Read + ?Sized > ( reader : & mut R , utf8_lossy : bool ) -> Result < Array > {
125
159
let mut arr = Array :: new ( ) ;
126
-
127
- // disregard the length: using Read::take causes infinite type recursion
128
- read_i32 ( reader) ?;
129
-
130
- loop {
131
- let tag = reader. read_u8 ( ) ?;
132
- if tag == 0 {
133
- break ;
134
- }
135
-
136
- let ( _, val) = deserialize_bson_kvp ( reader, tag, utf8_lossy) ?;
137
- arr. push ( val)
138
- }
160
+ let length = read_i32 ( reader) ?;
161
+
162
+ ensure_read_exactly (
163
+ reader,
164
+ ( length as usize ) - 4 ,
165
+ "array length longer than contents" ,
166
+ |cursor| {
167
+ loop {
168
+ let tag = cursor. read_u8 ( ) ?;
169
+ if tag == 0 {
170
+ break ;
171
+ }
172
+
173
+ let ( _, val) = deserialize_bson_kvp ( cursor, tag, utf8_lossy) ?;
174
+ arr. push ( val)
175
+ }
176
+ Ok ( ( ) )
177
+ } ,
178
+ ) ?;
139
179
140
180
Ok ( arr)
141
181
}
@@ -144,7 +184,7 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
144
184
reader : & mut R ,
145
185
tag : u8 ,
146
186
utf8_lossy : bool ,
147
- ) -> crate :: de :: Result < ( String , Bson ) > {
187
+ ) -> Result < ( String , Bson ) > {
148
188
use spec:: ElementType ;
149
189
let key = read_cstring ( reader) ?;
150
190
@@ -165,7 +205,15 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
165
205
166
206
// Skip length data in old binary.
167
207
if let BinarySubtype :: BinaryOld = subtype {
168
- read_i32 ( reader) ?;
208
+ let data_len = read_i32 ( reader) ?;
209
+
210
+ if data_len + 4 != len {
211
+ return Err ( Error :: invalid_length (
212
+ data_len as usize ,
213
+ & "0x02 length did not match top level binary length" ,
214
+ ) ) ;
215
+ }
216
+
169
217
len -= 4 ;
170
218
}
171
219
@@ -181,7 +229,17 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
181
229
}
182
230
Bson :: ObjectId ( oid:: ObjectId :: with_bytes ( objid) )
183
231
}
184
- Some ( ElementType :: Boolean ) => Bson :: Boolean ( reader. read_u8 ( ) ? != 0 ) ,
232
+ Some ( ElementType :: Boolean ) => {
233
+ let val = reader. read_u8 ( ) ?;
234
+ if val > 1 {
235
+ return Err ( Error :: invalid_value (
236
+ Unexpected :: Unsigned ( val as u64 ) ,
237
+ & "boolean must be stored as 0 or 1" ,
238
+ ) ) ;
239
+ }
240
+
241
+ Bson :: Boolean ( val != 0 )
242
+ }
185
243
Some ( ElementType :: Null ) => Bson :: Null ,
186
244
Some ( ElementType :: RegularExpression ) => {
187
245
let pattern = read_cstring ( reader) ?;
@@ -198,12 +256,29 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
198
256
read_string ( reader, utf8_lossy) . map ( Bson :: JavaScriptCode ) ?
199
257
}
200
258
Some ( ElementType :: JavaScriptCodeWithScope ) => {
201
- // disregard the length:
202
- // using Read::take causes infinite type recursion
203
- read_i32 ( reader) ?;
259
+ let length = read_i32 ( reader) ?;
260
+ if length < MIN_CODE_WITH_SCOPE_SIZE {
261
+ return Err ( Error :: invalid_length (
262
+ length as usize ,
263
+ & format ! (
264
+ "code with scope length must be at least {}" ,
265
+ MIN_CODE_WITH_SCOPE_SIZE
266
+ )
267
+ . as_str ( ) ,
268
+ ) ) ;
269
+ } else if length > MAX_BSON_SIZE {
270
+ return Err ( Error :: invalid_length (
271
+ length as usize ,
272
+ & "code with scope length too large" ,
273
+ ) ) ;
274
+ }
275
+
276
+ let mut buf = vec ! [ 0u8 ; ( length - 4 ) as usize ] ;
277
+ reader. read_exact ( & mut buf) ?;
204
278
205
- let code = read_string ( reader, utf8_lossy) ?;
206
- let scope = Document :: from_reader ( reader) ?;
279
+ let mut slice = buf. as_slice ( ) ;
280
+ let code = read_string ( & mut slice, utf8_lossy) ?;
281
+ let scope = Document :: from_reader ( & mut slice) ?;
207
282
Bson :: JavaScriptCodeWithScope ( JavaScriptCodeWithScope { code, scope } )
208
283
}
209
284
Some ( ElementType :: Int32 ) => read_i32 ( reader) . map ( Bson :: Int32 ) ?,
@@ -256,10 +331,10 @@ pub(crate) fn deserialize_bson_kvp<R: Read + ?Sized>(
256
331
}
257
332
258
333
/// Decode a BSON `Value` into a `T` Deserializable.
259
- pub fn from_bson < ' de , T > ( bson : Bson ) -> crate :: de :: Result < T >
334
+ pub fn from_bson < ' de , T > ( bson : Bson ) -> Result < T >
260
335
where
261
- T : de :: Deserialize < ' de > ,
336
+ T : Deserialize < ' de > ,
262
337
{
263
338
let de = Deserializer :: new ( bson) ;
264
- de :: Deserialize :: deserialize ( de)
339
+ Deserialize :: deserialize ( de)
265
340
}
0 commit comments