Skip to content

Commit 6e4f98c

Browse files
committed
don't leak items if alloc::shrink panics
1 parent 3ca6bb0 commit 6e4f98c

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

library/alloc/src/vec/in_place_collect.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,18 @@ where
225225
}
226226

227227
// The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`.
228-
// This is safe because `forget_allocation_drop_remaining` immediately forgets the allocation
228+
// This is safe because
229+
// * `forget_allocation_drop_remaining` immediately forgets the allocation
229230
// before any panic can occur in order to avoid any double free, and then proceeds to drop
230231
// any remaining values at the tail of the source.
232+
// * the shrink either panics without invalidating the allocation, aborts or
233+
// succeeds. In the last case we disarm the guard.
231234
//
232235
// Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
233236
// contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
234237
// module documentation why this is ok anyway.
235238
let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap: dst_cap };
236239
src.forget_allocation_drop_remaining();
237-
mem::forget(dst_guard);
238240

239241
// Adjust the allocation size if the source had a capacity in bytes that wasn't a multiple
240242
// of the destination type size.
@@ -256,6 +258,8 @@ where
256258
}
257259
}
258260

261+
mem::forget(dst_guard);
262+
259263
let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) };
260264

261265
vec

0 commit comments

Comments
 (0)