@@ -15,6 +15,8 @@ use bytes::BytesMut;
15
15
use error:: WireError ;
16
16
use ProtobufError ;
17
17
use ProtobufResult ;
18
+ use stream:: READ_RAW_BYTES_MAX_ALLOC ;
19
+
18
20
19
21
// If an input stream is constructed with a `Read`, we create a
20
22
// `BufReader` with an internal buffer of this size.
@@ -221,6 +223,61 @@ impl<'ignore> BufReadIter<'ignore> {
221
223
Ok ( r)
222
224
}
223
225
226
+ /// Read at most `max` bytes, append to `Vec`.
227
+ ///
228
+ /// Returns 0 when EOF or limit reached.
229
+ fn read_to_vec ( & mut self , vec : & mut Vec < u8 > , max : usize ) -> ProtobufResult < usize > {
230
+ let rem = self . fill_buf ( ) ?;
231
+
232
+ let len = cmp:: min ( rem. len ( ) , max) ;
233
+ vec. extend_from_slice ( & rem[ ..len] ) ;
234
+ self . pos_within_buf += len;
235
+ Ok ( len)
236
+ }
237
+
238
+ /// Read exact number of bytes into `Vec`.
239
+ ///
240
+ /// `Vec` is cleared in the beginning.
241
+ pub fn read_exact_to_vec ( & mut self , count : usize , target : & mut Vec < u8 > ) -> ProtobufResult < ( ) > {
242
+ // TODO: also do some limits when reading from unlimited source
243
+ if count as u64 > self . bytes_until_limit ( ) {
244
+ return Err ( ProtobufError :: WireError ( WireError :: TruncatedMessage ) ) ;
245
+ }
246
+
247
+ target. clear ( ) ;
248
+
249
+ if count >= READ_RAW_BYTES_MAX_ALLOC && count > target. capacity ( ) {
250
+ // avoid calling `reserve` on buf with very large buffer: could be a malformed message
251
+
252
+ target. reserve ( READ_RAW_BYTES_MAX_ALLOC ) ;
253
+
254
+ while target. len ( ) < count {
255
+ if count - target. len ( ) <= target. len ( ) {
256
+ target. reserve_exact ( count - target. len ( ) ) ;
257
+ } else {
258
+ target. reserve ( 1 ) ;
259
+ }
260
+
261
+ let max = cmp:: min ( target. capacity ( ) - target. len ( ) , count - target. len ( ) ) ;
262
+ let read = self . read_to_vec ( target, max) ?;
263
+ if read == 0 {
264
+ return Err ( ProtobufError :: WireError ( WireError :: TruncatedMessage ) ) ;
265
+ }
266
+ }
267
+ } else {
268
+ target. reserve_exact ( count) ;
269
+
270
+ unsafe {
271
+ self . read_exact ( & mut target. get_unchecked_mut ( ..count) ) ?;
272
+ target. set_len ( count) ;
273
+ }
274
+ }
275
+
276
+ debug_assert_eq ! ( count, target. len( ) ) ;
277
+
278
+ Ok ( ( ) )
279
+ }
280
+
224
281
#[ cfg( feature = "bytes" ) ]
225
282
pub fn read_exact_bytes ( & mut self , len : usize ) -> ProtobufResult < Bytes > {
226
283
if let InputSource :: Bytes ( bytes) = self . input_source {
@@ -231,15 +288,21 @@ impl<'ignore> BufReadIter<'ignore> {
231
288
self . pos_within_buf += len;
232
289
Ok ( r)
233
290
} else {
234
- let mut r = BytesMut :: with_capacity ( len) ;
235
- unsafe {
236
- {
237
- let mut buf = & mut r. bytes_mut ( ) [ ..len] ;
291
+ if len >= READ_RAW_BYTES_MAX_ALLOC {
292
+ // We cannot trust `len` because protobuf message could be malformed.
293
+ // Reading should not result in OOM when allocating a buffer.
294
+ let mut v = Vec :: new ( ) ;
295
+ self . read_exact_to_vec ( len, & mut v) ?;
296
+ Ok ( Bytes :: from ( v) )
297
+ } else {
298
+ let mut r = BytesMut :: with_capacity ( len) ;
299
+ unsafe {
300
+ let buf = & mut r. bytes_mut ( ) [ ..len] ;
238
301
self . read_exact ( buf) ?;
302
+ r. advance_mut ( len) ;
239
303
}
240
- r . advance_mut ( len ) ;
304
+ Ok ( r . freeze ( ) )
241
305
}
242
- Ok ( r. freeze ( ) )
243
306
}
244
307
}
245
308
0 commit comments