Skip to content

Commit c751aef

Browse files
committed
Fix io::default_read_to_end uses of read_buf
1 parent 09584e8 commit c751aef

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

library/std/src/io/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -474,13 +474,14 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
474474
}
475475

476476
let mut cursor = read_buf.unfilled();
477-
loop {
477+
let result = loop {
478478
match r.read_buf(cursor.reborrow()) {
479-
Ok(()) => break,
480479
Err(e) if e.is_interrupted() => continue,
481-
Err(e) => return Err(e),
480+
// Do not stop now in case of error: we might have received both data
481+
// and an error
482+
res => break res,
482483
}
483-
}
484+
};
484485

485486
let unfilled_but_initialized = cursor.init_ref().len();
486487
let bytes_read = cursor.written();
@@ -496,15 +497,18 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
496497
consecutive_short_reads = 0;
497498
}
498499

499-
// store how much was initialized but not filled
500-
initialized = unfilled_but_initialized;
501-
502500
// SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
503501
unsafe {
504502
let new_len = bytes_read + buf.len();
505503
buf.set_len(new_len);
506504
}
507505

506+
// Now that all data is pushed to the vector, we can fail without data loss
507+
result?;
508+
509+
// store how much was initialized but not filled
510+
initialized = unfilled_but_initialized;
511+
508512
// Use heuristics to determine the max read size if no initial size hint was provided
509513
if size_hint.is_none() {
510514
// The reader is returning short reads but it doesn't call ensure_init().

0 commit comments

Comments
 (0)