@@ -418,7 +418,8 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
418
418
let mut initialized = 0 ; // Extra initialized bytes from previous loop iteration
419
419
loop {
420
420
if buf. len ( ) == buf. capacity ( ) {
421
- buf. reserve ( 32 ) ; // buf is full, need more space
421
+ // buf is full, need more space
422
+ buf. try_reserve ( 32 ) . map_err ( |_| ErrorKind :: OutOfMemory ) ?;
422
423
}
423
424
424
425
let mut spare = buf. spare_capacity_mut ( ) ;
@@ -464,6 +465,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
464
465
match r. read ( & mut probe) {
465
466
Ok ( 0 ) => return Ok ( buf. len ( ) - start_len) ,
466
467
Ok ( n) => {
468
+ buf. try_reserve ( n) . map_err ( |_| ErrorKind :: OutOfMemory ) ?;
467
469
buf. extend_from_slice ( & probe[ ..n] ) ;
468
470
break ;
469
471
}
@@ -767,6 +769,30 @@ pub trait Read {
767
769
/// file.)
768
770
///
769
771
/// [`std::fs::read`]: crate::fs::read
772
+ ///
773
+ /// ## Implementing `read_to_end`
774
+ ///
775
+ /// When implementing the `io::Read` trait, it is recommended to allocate
776
+ /// memory using [`Vec::try_reserve`]. However, this behavior is not guaranteed
777
+ /// by all implementations, and `read_to_end` may not handle out-of-memory
778
+ /// situations gracefully.
779
+ ///
780
+ /// ```no_run
781
+ /// # use std::io;
782
+ /// # struct Example; impl Example {
783
+ /// # fn read_some_data_for_the_example(&self) -> &'static [u8] { &[] }
784
+ /// fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
785
+ /// let data_read = self.read_some_data_for_the_example();
786
+ ///
787
+ /// buf.try_reserve(data_read.len()).map_err(|_| io::ErrorKind::OutOfMemory)?;
788
+ /// buf.extend_from_slice(data_read);
789
+ ///
790
+ /// Ok(data_read.len())
791
+ /// }
792
+ /// # }
793
+ /// ```
794
+ ///
795
+ /// [`Vec::try_reserve`]: crate::vec::Vec::try_reserve
770
796
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
771
797
fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> Result < usize > {
772
798
default_read_to_end ( self , buf, None )
0 commit comments