mirror of
https://github.com/Lokathor/bytemuck.git
synced 2024-11-21 14:22:26 +00:00
Fix UB when dropping BoxBytes owning a zero-sized layout (#258)
This commit is contained in:
parent
005ee3254f
commit
1c75146bb6
@ -742,8 +742,9 @@ impl<I: ?Sized, T: ?Sized + TransparentWrapper<I>> TransparentWrapperAlloc<I>
|
||||
|
||||
/// As `Box<[u8]>`, but remembers the original alignment.
|
||||
pub struct BoxBytes {
|
||||
// SAFETY: `ptr` is owned, was allocated with `layout`, and points to
|
||||
// `layout.size()` initialized bytes.
|
||||
// SAFETY: `ptr` is owned, points to `layout.size()` initialized bytes, and
|
||||
// was allocated with `layout` (unless `layout.size() == 0` in which case it
|
||||
// is dangling).
|
||||
ptr: NonNull<u8>,
|
||||
layout: Layout,
|
||||
}
|
||||
@ -770,8 +771,11 @@ impl DerefMut for BoxBytes {
|
||||
|
||||
impl Drop for BoxBytes {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: See type invariant.
|
||||
unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), self.layout) };
|
||||
if self.layout.size() != 0 {
|
||||
// SAFETY: See type invariant: if `self.layout.size() != 0`, then
|
||||
// `self.ptr` is owned and was allocated with `self.layout`.
|
||||
unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), self.layout) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,3 +328,17 @@ fn test_arc_slices() {
|
||||
let empty: Arc<[i8]> = cast_slice_arc::<(), i8>(Arc::new([(); 42]));
|
||||
assert!(empty.is_empty());
|
||||
}
|
||||
|
||||
#[cfg(feature = "extern_crate_alloc")]
|
||||
#[test]
|
||||
fn box_bytes_zst() {
|
||||
let x: BoxBytes = box_bytes_of(Box::new([0u8; 0]));
|
||||
let _: Box<[u8]> = from_box_bytes(x);
|
||||
|
||||
let x: BoxBytes = box_bytes_of(Box::new([0u8; 0]));
|
||||
let res: Result<Box<[()]>, _> = try_from_box_bytes(x);
|
||||
assert_eq!(res.unwrap_err().0, PodCastError::SizeMismatch);
|
||||
|
||||
let x: BoxBytes = box_bytes_of(Box::new([(); 0]));
|
||||
let _: Box<[u8]> = from_box_bytes(x);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user