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 a2a4b8a
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 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,27 @@ 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 +311,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 a2a4b8a

Please sign in to comment.