serializable observers to

This commit is contained in:
Andrea Fioraldi 2020-12-10 10:06:29 +01:00
parent 6dfe253bb9
commit 67f6aecb6b
3 changed files with 124 additions and 25 deletions

View File

@ -89,7 +89,7 @@ where
/// The most common AFL-like feedback type
pub struct MapFeedback<T, R, O>
where
T: Integer + Copy + 'static,
T: Integer + Default + Copy + 'static,
R: Reducer<T>,
O: MapObserver<T>,
{
@ -103,7 +103,7 @@ where
impl<T, R, O, I> Feedback<I> for MapFeedback<T, R, O>
where
T: Integer + Copy + 'static,
T: Integer + Default + Copy + 'static,
R: Reducer<T>,
O: MapObserver<T> + 'static,
I: Input,
@ -137,7 +137,7 @@ where
impl<T, R, O> MapFeedback<T, R, O>
where
T: Integer + Copy + Default + 'static,
T: Integer + Default + Copy + 'static,
R: Reducer<T>,
O: MapObserver<T>,
{
@ -153,7 +153,7 @@ where
impl<T, R, O> MapFeedback<T, R, O>
where
T: Integer + Copy + 'static,
T: Integer + Default + Copy + 'static,
R: Reducer<T>,
O: MapObserver<T>,
{

View File

@ -6,7 +6,7 @@ use core::slice::from_raw_parts_mut;
use num::Integer;
use serde::{Deserialize, Serialize};
use crate::serde_anymap::{SerdeAny, SliceMut};
use crate::serde_anymap::{SerdeAny, ArrayMut};
use crate::AflError;
// TODO register each observer in the Registry in new()
@ -29,10 +29,12 @@ pub trait Observer: SerdeAny + 'static {
crate::create_serde_registry_for_trait!(observer_serde, crate::observers::Observer);
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T>
where
T: Integer + Copy,
T: Default + Copy,
{
/// Get the map
fn map(&self) -> &[T];
@ -63,19 +65,19 @@ where
/// The Map Observer retrieves the state of a map,
/// that will get updated by the target.
/// A well-known example is the AFL-Style coverage map.
#[derive(Serialize, Deserialize)]
#[derive(Serialize)]
pub struct StdMapObserver<T>
where
T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>,
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
map: SliceMut<'static, T>,
map: ArrayMut<T>,
initial: T,
name: &'static str,
}
impl<T> Observer for StdMapObserver<T>
where
T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>,
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
fn reset(&mut self) -> Result<(), AflError> {
self.reset_map()
@ -88,7 +90,7 @@ where
impl<T> SerdeAny for StdMapObserver<T>
where
T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>,
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
fn as_any(&self) -> &dyn Any {
self
@ -100,20 +102,14 @@ where
impl<T> MapObserver<T> for StdMapObserver<T>
where
T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>,
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
fn map(&self) -> &[T] {
match &self.map {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_slice(),
}
self.map.as_slice()
}
fn map_mut(&mut self) -> &mut [T] {
match &mut self.map {
SliceMut::Ref(r) => r,
SliceMut::Owned(v) => v.as_mut_slice(),
}
self.map.as_mut_slice()
}
fn initial(&self) -> T {
@ -129,16 +125,29 @@ where
}
}
impl<'de, T> Deserialize<'de> for StdMapObserver<T>
where
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut erased = erased_serde::Deserializer::erase(de);
erased_serde::deserialize(&mut erased).map_err(serde::de::Error::custom)
}
}
impl<T> StdMapObserver<T>
where
T: Integer + Copy + 'static + serde::Serialize + serde::Deserialize<'static>,
T: Default + Copy+ 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// Creates a new MapObserver
pub fn new(name: &'static str, map: &'static mut [T]) -> Self {
observer_serde::RegistryBuilder::register::<Self>();
let initial = if map.len() > 0 { map[0] } else { T::zero() };
let initial = if map.len() > 0 { map[0] } else { T::default() };
Self {
map: SliceMut::Ref(map),
map: ArrayMut::Cptr((map.as_mut_ptr(), map.len())),
initial: initial,
name: name,
}
@ -146,10 +155,11 @@ where
/// Creates a new MapObserver from a raw pointer
pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
observer_serde::RegistryBuilder::register::<Self>();
unsafe {
let initial = if len > 0 { *map_ptr } else { T::zero() };
let initial = if len > 0 { *map_ptr } else { T::default() };
StdMapObserver {
map: SliceMut::Ref(from_raw_parts_mut(map_ptr, len)),
map: ArrayMut::Cptr((map_ptr, len)),
initial: initial,
name: name,
}

View File

@ -509,3 +509,92 @@ where
Deserialize::deserialize(deserializer).map(SliceMut::Owned)
}
}
pub enum Array<T: Sized + serde::Serialize> {
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 + serde::Serialize> 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()
}
}
}
}
pub enum ArrayMut<T: Sized + serde::Serialize> {
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 + serde::Serialize> 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()
}
}
}
}