From c9287674fb6ac063e77adf9880719ea057777d45 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 29 Jan 2024 16:50:18 +0000 Subject: [PATCH] default_read_to_end can't try_reserve probe reads --- library/std/src/io/mod.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 97fd6564abbd7..46fb0822c961c 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -430,6 +430,8 @@ pub(crate) fn default_read_to_end( loop { match r.read(&mut probe) { Ok(n) => { + // there is no way to recover from allocation failure here + // because the data has already been read. buf.extend_from_slice(&probe[..n]); return Ok(n); } @@ -826,15 +828,23 @@ pub trait Read { /// /// ```no_run /// # use std::io; - /// # struct Example; impl Example { - /// # fn read_some_data_for_the_example(&self) -> &'static [u8] { &[] } - /// fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - /// let data_read = self.read_some_data_for_the_example(); - /// - /// buf.try_reserve(data_read.len()).map_err(|_| io::ErrorKind::OutOfMemory)?; - /// buf.extend_from_slice(data_read); - /// - /// Ok(data_read.len()) + /// # struct Example { example_datasource: io::Empty } impl Example { + /// # fn get_some_data_for_the_example(&self) -> &'static [u8] { &[] } + /// fn read_to_end(&mut self, dest_vec: &mut Vec) -> io::Result { + /// let initial_vec_len = dest_vec.len(); + /// loop { + /// let src_buf = self.example_datasource.fill_buf()?; + /// if src_buf.is_empty() { + /// break; + /// } + /// dest_vec.try_reserve(src_buf.len()).map_err(|_| io::ErrorKind::OutOfMemory)?; + /// dest_vec.extend_from_slice(src_buf); + /// + /// // Any irreversible side effects should happen after `try_reserve` succeeds, + /// // to avoid losing data on allocation error. + /// self.example_datasource.consume(src_buf.len()); + /// } + /// Ok(dest_vec.len() - initial_vec_len) /// } /// # } /// ```