split serde_anymap

This commit is contained in:
Andrea Fioraldi 2021-02-12 09:58:41 +01:00
parent 9272b8b37b
commit e78fbc0f0f
9 changed files with 347 additions and 793 deletions

View File

@ -1,411 +0,0 @@
use alloc::{boxed::Box, vec::Vec};
use core::{
any::{Any, TypeId},
slice::{Iter, IterMut},
};
use hashbrown::{
hash_map::{Keys, Values, ValuesMut},
HashMap,
};
/// A map, storing any trait object by TypeId
#[derive(Default)]
pub struct MetaMap {
map: HashMap<TypeId, Box<dyn Any>>,
}
impl MetaMap {
#[inline]
pub fn get<T>(&self) -> Option<&T>
where
T: Any,
{
self.map
.get(&TypeId::of::<T>())
.map(|x| x.as_ref().downcast_ref::<T>().unwrap())
}
#[inline]
pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: Any,
{
self.map
.get_mut(&TypeId::of::<T>())
.map(|x| x.as_mut().downcast_mut::<T>().unwrap())
}
#[inline]
pub fn insert<T>(&mut self, t: T)
where
T: Any,
{
self.map.insert(TypeId::of::<T>(), Box::new(t));
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn contains<T>(&self) -> bool
where
T: Any,
{
self.map.contains_key(&TypeId::of::<T>())
}
pub fn new() -> Self {
Self {
map: HashMap::default(),
}
}
}
/// A map, allowing to store multiple elements of any given type, by TypeId.
pub struct MultiMetaMap {
map: HashMap<TypeId, Vec<Box<dyn Any>>>,
}
impl MultiMetaMap {
#[inline]
pub fn get<T>(&self) -> Option<core::iter::Map<Iter<'_, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => None,
Some(v) => Some(v.iter().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
}
}
#[inline]
pub fn get_mut<T>(
&mut self,
) -> Option<core::iter::Map<IterMut<'_, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>>
where
T: Any,
{
match self.map.get_mut(&TypeId::of::<T>()) {
None => None,
Some(v) => Some(
v.iter_mut()
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
),
}
}
#[inline]
pub fn insert<T>(&mut self, t: T)
where
T: Any,
{
let typeid = TypeId::of::<T>();
if !self.map.contains_key(&typeid) {
self.map.insert(typeid, vec![Box::new(t)]);
} else {
self.map.get_mut(&typeid).unwrap().push(Box::new(t));
}
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn contains<T>(&self) -> bool
where
T: Any,
{
self.map.contains_key(&TypeId::of::<T>())
}
pub fn new() -> Self {
Self {
map: HashMap::default(),
}
}
}
pub struct MetaInstanceMap {
map: HashMap<TypeId, HashMap<*const (), Box<dyn Any>>>,
}
impl MetaInstanceMap {
#[inline]
pub fn get<T, U>(&self, instance: &U) -> Option<&T>
where
T: Any,
{
self.get_ptr::<T>(instance as *const _ as *const ())
}
pub fn get_ptr<T>(&self, instance: *const ()) -> Option<&T>
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => None,
Some(h) => h
.get(&instance)
.map(|x| x.as_ref().downcast_ref::<T>().unwrap()),
}
}
#[inline]
pub fn get_mut<T, U>(&mut self, instance: &U) -> Option<&mut T>
where
T: Any,
{
self.get_mut_ptr::<T>(instance as *const _ as *const ())
}
pub fn get_mut_ptr<T>(&mut self, instance: *const ()) -> Option<&mut T>
where
T: Any,
{
match self.map.get_mut(&TypeId::of::<T>()) {
None => None,
Some(h) => h
.get_mut(&instance)
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
}
}
pub fn get_all<T>(
&self,
) -> Option<core::iter::Map<Values<'_, *const (), Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => None,
Some(h) => Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
}
}
pub fn get_all_mut<T>(
&mut self,
) -> Option<
core::iter::Map<ValuesMut<'_, *const (), Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>,
>
where
T: Any,
{
match self.map.get_mut(&TypeId::of::<T>()) {
None => None,
Some(h) => Some(
h.values_mut()
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
),
}
}
#[inline]
pub fn insert<T, U>(&mut self, t: T, instance: &U)
where
T: Any,
{
self.insert_ptr(t, instance as *const _ as *const ())
}
pub fn insert_ptr<T>(&mut self, t: T, instance: *const ())
where
T: Any,
{
let typeid = TypeId::of::<T>();
if !self.map.contains_key(&typeid) {
self.map.insert(typeid, HashMap::default());
}
self.map
.get_mut(&typeid)
.unwrap()
.insert(instance, Box::new(t));
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn contains_type<T>(&self) -> bool
where
T: Any,
{
self.map.contains_key(&TypeId::of::<T>())
}
#[inline]
pub fn contains<T, U>(&self, instance: &U) -> bool
where
T: Any,
{
self.contains_ptr::<T>(instance as *const _ as *const ())
}
pub fn contains_ptr<T>(&self, instance: *const ()) -> bool
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => false,
Some(h) => h.contains_key(&instance),
}
}
pub fn new() -> Self {
Self {
map: HashMap::default(),
}
}
}
pub trait AsAny {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
/// A map, allowing to store and get any object by type and name
pub struct NamedAnyMap<B>
where
B: ?Sized + Any + AsAny,
{
map: HashMap<TypeId, HashMap<&'static str, Box<B>>>,
}
impl<B> NamedAnyMap<B>
where
B: ?Sized + Any + AsAny,
{
pub fn get<T>(&self, name: &'static str) -> Option<&T>
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => None,
Some(h) => h
.get(&name)
.map(|x| x.as_any().downcast_ref::<T>().unwrap()),
}
}
pub fn by_typeid(&self, name: &'static str, typeid: &TypeId) -> Option<&B> {
match self.map.get(typeid) {
None => None,
Some(h) => h.get(&name).map(|x| x.as_ref()),
}
}
pub fn get_mut<T>(&mut self, name: &'static str) -> Option<&mut T>
where
T: Any,
{
match self.map.get_mut(&TypeId::of::<T>()) {
None => None,
Some(h) => h
.get_mut(&name)
.map(|x| x.as_any_mut().downcast_mut::<T>().unwrap()),
}
}
pub fn by_typeid_mut(&mut self, name: &'static str, typeid: &TypeId) -> Option<&mut B> {
match self.map.get_mut(typeid) {
None => None,
Some(h) => h.get_mut(&name).map(|x| x.as_mut()),
}
}
pub fn get_all<T>(
&self,
) -> Option<core::iter::Map<Values<'_, &'static str, Box<B>>, fn(&Box<B>) -> &T>>
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => None,
Some(h) => Some(h.values().map(|x| x.as_any().downcast_ref::<T>().unwrap())),
}
}
pub fn all_by_typeid(
&self,
typeid: &TypeId,
) -> Option<core::iter::Map<Values<'_, &'static str, Box<B>>, fn(&Box<B>) -> &B>> {
match self.map.get(typeid) {
None => None,
Some(h) => Some(h.values().map(|x| x.as_ref())),
}
}
pub fn get_all_mut<T>(
&mut self,
) -> Option<core::iter::Map<ValuesMut<'_, &'static str, Box<B>>, fn(&mut Box<B>) -> &mut T>>
where
T: Any,
{
match self.map.get_mut(&TypeId::of::<T>()) {
None => None,
Some(h) => Some(
h.values_mut()
.map(|x| x.as_any_mut().downcast_mut::<T>().unwrap()),
),
}
}
pub fn all_by_typeid_mut(
&mut self,
typeid: &TypeId,
) -> Option<core::iter::Map<ValuesMut<'_, &'static str, Box<B>>, fn(&mut Box<B>) -> &mut B>>
{
match self.map.get_mut(typeid) {
None => None,
Some(h) => Some(h.values_mut().map(|x| x.as_mut())),
}
}
#[inline]
pub fn all_typeids(&self) -> Keys<'_, TypeId, HashMap<&'static str, Box<B>>> {
self.map.keys()
}
pub fn insert(&mut self, val: Box<B>, name: &'static str) {
let typeid = val.type_id();
if !self.map.contains_key(&typeid) {
self.map.insert(typeid, HashMap::default());
}
self.map.get_mut(&typeid).unwrap().insert(name, val);
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn contains_type<T>(&self) -> bool
where
T: Any,
{
self.map.contains_key(&TypeId::of::<T>())
}
#[inline]
pub fn contains<T>(&self, name: &'static str) -> bool
where
T: Any,
{
match self.map.get(&TypeId::of::<T>()) {
None => false,
Some(h) => h.contains_key(&name),
}
}
pub fn new() -> Self {
Self {
map: HashMap::default(),
}
}
}

View File

@ -1,7 +1,7 @@
//! Bolts are no conceptual fuzzing elements, but they keep libafl-based fuzzers together.
pub mod llmp;
pub mod metamap;
pub mod serde_anymap;
pub mod ownedref;
pub mod serdeany;
pub mod shmem;
pub mod tuples;

325
afl/src/bolts/ownedref.rs Normal file
View File

@ -0,0 +1,325 @@
use alloc::{boxed::Box, vec::Vec};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug)]
pub enum Ptr<'a, T: 'a + ?Sized> {
Ref(&'a T),
Owned(Box<T>),
}
impl<'a, T: 'a + ?Sized + Serialize> Serialize for Ptr<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Ptr::Ref(r) => r.serialize(se),
Ptr::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + ?Sized> Deserialize<'de> for Ptr<'a, T>
where
Box<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Ptr::Owned)
}
}
impl<'a, T: Sized> Ptr<'a, T> {
pub fn as_ref(&self) -> &T {
match self {
Ptr::Ref(r) => r,
Ptr::Owned(v) => v.as_ref(),
}
}
}
pub enum PtrMut<'a, T: 'a + ?Sized> {
Ref(&'a mut T),
Owned(Box<T>),
}
impl<'a, T: 'a + ?Sized + Serialize> Serialize for PtrMut<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
PtrMut::Ref(r) => r.serialize(se),
PtrMut::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + ?Sized> Deserialize<'de> for PtrMut<'a, T>
where
Box<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(PtrMut::Owned)
}
}
impl<'a, T: Sized> PtrMut<'a, T> {
pub fn as_ref(&self) -> &T {
match self {
PtrMut::Ref(r) => r,
PtrMut::Owned(v) => v.as_ref(),
}
}
pub fn as_mut(&mut self) -> &T {
match self {
PtrMut::Ref(r) => r,
PtrMut::Owned(v) => v.as_mut(),
}
}
}
pub enum Slice<'a, T: 'a + Sized> {
Ref(&'a [T]),
Owned(Vec<T>),
}
impl<'a, T: 'a + Sized + Serialize> Serialize for Slice<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Slice::Ref(r) => r.serialize(se),
Slice::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for Slice<'a, T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Slice::Owned)
}
}
impl<'a, T: Sized> Slice<'a, T> {
pub fn as_slice(&self) -> &[T] {
match self {
Slice::Ref(r) => r,
Slice::Owned(v) => v.as_slice(),
}
}
}
pub enum SliceMut<'a, T: 'a + Sized> {
Ref(&'a mut [T]),
Owned(Vec<T>),
}
impl<'a, T: 'a + Sized + Serialize> Serialize for SliceMut<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
SliceMut::Ref(r) => r.serialize(se),
SliceMut::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for SliceMut<'a, T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(SliceMut::Owned)
}
}
impl<'a, T: Sized> SliceMut<'a, T> {
pub fn as_slice(&self) -> &[T] {
match self {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_slice(),
}
}
pub fn as_mut_slice(&mut self) -> &[T] {
match self {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_mut_slice(),
}
}
}
#[derive(Clone, Debug)]
pub enum Cptr<T: Sized> {
Cptr(*const T),
Owned(Box<T>),
}
impl<T: Sized + Serialize> Serialize for Cptr<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.as_ref().serialize(se)
}
}
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for Cptr<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(de).map(Cptr::Owned)
}
}
impl<T: Sized> Cptr<T> {
pub fn as_ref(&self) -> &T {
match self {
Cptr::Cptr(p) => unsafe { p.as_ref().unwrap() },
Cptr::Owned(v) => v.as_ref(),
}
}
}
pub enum CptrMut<T: Sized> {
Cptr(*mut T),
Owned(Box<T>),
}
impl<T: Sized + Serialize> Serialize for CptrMut<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.as_ref().serialize(se)
}
}
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for CptrMut<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(de).map(CptrMut::Owned)
}
}
impl<T: Sized> CptrMut<T> {
pub fn as_ref(&self) -> &T {
match self {
CptrMut::Cptr(p) => unsafe { p.as_ref().unwrap() },
CptrMut::Owned(b) => b.as_ref(),
}
}
pub fn as_mut(&mut self) -> &mut T {
match self {
CptrMut::Cptr(p) => unsafe { p.as_mut().unwrap() },
CptrMut::Owned(b) => b.as_mut(),
}
}
}
pub enum Array<T: Sized> {
Cptr((*const T, usize)),
Owned(Vec<T>),
}
impl<T: Sized + Serialize> Serialize for Array<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.as_slice().serialize(se)
}
}
impl<'de, T: Sized + Serialize> Deserialize<'de> for Array<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(de).map(Array::Owned)
}
}
impl<T: Sized> Array<T> {
pub fn as_slice(&self) -> &[T] {
match self {
Array::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
Array::Owned(v) => v.as_slice(),
}
}
}
#[derive(Clone, Debug)]
pub enum ArrayMut<T: Sized> {
Cptr((*mut T, usize)),
Owned(Vec<T>),
}
impl<T: Sized + Serialize> Serialize for ArrayMut<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.as_slice().serialize(se)
}
}
impl<'de, T: Sized + Serialize> Deserialize<'de> for ArrayMut<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(de).map(ArrayMut::Owned)
}
}
impl<T: Sized> ArrayMut<T> {
pub fn as_slice(&self) -> &[T] {
match self {
ArrayMut::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
ArrayMut::Owned(v) => v.as_slice(),
}
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
match self {
ArrayMut::Cptr(p) => unsafe { core::slice::from_raw_parts_mut(p.0, p.1) },
ArrayMut::Owned(v) => v.as_mut_slice(),
}
}
}

