Skip to content

Commit

Permalink
manually copy padding bytes when running miri
Browse files Browse the repository at this point in the history
reorganize tests
remove faulty test from Lucretiel#3
  • Loading branch information
RustyYato committed Apr 8, 2020
1 parent 760be7f commit 788ad00
Showing 1 changed file with 28 additions and 37 deletions.
65 changes: 28 additions & 37 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,28 @@ impl<T> Stowaway<T> {
// that there are enough of them, and that blob takes ownership
// of value. This write call is paired with a `read` call in
// `into_inner`.

#[cfg(not(miri))]
ptr::write(ptr as *mut T, value);

#[cfg(miri)]
{
// we use this alternative implementation of write because we want
// MIRI to catch illegal padding bytes in `Stowaway::into_raw`

// under the current implementation of `ptr::write`, padding bytes are not always copied
// this means that MIRI will see zeros where the paddings bytes are suppoed to be
// and allows it. But this is *still* undefined behavior! So in order to make it easier
// for MIRI to catch this behavior, we manually copy padding bytes

ptr::copy_nonoverlapping(
&value as *const T as *const u8,
ptr as *mut u8,
core::mem::size_of::<T>(),
);
core::mem::forget(value);
}

// Safety: all the bytes of blob were initialized, either
// as zero or with `value`
blob
Expand Down Expand Up @@ -340,6 +360,14 @@ impl<T> Stowaway<T> {
#[cfg(test)]
mod test_for_uninit_bytes {
use crate::{stow, unstow};

#[test]
fn test_uninitialized_stowaway_new() {
type Uninint = core::mem::MaybeUninit<usize>;

let _sto = super::Stowaway::new(Uninint::uninit());
}

#[test]
fn zst() {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand All @@ -360,36 +388,6 @@ mod test_for_uninit_bytes {
assert_eq!(x, unstowed);
}
}
#[test]
fn t_with_gaps_32() {
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Gaps32 {
a: u8,
b: u16,
}
let x = Gaps32 { a: 7, b: 42 };
unsafe {
let stowed = stow(x);
let unstowed = unstow(stowed);
assert_eq!(x, unstowed);
}
}
#[test]
fn t_with_gaps_64() {
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Gaps64 {
a: u8,
b: u32,
}
let x = Gaps64 { a: 7, b: 42 };
unsafe {
let stowed = stow(x);
let unstowed = unstow(stowed);
assert_eq!(x, unstowed);
}
}
}

impl<T> Drop for Stowaway<T> {
Expand Down Expand Up @@ -893,10 +891,3 @@ fn test_mut_ref_from_stowed_large() {
let value: Vec<i64> = unsafe { unstow(storage) };
assert_eq!(&value, &[3245, 5675, 4653, 1234, 7345, 10, 12]);
}

#[test]
fn test_uninitialized_stowaway_new() {
type Uninint = MaybeUninit<usize>;

let _sto = Stowaway::new(Uninint::uninit());
}

0 comments on commit 788ad00

Please sign in to comment.