Fixes dropping empty BlobVec (#2295)

When dropping the data, we originally only checked the size of an individual item instead of the size of the allocation. However with a capacity of 0, we attempt to deallocate a pointer which was not the result of allocation. That is, an item of `Layout { size_: 8, align_: 8 }` produces an array of `Layout { size_: 0, align_: 8 }` when `capacity = 0`.

Fixes #2294
This commit is contained in:
thebluefish 2021-06-02 19:08:39 +00:00
parent 6301b728ea
commit f45dbe5bac

View file

@ -199,13 +199,11 @@ impl BlobVec {
impl Drop for BlobVec {
fn drop(&mut self) {
self.clear();
if self.item_layout.size() > 0 {
let array_layout =
array_layout(&self.item_layout, self.capacity).expect("array layout should be valid");
if array_layout.size() > 0 {
unsafe {
std::alloc::dealloc(
self.get_ptr().as_ptr(),
array_layout(&self.item_layout, self.capacity)
.expect("array layout should be valid"),
);
std::alloc::dealloc(self.get_ptr().as_ptr(), array_layout);
std::alloc::dealloc(self.swap_scratch.as_ptr(), self.item_layout);
}
}
@ -388,4 +386,11 @@ mod tests {
assert_eq!(*drop_counter.borrow(), 6);
}
#[test]
fn blob_vec_drop_empty_capacity() {
let item_layout = Layout::new::<Foo>();
let drop = TypeInfo::drop_ptr::<Foo>;
let _ = BlobVec::new(item_layout, drop, 0);
}
}