@@ -430,6 +430,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
430430 loop {
431431 match r. read ( & mut probe) {
432432 Ok ( n) => {
433+ buf. try_reserve ( n) . map_err ( |_| io:: ErrorKind :: OutOfMemory ) ?;
433434 buf. extend_from_slice ( & probe[ ..n] ) ;
434435 return Ok ( n) ;
435436 }
@@ -462,7 +463,8 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
462463 }
463464
464465 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 ) ?;
466468 }
467469
468470 let mut spare = buf. spare_capacity_mut ( ) ;
@@ -815,6 +817,30 @@ pub trait Read {
815817 /// file.)
816818 ///
817819 /// [`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
818844 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
819845 fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> Result < usize > {
820846 default_read_to_end ( self , buf, None )
0 commit comments