Skip to content

Commit

Permalink
Guard against zero sized layouts
Browse files Browse the repository at this point in the history
This new assert should be trivially optimized out
by constant propagation.
  • Loading branch information
Voultapher committed Jun 20, 2021
1 parent 628802b commit bb2f502
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ macro_rules! self_cell {
type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>;

let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
assert!(layout.size() != 0);

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

Expand Down Expand Up @@ -447,6 +448,7 @@ macro_rules! self_cell {
type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>;

let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
assert!(layout.size() != 0);

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

Expand Down Expand Up @@ -506,6 +508,7 @@ macro_rules! self_cell {
type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>;

let layout = $crate::alloc::alloc::Layout::new::<JoinedCell>();
assert!(layout.size() != 0);

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

Expand Down
42 changes: 33 additions & 9 deletions tests/self_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#![deny(private_in_public)]

use std::fmt::Debug;
use std::marker::PhantomData;
use std::panic::catch_unwind;
use std::rc::Rc;

use crossbeam_utils::thread;
Expand Down Expand Up @@ -219,14 +221,6 @@ fn catch_panic_in_from() {
}
}

// impl<'a> TryInto<PanicCtor<'a>> for &'a Owner {
// type Error = Box<dyn std::any::Any + Send + 'static>;

// fn try_into(self) -> Result<PanicCtor<'a>, Self::Error> {
// std::panic::catch_unwind(|| PanicCtor::new(&self))
// }
// }

self_cell!(
struct NoLeakCell {
owner: Owner,
Expand All @@ -242,7 +236,7 @@ fn catch_panic_in_from() {
let owner = Owner("This string is no trout".into());

let ast_cell_result = NoLeakCell::try_new(owner.clone(), |owner| {
std::panic::catch_unwind(|| PanicCtor::new(&owner))
catch_unwind(|| PanicCtor::new(&owner))
});
assert!(ast_cell_result.is_err());
}
Expand Down Expand Up @@ -440,6 +434,36 @@ fn into_owner() {
// assert_eq!(ast_cell.borrow_owner(), &expected_body);
}

#[test]
fn zero_size_cell() {
struct ZeroSizeRef<'a>(PhantomData<&'a ()>);

self_cell!(
struct ZeroSizeCell {
owner: (),

#[covariant]
dependent: ZeroSizeRef,
}
);

assert!(catch_unwind(|| ZeroSizeCell::new((), |_| ZeroSizeRef(PhantomData))).is_err());

assert!(
catch_unwind(|| ZeroSizeCell::try_new((), |_| -> Result<_, i32> {
Ok(ZeroSizeRef(PhantomData))
}))
.is_err()
);

assert!(catch_unwind(
|| ZeroSizeCell::try_new_or_recover((), |_| -> Result<_, i32> {
Ok(ZeroSizeRef(PhantomData))
})
)
.is_err());
}

#[test]
fn share_across_threads() {
// drop_joined takes &mut self, so that's not a thread concern anyway.
Expand Down

0 comments on commit bb2f502

Please sign in to comment.