Less unsafe type_eq in stable (#1392)

* less unsafe type_eq

* add type_eq test

* More type eq test

* extend test by a lot

* go mad with tests

* fmt

* simpler tests

* clippy
This commit is contained in:
Dominik Maier 2023-08-02 13:58:05 +02:00 committed by GitHub
parent f4f55088e3
commit d69cde896c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 8 deletions

View File

@ -499,8 +499,7 @@ fn recv_tcp_msg(stream: &mut TcpStream) -> Result<Vec<u8>, Error> {
let mut size_bytes = [0_u8; 4]; let mut size_bytes = [0_u8; 4];
stream.read_exact(&mut size_bytes)?; stream.read_exact(&mut size_bytes)?;
let size = u32::from_be_bytes(size_bytes); let size = u32::from_be_bytes(size_bytes);
let mut bytes = vec![]; let mut bytes = vec![0; size.try_into().unwrap()];
bytes.resize(size as usize, 0_u8);
#[cfg(feature = "llmp_debug")] #[cfg(feature = "llmp_debug")]
log::trace!("LLMP TCP: Receiving payload of size {size}"); log::trace!("LLMP TCP: Receiving payload of size {size}");

View File

@ -607,8 +607,7 @@ where
let mut size_bytes = [0_u8; 4]; let mut size_bytes = [0_u8; 4];
client.stream.read_exact(&mut size_bytes)?; client.stream.read_exact(&mut size_bytes)?;
let size = u32::from_be_bytes(size_bytes); let size = u32::from_be_bytes(size_bytes);
let mut bytes = vec![]; let mut bytes = vec![0; size.try_into().unwrap()];
bytes.resize(size as usize, 0_u8);
client client
.stream .stream
.read_exact(&mut bytes) .read_exact(&mut bytes)

View File

@ -1,5 +1,7 @@
//! Compiletime lists/tuples used throughout the `LibAFL` universe //! Compiletime lists/tuples used throughout the `LibAFL` universe
#[rustversion::not(nightly)]
use core::any::type_name;
use core::{ use core::{
any::TypeId, any::TypeId,
ptr::{addr_of, addr_of_mut}, ptr::{addr_of, addr_of_mut},
@ -11,6 +13,7 @@ use xxhash_rust::xxh3::xxh3_64;
/// Returns if the type `T` is equal to `U` /// Returns if the type `T` is equal to `U`
/// From <https://stackoverflow.com/a/60138532/7658998> /// From <https://stackoverflow.com/a/60138532/7658998>
#[rustversion::nightly] #[rustversion::nightly]
#[inline]
#[must_use] #[must_use]
pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool { pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
// Helper trait. `VALUE` is false, except for the specialization of the // Helper trait. `VALUE` is false, except for the specialization of the
@ -33,11 +36,14 @@ pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
} }
/// Returns if the type `T` is equal to `U` /// Returns if the type `T` is equal to `U`
/// As this relies on [`type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html#note) internally,
/// there is a chance for collisions.
/// Use `nightly` if you need a perfect match at all times.
#[rustversion::not(nightly)] #[rustversion::not(nightly)]
#[inline]
#[must_use] #[must_use]
pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool { pub fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
// BEWARE! This is not unsafe, it is SUPER UNSAFE type_name::<T>() == type_name::<U>()
true
} }
/// Gets the length of the element /// Gets the length of the element
@ -235,7 +241,8 @@ where
/// Match for a name and return the value /// Match for a name and return the value
/// ///
/// # Note /// # Note
/// This operation is unsafe with Rust stable, wait for [specialization](https://stackoverflow.com/a/60138532/7658998). /// This operation may not be 100% accurate with Rust stable, see the notes for [`type_eq`]
/// (in `nightly`, it uses [specialization](https://stackoverflow.com/a/60138532/7658998)).
pub trait MatchName { pub trait MatchName {
/// Match for a name and return the borrowed value /// Match for a name and return the borrowed value
fn match_name<T>(&self, name: &str) -> Option<&T>; fn match_name<T>(&self, name: &str) -> Option<&T>;
@ -513,3 +520,43 @@ impl<Head, Tail> PlusOne for (Head, Tail) where
} }
*/ */
#[cfg(test)]
mod test {
use crate::bolts::{ownedref::OwnedMutSlice, tuples::type_eq};
#[test]
#[allow(unused_qualifications)] // for type name tests
fn test_type_eq() {
#[allow(extra_unused_lifetimes)]
fn test_lifetimes<'a, 'b>() {
assert!(type_eq::<OwnedMutSlice<'a, u8>, OwnedMutSlice<'b, u8>>());
assert!(type_eq::<OwnedMutSlice<'static, u8>, OwnedMutSlice<'a, u8>>());
assert!(type_eq::<OwnedMutSlice<'a, u8>, OwnedMutSlice<'b, u8>>());
assert!(type_eq::<OwnedMutSlice<'a, u8>, OwnedMutSlice<'static, u8>>());
assert!(!type_eq::<OwnedMutSlice<'a, u8>, OwnedMutSlice<'b, i8>>());
}
type OwnedMutSliceAlias<'a> = OwnedMutSlice<'a, u8>;
assert!(type_eq::<OwnedMutSlice<u8>, OwnedMutSliceAlias>());
test_lifetimes();
// test eq
assert!(type_eq::<u64, u64>());
// test neq
assert!(!type_eq::<u64, usize>());
// test weirder lifetime things
assert!(type_eq::<OwnedMutSlice<u8>, OwnedMutSlice<u8>>());
assert!(!type_eq::<OwnedMutSlice<u8>, OwnedMutSlice<u32>>());
assert!(type_eq::<
OwnedMutSlice<u8>,
crate::bolts::ownedref::OwnedMutSlice<u8>,
>());
assert!(!type_eq::<
OwnedMutSlice<u8>,
crate::bolts::ownedref::OwnedMutSlice<u32>,
>());
}
}