Skip to content

Commit 62da957

Browse files
authored
Rollup merge of #125123 - a1phyr:fix-read_exact, r=workingjubilee
Fix `read_exact` and `read_buf_exact` for `&[u8]` and `io:Cursor` - Drain after `read_exact` and `read_buf_exact` - Append to cursor in `read_buf_exact`
2 parents e275d2d + a197ff3 commit 62da957

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

library/std/src/io/cursor.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ where
328328
fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
329329
let prev_written = cursor.written();
330330

331-
Read::read_buf(&mut self.fill_buf()?, cursor.reborrow())?;
331+
Read::read_buf(&mut self.remaining_slice(), cursor.reborrow())?;
332332

333333
self.pos += (cursor.written() - prev_written) as u64;
334334

@@ -352,17 +352,24 @@ where
352352
}
353353

354354
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
355-
let n = buf.len();
356-
Read::read_exact(&mut self.remaining_slice(), buf)?;
357-
self.pos += n as u64;
358-
Ok(())
355+
let result = Read::read_exact(&mut self.remaining_slice(), buf);
356+
357+
match result {
358+
Ok(_) => self.pos += buf.len() as u64,
359+
// The only possible error condition is EOF, so place the cursor at "EOF"
360+
Err(_) => self.pos = self.inner.as_ref().len() as u64,
361+
}
362+
363+
result
359364
}
360365

361-
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
362-
let n = cursor.capacity();
363-
Read::read_buf_exact(&mut self.remaining_slice(), cursor)?;
364-
self.pos += n as u64;
365-
Ok(())
366+
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
367+
let prev_written = cursor.written();
368+
369+
let result = Read::read_buf_exact(&mut self.remaining_slice(), cursor.reborrow());
370+
self.pos += (cursor.written() - prev_written) as u64;
371+
372+
result
366373
}
367374

368375
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {

library/std/src/io/impls.rs

+6
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ impl Read for &[u8] {
287287
#[inline]
288288
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
289289
if buf.len() > self.len() {
290+
// `read_exact` makes no promise about the content of `buf` if it
291+
// fails so don't bother about that.
292+
*self = &self[self.len()..];
290293
return Err(io::Error::READ_EXACT_EOF);
291294
}
292295
let (a, b) = self.split_at(buf.len());
@@ -307,6 +310,9 @@ impl Read for &[u8] {
307310
#[inline]
308311
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
309312
if cursor.capacity() > self.len() {
313+
// Append everything we can to the cursor.
314+
cursor.append(*self);
315+
*self = &self[self.len()..];
310316
return Err(io::Error::READ_EXACT_EOF);
311317
}
312318
let (a, b) = self.split_at(cursor.capacity());

library/std/src/io/tests.rs

+32
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,38 @@ fn test_take_wrong_length() {
653653
let _ = reader.read(&mut buffer[..]);
654654
}
655655

656+
#[test]
657+
fn slice_read_exact_eof() {
658+
let slice = &b"123456"[..];
659+
660+
let mut r = slice;
661+
assert!(r.read_exact(&mut [0; 10]).is_err());
662+
assert!(r.is_empty());
663+
664+
let mut r = slice;
665+
let buf = &mut [0; 10];
666+
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
667+
assert!(r.read_buf_exact(buf.unfilled()).is_err());
668+
assert!(r.is_empty());
669+
assert_eq!(buf.filled(), b"123456");
670+
}
671+
672+
#[test]
673+
fn cursor_read_exact_eof() {
674+
let slice = Cursor::new(b"123456");
675+
676+
let mut r = slice.clone();
677+
assert!(r.read_exact(&mut [0; 10]).is_err());
678+
assert!(r.is_empty());
679+
680+
let mut r = slice;
681+
let buf = &mut [0; 10];
682+
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
683+
assert!(r.read_buf_exact(buf.unfilled()).is_err());
684+
assert!(r.is_empty());
685+
assert_eq!(buf.filled(), b"123456");
686+
}
687+
656688
#[bench]
657689
fn bench_take_read(b: &mut test::Bencher) {
658690
b.iter(|| {

0 commit comments

Comments
 (0)