@@ -430,6 +430,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
430
430
loop {
431
431
match r. read ( & mut probe) {
432
432
Ok ( n) => {
433
+ buf. try_reserve ( n) . map_err ( |_| io:: ErrorKind :: OutOfMemory ) ?;
433
434
buf. extend_from_slice ( & probe[ ..n] ) ;
434
435
return Ok ( n) ;
435
436
}
@@ -462,7 +463,8 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
462
463
}
463
464
464
465
if buf. len ( ) == buf. capacity ( ) {
465
- buf. reserve ( PROBE_SIZE ) ; // buf is full, need more space
466
+ // buf is full, need more space
467
+ buf. try_reserve ( PROBE_SIZE ) . map_err ( |_| ErrorKind :: OutOfMemory ) ?;
466
468
}
467
469
468
470
let mut spare = buf. spare_capacity_mut ( ) ;
@@ -815,6 +817,30 @@ pub trait Read {
815
817
/// file.)
816
818
///
817
819
/// [`std::fs::read`]: crate::fs::read
820
+ ///
821
+ /// ## Implementing `read_to_end`
822
+ ///
823
+ /// When implementing the `io::Read` trait, it is recommended to allocate
824
+ /// memory using [`Vec::try_reserve`]. However, this behavior is not guaranteed
825
+ /// by all implementations, and `read_to_end` may not handle out-of-memory
826
+ /// situations gracefully.
827
+ ///
828
+ /// ```no_run
829
+ /// # use std::io;
830
+ /// # struct Example; impl Example {
831
+ /// # fn read_some_data_for_the_example(&self) -> &'static [u8] { &[] }
832
+ /// fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
833
+ /// let data_read = self.read_some_data_for_the_example();
834
+ ///
835
+ /// buf.try_reserve(data_read.len()).map_err(|_| io::ErrorKind::OutOfMemory)?;
836
+ /// buf.extend_from_slice(data_read);
837
+ ///
838
+ /// Ok(data_read.len())
839
+ /// }
840
+ /// # }
841
+ /// ```
842
+ ///
843
+ /// [`Vec::try_reserve`]: crate::vec::Vec::try_reserve
818
844
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
819
845
fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> Result < usize > {
820
846
default_read_to_end ( self , buf, None )
0 commit comments