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.
|
/// As `Box<[u8]>`, but remembers the original alignment.
|
||||||
pub struct BoxBytes {
|
pub struct BoxBytes {
|
||||||
// SAFETY: `ptr` is owned, was allocated with `layout`, and points to
|
// SAFETY: `ptr` is owned, points to `layout.size()` initialized bytes, and
|
||||||
// `layout.size()` initialized bytes.
|
// was allocated with `layout` (unless `layout.size() == 0` in which case it
|
||||||
|
// is dangling).
|
||||||
ptr: NonNull<u8>,
|
ptr: NonNull<u8>,
|
||||||
layout: Layout,
|
layout: Layout,
|
||||||
}
|
}
|
||||||
@ -770,8 +771,11 @@ impl DerefMut for BoxBytes {
|
|||||||
|
|
||||||
impl Drop for BoxBytes {
|
impl Drop for BoxBytes {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// SAFETY: See type invariant.
|
if self.layout.size() != 0 {
|
||||||
unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), self.layout) };
|
// 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]));
|
let empty: Arc<[i8]> = cast_slice_arc::<(), i8>(Arc::new([(); 42]));
|
||||||
assert!(empty.is_empty());
|
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