Skip to content

Commit e8b74f3

Browse files
committed
fix bug in ByteBuffer::grow
1 parent b6b117a commit e8b74f3

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

crates/core/src/memory/buffer.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,18 @@ impl ByteBuffer {
130130
}
131131

132132
/// Grow the byte buffer to the given `new_size` when backed by a [`Vec`].
133-
fn grow_vec(&mut self, mut vec: Vec<u8>, new_size: usize) -> Result<(), MemoryError> {
133+
fn grow_vec(
134+
&mut self,
135+
mut vec: ManuallyDrop<Vec<u8>>,
136+
new_size: usize,
137+
) -> Result<(), MemoryError> {
134138
debug_assert!(vec.len() <= new_size);
135139
let additional = new_size - vec.len();
136140
if vec.try_reserve(additional).is_err() {
137141
return Err(MemoryError::OutOfSystemMemory);
138142
};
139143
vec.resize(new_size, 0x00_u8);
140-
(self.ptr, self.len, self.capacity) = vec_into_raw_parts(vec);
144+
(self.ptr, self.len, self.capacity) = vec_into_raw_parts(ManuallyDrop::into_inner(vec));
141145
Ok(())
142146
}
143147

@@ -181,16 +185,21 @@ impl ByteBuffer {
181185
///
182186
/// # Note
183187
///
184-
/// The returned `Vec` will free its memory and thus the memory of the [`ByteBuffer`] if dropped.
185-
fn get_vec(&mut self) -> Option<Vec<u8>> {
188+
/// - The returned `Vec` will free its memory and thus the memory of the [`ByteBuffer`] if dropped.
189+
/// - The returned `Vec` is returned as [`ManuallyDrop`] to prevent its buffer from being freed
190+
/// automatically upon going out of scope.
191+
fn get_vec(&mut self) -> Option<ManuallyDrop<Vec<u8>>> {
186192
if self.is_static {
187193
return None;
188194
}
189195
// Safety
190196
//
191197
// - At this point we are guaranteed that the byte buffer is backed by a `Vec`
192198
// so it is safe to reconstruct the `Vec` by its raw parts.
193-
Some(unsafe { Vec::from_raw_parts(self.ptr, self.len, self.capacity) })
199+
// - The returned `Vec` is returned as [`ManuallyDrop`] to prevent its buffer from being free
200+
// upon going out of scope.
201+
let vec = unsafe { Vec::from_raw_parts(self.ptr, self.len, self.capacity) };
202+
Some(ManuallyDrop::new(vec))
194203
}
195204
}
196205

0 commit comments

Comments
 (0)