diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index f6a11b005285d..97fea65853630 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -477,13 +477,14 @@ pub(crate) fn default_read_to_end( } let mut cursor = read_buf.unfilled(); - loop { + let result = loop { match r.read_buf(cursor.reborrow()) { - Ok(()) => break, Err(e) if e.is_interrupted() => continue, - Err(e) => return Err(e), + // Do not stop now in case of error: we might have received both data + // and an error + res => break res, } - } + }; let unfilled_but_initialized = cursor.init_ref().len(); let bytes_read = cursor.written(); @@ -493,15 +494,18 @@ pub(crate) fn default_read_to_end( return Ok(buf.len() - start_len); } - // store how much was initialized but not filled - initialized = unfilled_but_initialized; - // SAFETY: BorrowedBuf's invariants mean this much memory is initialized. unsafe { let new_len = bytes_read + buf.len(); buf.set_len(new_len); } + // Now that all data is pushed to the vector, we can fail without data loss + result?; + + // store how much was initialized but not filled + initialized = unfilled_but_initialized; + // Use heuristics to determine the max read size if no initial size hint was provided if size_hint.is_none() { // The reader is returning short reads but it doesn't call ensure_init().