Skip to content

Commit 5254770

Browse files
committed
Handle OOM when writing to Vec
1 parent 1f880d9 commit 5254770

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

library/std/src/io/cursor.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ fn reserve_and_pad<A: Allocator>(
481481
// to have room for (pos+buf_len) bytes. Reserve allocates
482482
// based on additional elements from the length, so we need to
483483
// reserve the difference
484-
vec.reserve(desired_cap - vec.len());
484+
vec.try_reserve(desired_cap - vec.len())?;
485485
}
486486
// Pad if pos is above the current len.
487487
if pos > vec.len() {
@@ -511,7 +511,8 @@ unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8
511511
where
512512
A: Allocator,
513513
{
514-
debug_assert!(vec.capacity() >= pos + buf.len());
514+
debug_assert!(pos <= vec.capacity());
515+
debug_assert!(buf.len() <= vec.capacity() - pos);
515516
unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
516517
pos + buf.len()
517518
}
@@ -565,7 +566,7 @@ where
565566
A: Allocator,
566567
{
567568
// For safety reasons, we don't want this sum to overflow ever.
568-
// If this saturates, the reserve should panic to avoid any unsound writing.
569+
// If this saturates, the reserve will fail, which will avoid any unsound writing.
569570
let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
570571
let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
571572

library/std/src/io/impls.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,14 +480,15 @@ impl Write for &mut [u8] {
480480
impl<A: Allocator> Write for Vec<u8, A> {
481481
#[inline]
482482
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
483+
self.try_reserve(buf.len())?;
483484
self.extend_from_slice(buf);
484485
Ok(buf.len())
485486
}
486487

487488
#[inline]
488489
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
489490
let len = bufs.iter().map(|b| b.len()).sum();
490-
self.reserve(len);
491+
self.try_reserve(len)?;
491492
for buf in bufs {
492493
self.extend_from_slice(buf);
493494
}
@@ -501,6 +502,7 @@ impl<A: Allocator> Write for Vec<u8, A> {
501502

502503
#[inline]
503504
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
505+
self.try_reserve(buf.len())?;
504506
self.extend_from_slice(buf);
505507
Ok(())
506508
}

0 commit comments

Comments
 (0)