From 56ba98301e76f250c9165de5bc1939b8697a2549 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 4 Sep 2023 18:38:52 -0600 Subject: [PATCH] hybrid-array: fix reference conversions The target type on the pointer cast is incorrect: it should be `*const Array` but instead it's `*const &Array`. This is a memory safety error. It was introduced in #904 and thus has never been in anything but v0.2 prereleases, so it isn't particularly security-relevant. --- hybrid-array/src/lib.rs | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/hybrid-array/src/lib.rs b/hybrid-array/src/lib.rs index cdc244ff..2f76c6c6 100644 --- a/hybrid-array/src/lib.rs +++ b/hybrid-array/src/lib.rs @@ -362,7 +362,7 @@ where // SAFETY: `Array` is a `repr(transparent)` newtype for a core // array with length checked above. - Ok(unsafe { *(slice.as_ptr() as *const Self) }) + Ok(unsafe { &*(slice.as_ptr() as *const Array) }) } } @@ -378,7 +378,7 @@ where // SAFETY: `Array` is a `repr(transparent)` newtype for a core // array with length checked above. - Ok(unsafe { *(slice.as_ptr() as *mut Self) }) + Ok(unsafe { &mut *(slice.as_ptr() as *mut Array) }) } } @@ -497,7 +497,7 @@ impl ArrayExt for [T; N] { /// [`typenum::consts`]. pub unsafe trait ArraySize: Unsigned { /// Array type which corresponds to this size. - type ArrayType: AsRef<[T]> + AsMut<[T]> + IntoArray + ArrayExt; + type ArrayType: ArrayExt + AsRef<[T]> + AsMut<[T]> + IntoArray; } /// Convert the given type into an [`Array`]. @@ -682,17 +682,36 @@ impl_array_size! { #[cfg(test)] mod tests { use super::ByteArray; + use crate::Array; use typenum::{U0, U3, U6, U7}; + const EXAMPLE_SLICE: &[u8] = &[1, 2, 3, 4, 5, 6]; + + #[test] + fn clone_from_slice() { + let array = Array::::clone_from_slice(EXAMPLE_SLICE); + assert_eq!(array.as_slice(), EXAMPLE_SLICE); + } + + #[test] + fn tryfrom_slice_for_array() { + assert!(ByteArray::::try_from(EXAMPLE_SLICE).is_err()); + assert!(ByteArray::::try_from(EXAMPLE_SLICE).is_err()); + + let array_ref = ByteArray::::try_from(EXAMPLE_SLICE).expect("slice contains 6 bytes"); + assert_eq!(&*array_ref, EXAMPLE_SLICE); + + assert!(ByteArray::::try_from(EXAMPLE_SLICE).is_err()); + } + #[test] fn tryfrom_slice_for_array_ref() { - let slice: &[u8] = &[1, 2, 3, 4, 5, 6]; - assert!(ByteArray::::try_from(slice).is_err()); - assert!(ByteArray::::try_from(slice).is_err()); + assert!(<&ByteArray>::try_from(EXAMPLE_SLICE).is_err()); + assert!(<&ByteArray::>::try_from(EXAMPLE_SLICE).is_err()); - let array_ref = ByteArray::::try_from(slice).expect("slice contains 6 bytes"); - assert_eq!(&*array_ref, slice); + let array_ref = <&ByteArray>::try_from(EXAMPLE_SLICE).expect("slice contains 6 bytes"); + assert_eq!(array_ref.as_slice(), EXAMPLE_SLICE); - assert!(ByteArray::::try_from(slice).is_err()); + assert!(<&ByteArray::>::try_from(EXAMPLE_SLICE).is_err()); } }