View File

@ -1,7 +1,8 @@
use serde::Deserialize;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use alloc::{boxed::Box, vec::Vec};
use alloc::boxed::Box;
use core::any::{Any, TypeId};
#[cfg(fature = "anymap_debug")]
use serde_json;
@ -26,13 +27,13 @@ pub trait SerdeAny: Any + erased_serde::Serialize {
}
pub struct Wrap<'a, T: ?Sized>(pub &'a T);
impl<'a, T> serde::Serialize for Wrap<'a, T>
impl<'a, T> Serialize for Wrap<'a, T>
where
T: ?Sized + erased_serde::Serialize + 'a,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
S: Serializer,
{
erased_serde::serialize(self.0, serializer)
}
@ -78,7 +79,7 @@ macro_rules! create_serde_registry_for_trait {
use hashbrown::hash_map::{Keys, Values, ValuesMut};
use hashbrown::HashMap;
use $crate::bolts::serde_anymap::{
use $crate::bolts::serdeany::{
pack_type_id, unpack_type_id, DeserializeCallback, DeserializeCallbackSeed,
};
use $crate::AflError;
@ -118,7 +119,7 @@ macro_rules! create_serde_registry_for_trait {
impl Registry {
pub fn register<T>(&mut self)
where
T: $trait_name + serde::Serialize + serde::de::DeserializeOwned,
T: $trait_name + Serialize + serde::de::DeserializeOwned,
{
if self.finalized {
panic!("Registry is already finalized!");
@ -145,7 +146,7 @@ macro_rules! create_serde_registry_for_trait {
impl RegistryBuilder {
pub fn register<T>()
where
T: $trait_name + serde::Serialize + serde::de::DeserializeOwned,
T: $trait_name + Serialize + serde::de::DeserializeOwned,
{
unsafe {
REGISTRY.register::<T>();
@ -463,25 +464,25 @@ macro_rules! create_serde_registry_for_trait {
}
}
impl<'a> serde::Serialize for dyn $trait_name {
impl<'a> Serialize for dyn $trait_name {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
S: Serializer,
{
use serde::ser::SerializeSeq;
let id = $crate::bolts::serde_anymap::unpack_type_id(self.type_id());
let id = $crate::bolts::serdeany::unpack_type_id(self.type_id());
let mut seq = se.serialize_seq(Some(2))?;
seq.serialize_element(&id)?;
seq.serialize_element(&$crate::bolts::serde_anymap::Wrap(self))?;
seq.serialize_element(&$crate::bolts::serdeany::Wrap(self))?;
seq.end()
}
}
impl<'de> serde::Deserialize<'de> for Box<dyn $trait_name> {
impl<'de> Deserialize<'de> for Box<dyn $trait_name> {
fn deserialize<D>(deserializer: D) -> Result<Box<dyn $trait_name>, D::Error>
where
D: serde::Deserializer<'de>,
D: Deserializer<'de>,
{
deserializer.deserialize_seq($mod_name::BoxDynVisitor {})
}
@ -489,328 +490,5 @@ macro_rules! create_serde_registry_for_trait {
};
}
create_serde_registry_for_trait!(serdeany_serde, crate::bolts::serde_anymap::SerdeAny);
pub use serdeany_serde::*;
#[derive(Clone, Debug)]
pub enum Ptr<'a, T: 'a + ?Sized> {
Ref(&'a T),
Owned(Box<T>),
}
impl<'a, T: 'a + ?Sized + serde::Serialize> serde::Serialize for Ptr<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Ptr::Ref(r) => r.serialize(se),
Ptr::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + ?Sized> Deserialize<'de> for Ptr<'a, T>
where
Box<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Ptr::Owned)
}
}
impl<'a, T: Sized> Ptr<'a, T> {
pub fn as_ref(&self) -> &T {
match self {
Ptr::Ref(r) => r,
Ptr::Owned(v) => v.as_ref(),
}
}
}
pub enum PtrMut<'a, T: 'a + ?Sized> {
Ref(&'a mut T),
Owned(Box<T>),
}
impl<'a, T: 'a + ?Sized + serde::Serialize> serde::Serialize for PtrMut<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
PtrMut::Ref(r) => r.serialize(se),
PtrMut::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + ?Sized> Deserialize<'de> for PtrMut<'a, T>
where
Box<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(PtrMut::Owned)
}
}
impl<'a, T: Sized> PtrMut<'a, T> {
pub fn as_ref(&self) -> &T {
match self {
PtrMut::Ref(r) => r,
PtrMut::Owned(v) => v.as_ref(),
}
}
pub fn as_mut(&mut self) -> &T {
match self {
PtrMut::Ref(r) => r,
PtrMut::Owned(v) => v.as_mut(),
}
}
}
pub enum Slice<'a, T: 'a + Sized> {
Ref(&'a [T]),
Owned(Vec<T>),
}
impl<'a, T: 'a + Sized + serde::Serialize> serde::Serialize for Slice<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Slice::Ref(r) => r.serialize(se),
Slice::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for Slice<'a, T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Slice::Owned)
}
}
impl<'a, T: Sized> Slice<'a, T> {
pub fn as_slice(&self) -> &[T] {
match self {
Slice::Ref(r) => r,
Slice::Owned(v) => v.as_slice(),
}
}
}
pub enum SliceMut<'a, T: 'a + Sized> {
Ref(&'a mut [T]),
Owned(Vec<T>),
}
impl<'a, T: 'a + Sized + serde::Serialize> serde::Serialize for SliceMut<'a, T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
SliceMut::Ref(r) => r.serialize(se),
SliceMut::Owned(b) => b.serialize(se),
}
}
}
impl<'de, 'a, T: 'a + Sized> Deserialize<'de> for SliceMut<'a, T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(SliceMut::Owned)
}
}
impl<'a, T: Sized> SliceMut<'a, T> {
pub fn as_slice(&self) -> &[T] {
match self {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_slice(),
}
}
pub fn as_mut_slice(&mut self) -> &[T] {
match self {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_mut_slice(),
}
}
}
#[derive(Clone, Debug)]
pub enum Cptr<T: Sized> {
Cptr(*const T),
Owned(Box<T>),
}
impl<T: Sized + serde::Serialize> serde::Serialize for Cptr<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_ref().serialize(se)
}
}
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for Cptr<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(de).map(Cptr::Owned)
}
}
impl<T: Sized> Cptr<T> {
pub fn as_ref(&self) -> &T {
match self {
Cptr::Cptr(p) => unsafe { p.as_ref().unwrap() },
Cptr::Owned(v) => v.as_ref(),
}
}
}
pub enum CptrMut<T: Sized> {
Cptr(*mut T),
Owned(Box<T>),
}
impl<T: Sized + serde::Serialize> serde::Serialize for CptrMut<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_ref().serialize(se)
}
}
impl<'de, T: Sized + serde::de::DeserializeOwned> Deserialize<'de> for CptrMut<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(de).map(CptrMut::Owned)
}
}
impl<T: Sized> CptrMut<T> {
pub fn as_ref(&self) -> &T {
match self {
CptrMut::Cptr(p) => unsafe { p.as_ref().unwrap() },
CptrMut::Owned(b) => b.as_ref(),
}
}
pub fn as_mut(&mut self) -> &mut T {
match self {
CptrMut::Cptr(p) => unsafe { p.as_mut().unwrap() },
CptrMut::Owned(b) => b.as_mut(),
}
}
}
pub enum Array<T: Sized> {
Cptr((*const T, usize)),
Owned(Vec<T>),
}
impl<T: Sized + serde::Serialize> serde::Serialize for Array<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_slice().serialize(se)
}
}
impl<'de, T: Sized + serde::Serialize> Deserialize<'de> for Array<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(de).map(Array::Owned)
}
}
impl<T: Sized> Array<T> {
pub fn as_slice(&self) -> &[T] {
match self {
Array::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
Array::Owned(v) => v.as_slice(),
}
}
}
#[derive(Clone, Debug)]
pub enum ArrayMut<T: Sized> {
Cptr((*mut T, usize)),
Owned(Vec<T>),
}
impl<T: Sized + serde::Serialize> serde::Serialize for ArrayMut<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_slice().serialize(se)
}
}
impl<'de, T: Sized + serde::Serialize> Deserialize<'de> for ArrayMut<T>
where
Vec<T>: Deserialize<'de>,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(de).map(ArrayMut::Owned)
}
}
impl<T: Sized> ArrayMut<T> {
pub fn as_slice(&self) -> &[T] {
match self {
ArrayMut::Cptr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
ArrayMut::Owned(v) => v.as_slice(),
}
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
match self {
ArrayMut::Cptr(p) => unsafe { core::slice::from_raw_parts_mut(p.0, p.1) },
ArrayMut::Owned(v) => v.as_mut_slice(),
}
}
}
create_serde_registry_for_trait!(serdeany_registry, crate::bolts::serdeany::SerdeAny);
pub use serdeany_registry::*;

