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 { impl Drop for BlobVec {
fn drop(&mut self) { fn drop(&mut self) {
self.clear(); 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 { unsafe {
std::alloc::dealloc( std::alloc::dealloc(self.get_ptr().as_ptr(), array_layout);
self.get_ptr().as_ptr(),
array_layout(&self.item_layout, self.capacity)
.expect("array layout should be valid"),
);
std::alloc::dealloc(self.swap_scratch.as_ptr(), self.item_layout); std::alloc::dealloc(self.swap_scratch.as_ptr(), self.item_layout);
} }
} }
@ -388,4 +386,11 @@ mod tests {
assert_eq!(*drop_counter.borrow(), 6); 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);
}
} }