Skip to content

Commit

Permalink
io: fix unsound Buf::ensure_capacity_for
Browse files Browse the repository at this point in the history
  • Loading branch information
paolobarbolini committed Dec 29, 2024
1 parent 4ca13e6 commit e64152a
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions tokio/src/io/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(crate) struct Blocking<T> {
pub(crate) struct Buf {
buf: Vec<u8>,
pos: usize,
init_len: usize,
}

pub(crate) const DEFAULT_MAX_BUF_SIZE: usize = 2 * 1024 * 1024;
Expand Down Expand Up @@ -190,6 +191,7 @@ impl Buf {
Buf {
buf: Vec::with_capacity(n),
pos: 0,
init_len: 0,
}
}

Expand Down Expand Up @@ -220,6 +222,7 @@ impl Buf {
let n = cmp::min(src.len(), max_buf_size);

self.buf.extend_from_slice(&src[..n]);
self.init_len = cmp::max(self.init_len, self.buf.len());
n
}

Expand All @@ -236,6 +239,18 @@ impl Buf {
self.buf.reserve(len - self.buf.len());
}

if self.init_len < len {
debug_assert!(self.init_len < self.buf.capacity(), "init_len of Vec is bigger than the capacity");
debug_assert!(len <= self.buf.capacity(), "uninit area of Vec is bigger than the capacity");

let uninit_len = len - self.init_len;
// SAFETY: the area is within the allocation of the Vec
unsafe {
self.buf.as_mut_ptr().add(self.init_len).write_bytes(0, uninit_len);
}
}

// SAFETY: `len` is within the capacity and is init
unsafe {
self.buf.set_len(len);
}
Expand Down Expand Up @@ -287,6 +302,7 @@ cfg_fs! {
self.buf.extend_from_slice(&buf[..len]);
rem -= len;
}
self.init_len = cmp::max(self.init_len, self.buf.len());

max_buf_size - rem
}
Expand Down

0 comments on commit e64152a

Please sign in to comment.