View File

@ -6,7 +6,7 @@ use core::{convert::Into, default::Default, option::Option};
use serde::{Deserialize, Serialize};
use crate::{
bolts::serde_anymap::{SerdeAny, SerdeAnyMap},
bolts::serdeany::{SerdeAny, SerdeAnyMap},
inputs::Input,
AflError,
};

View File

@ -2,7 +2,7 @@
//! They may be inserted as part of mutations during fuzzing.
use crate::{
bolts::serde_anymap::SerdeAny,
bolts::serdeany::SerdeAny,
inputs::{HasBytesVec, Input},
mutators::*,
utils::Rand,

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{
bolts::{
serde_anymap::{ArrayMut, Cptr},
ownedref::{ArrayMut, Cptr},
tuples::{MatchNameAndType, MatchType, Named, TupleList},
},
utils::current_time,

View File

@ -9,7 +9,7 @@ use std::{
};
use crate::{
bolts::serde_anymap::{SerdeAny, SerdeAnyMap},
bolts::serdeany::{SerdeAny, SerdeAnyMap},
corpus::{Corpus, Testcase},
events::{Event, EventManager, LogSeverity},
executors::{Executor, HasObservers},

View File

@ -1,52 +1,14 @@
//! Utility functions for AFL
use alloc::vec::Vec;
use core::{cell::RefCell, debug_assert, fmt::Debug, time};
use postcard;
use serde::{Deserialize, Serialize};
use xxhash_rust::xxh3::xxh3_64_with_seed;
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
use crate::{corpus::Corpus, feedbacks::FeedbacksTuple, inputs::Input, state::State, AflError};
pub type StdRand = RomuTrioRand;
/// Serialize the current state and corpus during an executiont to bytes.
/// This method is needed when the fuzzer run crashes and has to restart.
pub fn serialize_state_corpus<C, FT, I, R>(
state: &State<C, FT, I, R>,
corpus: &C,
) -> Result<Vec<u8>, AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let state_bytes = postcard::to_allocvec(&state)?;
let corpus_bytes = postcard::to_allocvec(&corpus)?;
Ok(postcard::to_allocvec(&(state_bytes, corpus_bytes))?)
}
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
pub fn deserialize_state_corpus<C, FT, I, R>(
state_corpus_serialized: &[u8],
) -> Result<(State<C, FT, I, R>, C), AflError>
where
C: Corpus<I, R>,
FT: FeedbacksTuple<I>,
I: Input,
R: Rand,
{
let tuple: (Vec<u8>, Vec<u8>) = postcard::from_bytes(&state_corpus_serialized)?;
Ok((
postcard::from_bytes(&tuple.0)?,
postcard::from_bytes(&tuple.1)?,
))
}
/// Ways to get random around here
pub trait Rand: Debug + Serialize {
// Sets the seed of this Rand