Skip to content

Commit

Permalink
Rollup merge of rust-lang#130042 - lolbinarycat:bufreaker_peek_eof, r…
Browse files Browse the repository at this point in the history
…=Amanieu

properly handle EOF in BufReader::peek

previously this would cause an infinite loop due to it being unable to read `n` bytes.
  • Loading branch information
Zalathar authored Sep 15, 2024
2 parents d38c59a + 335236c commit 09f1d40
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
12 changes: 10 additions & 2 deletions std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ impl<R: Read> BufReader<R> {
impl<R: Read + ?Sized> BufReader<R> {
/// 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
///
Expand All @@ -117,6 +120,7 @@ impl<R: Read + ?Sized> BufReader<R> {
/// 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]> {
Expand All @@ -125,7 +129,11 @@ impl<R: Read + ?Sized> BufReader<R> {
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])
Expand Down
4 changes: 2 additions & 2 deletions std/src/io/buffered/bufreader/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl Buffer {
}

/// 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<usize> {
let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]);
let old_init = self.initialized - self.pos;
unsafe {
Expand All @@ -107,7 +107,7 @@ impl Buffer {
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.
Expand Down

0 comments on commit 09f1d40

Please sign in to comment.