diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2022-07-25 18:46:47 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-25 18:46:47 +0900 |
| commit | 0ecbcbb0ace4229f59e09de035ccef747b024e00 (patch) | |
| tree | e7fae9c81da63a062a316547669bdac59a968e4e | |
| parent | 7f93d4aa0dc4ac071c617e0e07d2758e3bb388f9 (diff) | |
| parent | 64ac04567ba397f8600952e3875b9a197f7b2910 (diff) | |
| download | rust-0ecbcbb0ace4229f59e09de035ccef747b024e00.tar.gz rust-0ecbcbb0ace4229f59e09de035ccef747b024e00.zip | |
Rollup merge of #95040 - frank-king:fix/94981, r=Mark-Simulacrum
protect `std::io::Take::limit` from overflow in `read` Resolves #94981
| -rw-r--r-- | library/std/src/io/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/io/tests.rs | 19 |
2 files changed, 20 insertions, 0 deletions
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index f4f2e3f2434..18f7f6a35e9 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -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) } diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index d5a8c93b0ce..f357f33ec52 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -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(|| { |
