From 525477048989c3aee6b5bdf952e9373cd833e401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Tue, 4 Nov 2025 11:55:43 +0100 Subject: [PATCH] Handle OOM when writing to `Vec` --- library/std/src/io/cursor.rs | 7 ++++--- library/std/src/io/impls.rs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index d7131e2fe92fd..ba39e64169d93 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -481,7 +481,7 @@ fn reserve_and_pad( // to have room for (pos+buf_len) bytes. Reserve allocates // based on additional elements from the length, so we need to // reserve the difference - vec.reserve(desired_cap - vec.len()); + vec.try_reserve(desired_cap - vec.len())?; } // Pad if pos is above the current len. if pos > vec.len() { @@ -511,7 +511,8 @@ unsafe fn vec_write_all_unchecked(pos: usize, vec: &mut Vec, buf: &[u8 where A: Allocator, { - debug_assert!(vec.capacity() >= pos + buf.len()); + debug_assert!(pos <= vec.capacity()); + debug_assert!(buf.len() <= vec.capacity() - pos); unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) }; pos + buf.len() } @@ -565,7 +566,7 @@ where A: Allocator, { // For safety reasons, we don't want this sum to overflow ever. - // If this saturates, the reserve should panic to avoid any unsound writing. + // If this saturates, the reserve will fail, which will avoid any unsound writing. let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len())); let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?; diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index d0245f3d4984c..710d3100c5c15 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -480,6 +480,7 @@ impl Write for &mut [u8] { impl Write for Vec { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { + self.try_reserve(buf.len())?; self.extend_from_slice(buf); Ok(buf.len()) } @@ -487,7 +488,7 @@ impl Write for Vec { #[inline] fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { let len = bufs.iter().map(|b| b.len()).sum(); - self.reserve(len); + self.try_reserve(len)?; for buf in bufs { self.extend_from_slice(buf); } @@ -501,6 +502,7 @@ impl Write for Vec { #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.try_reserve(buf.len())?; self.extend_from_slice(buf); Ok(()) }