Rollup merge of #95040 - frank-king:fix/94981, r=Mark-Simulacrum

protect `std::io::Take::limit` from overflow in `read`

Resolves #94981
This commit is contained in:
Yuki Okushi 2022-07-25 18:46:47 +09:00 committed by GitHub
commit 0ecbcbb0ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 0 deletions

View file

@ -2577,6 +2577,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)
}

View file

@ -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(|| {