@@ -377,18 +377,28 @@ impl Write for &mut [u8] {
377
377
378
378
/// Write is implemented for `Vec<u8>` by appending to the vector.
379
379
/// The vector will grow as needed.
380
+ ///
381
+ /// # Panics
382
+ ///
383
+ /// In case of allocation error or capacity overflow, write operations will panic.
384
+ /// The panicking behavior is not guaranteed. In the future, it may become
385
+ /// a regular `io::Error`.
380
386
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
381
387
impl < A : Allocator > Write for Vec < u8 , A > {
382
388
#[ inline]
383
389
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
390
+ fallible_reserve ( self , buf. len ( ) ) ;
384
391
self . extend_from_slice ( buf) ;
385
392
Ok ( buf. len ( ) )
386
393
}
387
394
388
395
#[ inline]
389
396
fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
390
- let len = bufs. iter ( ) . map ( |b| b. len ( ) ) . sum ( ) ;
391
- self . reserve ( len) ;
397
+ let len = bufs
398
+ . iter ( )
399
+ . try_fold ( 0usize , |len, b| len. checked_add ( b. len ( ) ) )
400
+ . expect ( "capacity overflow" ) ;
401
+ fallible_reserve ( self , len) ;
392
402
for buf in bufs {
393
403
self . extend_from_slice ( buf) ;
394
404
}
@@ -402,6 +412,7 @@ impl<A: Allocator> Write for Vec<u8, A> {
402
412
403
413
#[ inline]
404
414
fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
415
+ fallible_reserve ( self , buf. len ( ) ) ;
405
416
self . extend_from_slice ( buf) ;
406
417
Ok ( ( ) )
407
418
}
@@ -412,6 +423,20 @@ impl<A: Allocator> Write for Vec<u8, A> {
412
423
}
413
424
}
414
425
426
+ #[ inline]
427
+ fn fallible_reserve < T , A : Allocator > ( vec : & mut Vec < T , A > , len : usize ) {
428
+ if len > vec. capacity ( ) . wrapping_sub ( vec. len ( ) ) {
429
+ do_reserve_and_handle ( vec, len) ;
430
+ }
431
+ }
432
+
433
+ #[ cold]
434
+ fn do_reserve_and_handle < T , A : Allocator > ( vec : & mut Vec < T , A > , len : usize ) {
435
+ if let Err ( _) = vec. try_reserve ( len) {
436
+ panic ! ( "out of memory" ) ;
437
+ }
438
+ }
439
+
415
440
/// Read is implemented for `VecDeque<u8>` by consuming bytes from the front of the `VecDeque`.
416
441
#[ stable( feature = "vecdeque_read_write" , since = "1.63.0" ) ]
417
442
impl < A : Allocator > Read for VecDeque < u8 , A > {
0 commit comments