Skip to content

Commit 5c906ab

Browse files
authored
Unrolled build for #120607
Rollup merge of #120607 - conradludgate:fix-120603, r=dtolnay fix #120603 by adding a check in default_read_buf Fixes #120603 by checking the returned read n is in-bounds of the cursor. Interestingly, I noticed that `BorrowedBuf` side-steps this issue by using checked accesses. Maybe this can be switched to unchecked to mirror what BufReader does https://github.com/rust-lang/rust/blob/bf3c6c5bed498f41ad815641319a1ad9bcecb8e8/library/core/src/io/borrowed_buf.rs#L95
2 parents 0984bec + 4c694db commit 5c906ab

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

library/std/src/io/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,13 @@ where
578578
F: FnOnce(&mut [u8]) -> Result<usize>,
579579
{
580580
let n = read(cursor.ensure_init().init_mut())?;
581+
assert!(
582+
n <= cursor.capacity(),
583+
"read should not return more bytes than there is capacity for in the read buffer"
584+
);
581585
unsafe {
582-
// SAFETY: we initialised using `ensure_init` so there is no uninit data to advance to.
586+
// SAFETY: we initialised using `ensure_init` so there is no uninit data to advance to
587+
// and we have checked that the read amount is not over capacity (see #120603)
583588
cursor.advance(n);
584589
}
585590
Ok(())

library/std/src/io/tests.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{repeat, BorrowedBuf, Cursor, SeekFrom};
22
use crate::cmp::{self, min};
3-
use crate::io::{self, IoSlice, IoSliceMut};
3+
use crate::io::{self, IoSlice, IoSliceMut, DEFAULT_BUF_SIZE};
44
use crate::io::{BufRead, BufReader, Read, Seek, Write};
55
use crate::mem::MaybeUninit;
66
use crate::ops::Deref;
@@ -652,3 +652,32 @@ fn bench_take_read_buf(b: &mut test::Bencher) {
652652
[255; 128].take(64).read_buf(buf.unfilled()).unwrap();
653653
});
654654
}
655+
656+
// Issue #120603
657+
#[test]
658+
#[should_panic = "read should not return more bytes than there is capacity for in the read buffer"]
659+
fn read_buf_broken_read() {
660+
struct MalformedRead;
661+
662+
impl Read for MalformedRead {
663+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
664+
// broken length calculation
665+
Ok(buf.len() + 1)
666+
}
667+
}
668+
669+
let _ = BufReader::new(MalformedRead).fill_buf();
670+
}
671+
672+
#[test]
673+
fn read_buf_full_read() {
674+
struct FullRead;
675+
676+
impl Read for FullRead {
677+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
678+
Ok(buf.len())
679+
}
680+
}
681+
682+
assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE);
683+
}

0 commit comments

Comments
 (0)