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];
stream.read_exact(&mut size_bytes)?;
let size = u32::from_be_bytes(size_bytes);
let mut bytes = vec![];
bytes.resize(size as usize, 0_u8);
let mut bytes = vec![0; size.try_into().unwrap()];
#[cfg(feature = "llmp_debug")]
log::trace!("LLMP TCP: Receiving payload of size {size}");

View File

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

View File

@ -1,5 +1,7 @@
//! Compiletime lists/tuples used throughout the `LibAFL` universe
#[rustversion::not(nightly)]
use core::any::type_name;
use core::{
any::TypeId,
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`
/// From <https://stackoverflow.com/a/60138532/7658998>
#[rustversion::nightly]
#[inline]
#[must_use]
pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
// 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`
/// 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)]
#[inline]
#[must_use]
pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
// BEWARE! This is not unsafe, it is SUPER UNSAFE
true
pub fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
type_name::<T>() == type_name::<U>()
}
/// Gets the length of the element
@ -235,7 +241,8 @@ where
/// Match for a name and return the value
///
/// # 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 {
/// Match for a name and return the borrowed value
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>,
>());
}
}