fix try_pod_read_unaligned... never having worked correctly (#138)

It seems like a copy-paste error has happened between `try_from_bytes`/`try_from_bytes_mut` and `try_pod_read_unaligned`, causing `internal::try_pod_read_unaligned` to try to read a &T::Bits instead of a T::Bits, usually failing with a `SizeMismatch` error. In the worst case, this allows UB in safe code by having a type allowing any bit pattern and being pointer-sized.
This commit is contained in:
Dennis Duda 2022-10-30 15:06:55 -07:00 committed by GitHub
parent 09dd2ffd68
commit f1571512d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 1 deletions

View File

@ -186,6 +186,21 @@ fn anybitpattern_implies_zeroable() {
assert_eq!(test, AnyBitPatternTest { a: 0, b: 0 }); assert_eq!(test, AnyBitPatternTest { a: 0, b: 0 });
} }
#[test]
fn checkedbitpattern_try_pod_read_unaligned() {
let pod = [0u8];
let res = bytemuck::checked::try_pod_read_unaligned::<
CheckedBitPatternEnumWithValues,
>(&pod);
assert!(res.is_ok());
let pod = [5u8];
let res = bytemuck::checked::try_pod_read_unaligned::<
CheckedBitPatternEnumWithValues,
>(&pod);
assert!(res.is_err());
}
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C, align(16))] #[repr(C, align(16))]
struct Issue127 {} struct Issue127 {}

View File

@ -249,7 +249,7 @@ pub fn try_pod_read_unaligned<T: CheckedBitPattern>(
) -> Result<T, CheckedCastError> { ) -> Result<T, CheckedCastError> {
let pod = unsafe { internal::try_pod_read_unaligned(bytes) }?; let pod = unsafe { internal::try_pod_read_unaligned(bytes) }?;
if <T as CheckedBitPattern>::is_valid_bit_pattern(pod) { if <T as CheckedBitPattern>::is_valid_bit_pattern(&pod) {
Ok(unsafe { transmute!(pod) }) Ok(unsafe { transmute!(pod) })
} else { } else {
Err(CheckedCastError::InvalidBitPattern) Err(CheckedCastError::InvalidBitPattern)