From dfdbf6343ae1ea97b504b36ec1933e181ec7198e Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 6 Sep 2024 16:28:22 -0400 Subject: [PATCH] properly handle EOF in BufReader::peek previously this would cause an infinite loop due to it being unable to read `n` bytes. --- library/std/src/io/buffered/bufreader.rs | 12 ++++++++++-- library/std/src/io/buffered/bufreader/buffer.rs | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index cf226bd28d0..b69d7edb5a7 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -99,7 +99,10 @@ pub fn with_capacity(capacity: usize, inner: R) -> BufReader { impl BufReader { /// Attempt to look ahead `n` bytes. /// - /// `n` must be less than `capacity`. + /// `n` must be less than or equal to `capacity`. + /// + /// the returned slice may be less than `n` bytes long if + /// end of file is reached. /// /// ## Examples /// @@ -117,6 +120,7 @@ impl BufReader { /// let mut s = String::new(); /// rdr.read_to_string(&mut s).unwrap(); /// assert_eq!(&s, "hello"); + /// assert_eq!(rdr.peek(1).unwrap().len(), 0); /// ``` #[unstable(feature = "bufreader_peek", issue = "128405")] pub fn peek(&mut self, n: usize) -> io::Result<&[u8]> { @@ -125,7 +129,11 @@ pub fn peek(&mut self, n: usize) -> io::Result<&[u8]> { if self.buf.pos() > 0 { self.buf.backshift(); } - self.buf.read_more(&mut self.inner)?; + let new = self.buf.read_more(&mut self.inner)?; + if new == 0 { + // end of file, no more bytes to read + return Ok(&self.buf.buffer()[..]); + } debug_assert_eq!(self.buf.pos(), 0); } Ok(&self.buf.buffer()[..n]) diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index ccd67fafb45..1bf84d8bef3 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -98,7 +98,7 @@ pub fn unconsume(&mut self, amt: usize) { } /// Read more bytes into the buffer without discarding any of its contents - pub fn read_more(&mut self, mut reader: impl Read) -> io::Result<()> { + pub fn read_more(&mut self, mut reader: impl Read) -> io::Result { let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]); let old_init = self.initialized - self.pos; unsafe { @@ -107,7 +107,7 @@ pub fn read_more(&mut self, mut reader: impl Read) -> io::Result<()> { reader.read_buf(buf.unfilled())?; self.filled += buf.len(); self.initialized += buf.init_len() - old_init; - Ok(()) + Ok(buf.len()) } /// Remove bytes that have already been read from the buffer.