about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe 8472 <git@infinite-source.de>2023-11-04 12:09:27 +0100
committerThe 8472 <git@infinite-source.de>2023-11-04 16:11:01 +0100
commit78aa5e511c0b205a742edffd48533670579ec247 (patch)
treefb7d709a6bcac7044c20b023d8454dfa1f48912d
parent8d8f06b277a12e19189d6b08dbd9893db3283e9d (diff)
downloadrust-78aa5e511c0b205a742edffd48533670579ec247.tar.gz
rust-78aa5e511c0b205a742edffd48533670579ec247.zip
detect EOF earlier
The initial probe-for-empty-source by stack_buffer_copy only detected EOF
if the source was empty but not when it was merely small which lead to
additional calls to read() after Ok(0) had already been returned
in the stack copy routine
-rw-r--r--library/std/src/io/copy.rs12
1 files changed, 7 insertions, 5 deletions
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index e05ec9bde24..4d51a719f6c 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -264,11 +264,13 @@ impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
     fn copy_from<R: Read + ?Sized>(&mut self, reader: &mut R) -> Result<u64> {
         let mut bytes = 0;
 
-        // avoid allocating before we have determined that there's anything to read
-        if self.capacity() == 0 {
-            bytes = stack_buffer_copy(&mut reader.take(DEFAULT_BUF_SIZE as u64), self)?;
-            if bytes == 0 {
-                return Ok(0);
+        // avoid inflating empty/small vecs before we have determined that there's anything to read
+        if self.capacity() < DEFAULT_BUF_SIZE {
+            let stack_read_limit = DEFAULT_BUF_SIZE as u64;
+            bytes = stack_buffer_copy(&mut reader.take(stack_read_limit), self)?;
+            // fewer bytes than requested -> EOF reached
+            if bytes < stack_read_limit {
+                return Ok(bytes);
             }
         }