Skip to content

Commit 986d94d

Browse files
committed
Plug leak on init panic
1 parent 3f01453 commit 986d94d

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

crates/slice-dst/src/lib.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ use core::slice::from_raw_parts_mut as slice_from_raw_parts;
9696
use erasable::{Erasable, ErasedPtr};
9797
use {
9898
alloc::{
99-
alloc::{alloc, handle_alloc_error},
99+
alloc::{alloc, dealloc, handle_alloc_error},
100100
boxed::Box,
101101
},
102102
core::{alloc::Layout, mem::ManuallyDrop, ptr, slice},
@@ -198,9 +198,31 @@ unsafe impl<S: ?Sized + SliceDst> AllocSliceDst<S> for Box<S> {
198198
where
199199
I: FnOnce(ptr::NonNull<S>),
200200
{
201-
let ptr = alloc_slice_dst(len);
202-
init(ptr);
203-
Box::from_raw(ptr.as_ptr())
201+
struct RawBox<S: ?Sized + SliceDst>(ptr::NonNull<S>, Layout);
202+
203+
impl<S: ?Sized + SliceDst> RawBox<S> {
204+
unsafe fn new(len: usize) -> Self {
205+
let layout = S::layout_for(len);
206+
RawBox(alloc_slice_dst(len), layout)
207+
}
208+
209+
unsafe fn finalize(self) -> Box<S> {
210+
let this = ManuallyDrop::new(self);
211+
Box::from_raw(this.0.as_ptr())
212+
}
213+
}
214+
215+
impl<S: ?Sized + SliceDst> Drop for RawBox<S> {
216+
fn drop(&mut self) {
217+
unsafe {
218+
dealloc(self.0.as_ptr().cast(), self.1);
219+
}
220+
}
221+
}
222+
223+
let ptr = RawBox::new(len);
224+
init(ptr.0);
225+
ptr.finalize()
204226
}
205227
}
206228

0 commit comments

Comments
 (0)