From 5216f9a7fc7a541101fcc8b3de77c48d2118b08c Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 29 Oct 2023 15:23:48 -0400 Subject: [PATCH] Remove some unsafe code --- Cargo.toml | 3 ++- rand_core/Cargo.toml | 1 + rand_core/src/impls.rs | 18 +++--------------- src/distributions/integer.rs | 3 +-- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 98dbdeb1dca..21781ef5385 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ alloc = ["rand_core/alloc"] getrandom = ["rand_core/getrandom"] # Option (requires nightly Rust): experimental SIMD support -simd_support = [] +simd_support = ["zerocopy/simd-nightly"] # Option (enabled by default): enable StdRng std_rng = ["rand_chacha"] @@ -69,6 +69,7 @@ rand_core = { path = "rand_core", version = "0.7.0" } log = { version = "0.4.4", optional = true } serde = { version = "1.0.103", features = ["derive"], optional = true } rand_chacha = { path = "rand_chacha", version = "0.4.0", default-features = false, optional = true } +zerocopy = { version = "0.7.20", default-features = false, features = ["simd"] } [target.'cfg(unix)'.dependencies] # Used for fork protection (reseeding.rs) diff --git a/rand_core/Cargo.toml b/rand_core/Cargo.toml index 6dd6f843a1d..37c2a563a35 100644 --- a/rand_core/Cargo.toml +++ b/rand_core/Cargo.toml @@ -32,3 +32,4 @@ serde1 = ["serde"] # enables serde for BlockRng wrapper [dependencies] serde = { version = "1", features = ["derive"], optional = true } getrandom = { version = "0.2", optional = true } +zerocopy = { version = "0.7.20", default-features = false } diff --git a/rand_core/src/impls.rs b/rand_core/src/impls.rs index 8f99ef813a5..d7dcd3457d3 100644 --- a/rand_core/src/impls.rs +++ b/rand_core/src/impls.rs @@ -19,6 +19,7 @@ use crate::RngCore; use core::cmp::min; +use zerocopy::AsBytes; /// Implement `next_u64` via `next_u32`, little-endian order. pub fn next_u64_via_u32(rng: &mut R) -> u64 { @@ -52,31 +53,18 @@ pub fn fill_bytes_via_next(rng: &mut R, dest: &mut [u8]) { } } -trait Observable: Copy { +trait Observable: AsBytes + Copy { fn to_le(self) -> Self; - - // Contract: observing self is memory-safe (implies no uninitialised padding) - fn as_byte_slice(x: &[Self]) -> &[u8]; } impl Observable for u32 { fn to_le(self) -> Self { self.to_le() } - fn as_byte_slice(x: &[Self]) -> &[u8] { - let ptr = x.as_ptr() as *const u8; - let len = x.len() * core::mem::size_of::(); - unsafe { core::slice::from_raw_parts(ptr, len) } - } } impl Observable for u64 { fn to_le(self) -> Self { self.to_le() } - fn as_byte_slice(x: &[Self]) -> &[u8] { - let ptr = x.as_ptr() as *const u8; - let len = x.len() * core::mem::size_of::(); - unsafe { core::slice::from_raw_parts(ptr, len) } - } } /// Fill dest from src @@ -98,7 +86,7 @@ fn fill_via_chunks(src: &mut [T], dest: &mut [u8]) -> (usize, usi } } - dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]); + dest[..byte_len].copy_from_slice(&<[T]>::as_bytes(&src[..num_chunks])[..byte_len]); (num_chunks, byte_len) } diff --git a/src/distributions/integer.rs b/src/distributions/integer.rs index 3ef746b9928..e5d320b2550 100644 --- a/src/distributions/integer.rs +++ b/src/distributions/integer.rs @@ -134,8 +134,7 @@ macro_rules! x86_intrinsic_impl { let mut buf = [0_u8; mem::size_of::<$intrinsic>()]; rng.fill_bytes(&mut buf); // x86 is little endian so no need for conversion - // SAFETY: we know [u8; N] and $intrinsic have the same size - unsafe { mem::transmute_copy(&buf) } + zerocopy::transmute!(buf) } } )+};