Skip to content

Commit

Permalink
protect std::io::Take::limit from overflow in read
Browse files Browse the repository at this point in the history
fixs #94981
  • Loading branch information
frank-king committed May 29, 2022
1 parent be52b4a commit 64ac045
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
1 change: 1 addition & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,7 @@ impl<T: Read> Read for Take<T> {

let max = cmp::min(buf.len() as u64, self.limit) as usize;
let n = self.inner.read(&mut buf[..max])?;
assert!(n as u64 <= self.limit, "number of read bytes exceeds limit");
self.limit -= n as u64;
Ok(n)
}
Expand Down
19 changes: 19 additions & 0 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,25 @@ fn test_write_all_vectored() {
}
}

// Issue 94981
#[test]
#[should_panic = "number of read bytes exceeds limit"]
fn test_take_wrong_length() {
struct LieAboutSize(bool);

impl Read for LieAboutSize {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// Lie about the read size at first time of read.
if core::mem::take(&mut self.0) { Ok(buf.len() + 1) } else { Ok(buf.len()) }
}
}

let mut buffer = vec![0; 4];
let mut reader = LieAboutSize(true).take(4);
// Primed the `Limit` by lying about the read size.
let _ = reader.read(&mut buffer[..]);
}

#[bench]
fn bench_take_read(b: &mut test::Bencher) {
b.iter(|| {
Expand Down

0 comments on commit 64ac045

Please sign in to comment.