serde input
This commit is contained in:
parent
0d3e374f17
commit
0365bdac7a
@ -34,4 +34,5 @@ num = "*"
|
|||||||
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
||||||
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
||||||
erased-serde = "0.3.12"
|
erased-serde = "0.3.12"
|
||||||
postcard = { version = "0.5.1", features = ["alloc"] } # no_std compatible serde serialization fromat
|
postcard = { version = "0.5.1", features = ["alloc"] } # no_std compatible serde serialization fromat
|
||||||
|
bincode = "1.3.1"
|
@ -45,6 +45,7 @@ impl TestcaseMetadataContainer {
|
|||||||
|
|
||||||
/// An entry in the Testcase Corpus
|
/// An entry in the Testcase Corpus
|
||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
|
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
||||||
pub struct Testcase<I>
|
pub struct Testcase<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
|
@ -68,6 +68,7 @@ where
|
|||||||
|
|
||||||
/// Events sent around in the library
|
/// Events sent around in the library
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
||||||
pub enum Event<'a, C, E, I, R>
|
pub enum Event<'a, C, E, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
|
@ -2,7 +2,7 @@ use core::ffi::c_void;
|
|||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
use crate::executors::{Executor, ExitKind};
|
use crate::executors::{Executor, ExitKind};
|
||||||
use crate::inputs::Input;
|
use crate::inputs::{HasTargetBytes, Input};
|
||||||
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
|||||||
/// The inmem executor simply calls a target function, then returns afterwards.
|
/// The inmem executor simply calls a target function, then returns afterwards.
|
||||||
pub struct InMemoryExecutor<I>
|
pub struct InMemoryExecutor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input + HasTargetBytes,
|
||||||
{
|
{
|
||||||
harness: HarnessFunction<I>,
|
harness: HarnessFunction<I>,
|
||||||
observers: NamedSerdeAnyMap,
|
observers: NamedSerdeAnyMap,
|
||||||
@ -24,14 +24,14 @@ where
|
|||||||
|
|
||||||
impl<I> Executor<I> for InMemoryExecutor<I>
|
impl<I> Executor<I> for InMemoryExecutor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input + HasTargetBytes,
|
||||||
{
|
{
|
||||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
|
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError> {
|
||||||
let bytes = input.serialize()?;
|
let bytes = input.target_bytes();
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_INMEMORY_EXECUTOR_PTR = self as *const InMemoryExecutor<I> as *const c_void;
|
CURRENT_INMEMORY_EXECUTOR_PTR = self as *const InMemoryExecutor<I> as *const c_void;
|
||||||
}
|
}
|
||||||
let ret = (self.harness)(self, bytes);
|
let ret = (self.harness)(self, bytes.as_slice());
|
||||||
unsafe {
|
unsafe {
|
||||||
CURRENT_INMEMORY_EXECUTOR_PTR = ptr::null();
|
CURRENT_INMEMORY_EXECUTOR_PTR = ptr::null();
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ where
|
|||||||
|
|
||||||
impl<I> InMemoryExecutor<I>
|
impl<I> InMemoryExecutor<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input + HasTargetBytes,
|
||||||
{
|
{
|
||||||
pub fn new(harness_fn: HarnessFunction<I>) -> Self {
|
pub fn new(harness_fn: HarnessFunction<I>) -> Self {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -165,17 +165,17 @@ mod tests {
|
|||||||
|
|
||||||
use crate::executors::inmemory::InMemoryExecutor;
|
use crate::executors::inmemory::InMemoryExecutor;
|
||||||
use crate::executors::{Executor, ExitKind};
|
use crate::executors::{Executor, ExitKind};
|
||||||
use crate::inputs::Input;
|
use crate::inputs::{HasTargetBytes, Input, TargetBytes};
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
#[derive(Clone)]
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
struct NopInput {}
|
struct NopInput {}
|
||||||
impl Input for NopInput {
|
impl Input for NopInput {}
|
||||||
fn serialize(&self) -> Result<&[u8], AflError> {
|
impl HasTargetBytes for NopInput {
|
||||||
Ok("NOP".as_bytes())
|
fn target_bytes(&self) -> TargetBytes {
|
||||||
}
|
TargetBytes::Owned(vec![0])
|
||||||
fn deserialize(_buf: &[u8]) -> Result<Self, AflError> {
|
|
||||||
Ok(Self {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,27 +3,17 @@ use alloc::rc::Rc;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::convert::From;
|
use core::convert::From;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::inputs::{HasBytesVec, HasTargetBytes, Input};
|
use crate::inputs::{HasBytesVec, HasTargetBytes, Input, TargetBytes};
|
||||||
use crate::AflError;
|
|
||||||
|
|
||||||
/// A bytes input is the basic input
|
/// A bytes input is the basic input
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||||
pub struct BytesInput {
|
pub struct BytesInput {
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for BytesInput {
|
impl Input for BytesInput {}
|
||||||
fn serialize(&self) -> Result<&[u8], AflError> {
|
|
||||||
Ok(&self.bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(buf: &[u8]) -> Result<Self, AflError> {
|
|
||||||
Ok(Self {
|
|
||||||
bytes: buf.to_owned(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rc Ref-cell from Input
|
/// Rc Ref-cell from Input
|
||||||
impl Into<Rc<RefCell<Self>>> for BytesInput {
|
impl Into<Rc<RefCell<Self>>> for BytesInput {
|
||||||
@ -42,8 +32,8 @@ impl HasBytesVec for BytesInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HasTargetBytes for BytesInput {
|
impl HasTargetBytes for BytesInput {
|
||||||
fn target_bytes(&self) -> &[u8] {
|
fn target_bytes(&self) -> TargetBytes {
|
||||||
&self.bytes
|
TargetBytes::Ref(&self.bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use std::path::Path;
|
|||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
/// An input for the target
|
/// An input for the target
|
||||||
pub trait Input: Clone {
|
pub trait Input: Clone + serde::Serialize + serde::de::DeserializeOwned {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
/// Write this input to the file
|
/// Write this input to the file
|
||||||
fn to_file<P>(&self, path: P) -> Result<(), AflError>
|
fn to_file<P>(&self, path: P) -> Result<(), AflError>
|
||||||
@ -22,7 +22,9 @@ pub trait Input: Clone {
|
|||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
let mut file = File::create(path)?;
|
let mut file = File::create(path)?;
|
||||||
file.write_all(self.serialize()?)?;
|
let v = bincode::serialize(&self)
|
||||||
|
.map_err(|_| AflError::Unknown("cannot serialize".to_string()))?;
|
||||||
|
file.write_all(v.as_slice())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +44,8 @@ where {
|
|||||||
let mut file = File::open(path).map_err(AflError::File)?;
|
let mut file = File::open(path).map_err(AflError::File)?;
|
||||||
let mut bytes: Vec<u8> = vec![];
|
let mut bytes: Vec<u8> = vec![];
|
||||||
file.read_to_end(&mut bytes).map_err(AflError::File)?;
|
file.read_to_end(&mut bytes).map_err(AflError::File)?;
|
||||||
Self::deserialize(&bytes)
|
bincode::deserialize::<Self>(&bytes)
|
||||||
|
.map_err(|_| AflError::Unknown("cannot deserialize".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write this input to the file
|
/// Write this input to the file
|
||||||
@ -51,22 +54,28 @@ where {
|
|||||||
where {
|
where {
|
||||||
Err(AflError::NotImplemented("Not suppored in no_std".into()))
|
Err(AflError::NotImplemented("Not suppored in no_std".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize this input, for later deserialization.
|
|
||||||
/// This is not necessarily the representation to be used by the target
|
|
||||||
/// Instead, to get bytes for a target, use [HasTargetBytes](afl::inputs::HasTargetBytes).
|
|
||||||
fn serialize(&self) -> Result<&[u8], AflError>;
|
|
||||||
|
|
||||||
/// Deserialize this input, using the bytes serialized before.
|
|
||||||
fn deserialize(buf: &[u8]) -> Result<Self, AflError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can be serialized to a bytes representation
|
pub enum TargetBytes<'a> {
|
||||||
|
Ref(&'a [u8]),
|
||||||
|
Owned(Vec<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TargetBytes<'a> {
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
match self {
|
||||||
|
TargetBytes::Ref(r) => r,
|
||||||
|
TargetBytes::Owned(v) => v.as_slice(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Can be represented with a vector of bytes
|
||||||
/// This representation is not necessarily deserializable
|
/// This representation is not necessarily deserializable
|
||||||
/// Instead, it can be used as bytes input for a target
|
/// Instead, it can be used as bytes input for a target
|
||||||
pub trait HasTargetBytes {
|
pub trait HasTargetBytes {
|
||||||
/// Target bytes, that can be written to a target
|
/// Target bytes, that can be written to a target
|
||||||
fn target_bytes(&self) -> &[u8];
|
fn target_bytes(&self) -> TargetBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains an internal bytes Vector
|
/// Contains an internal bytes Vector
|
||||||
|
@ -160,7 +160,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_observer_serde() {
|
fn test_observer_serde() {
|
||||||
let o: Box<dyn Observer> = Box::new(StdMapObserver::<u32>::new("test", unsafe { &mut MAP }));
|
let o: Box<dyn Observer> =
|
||||||
|
Box::new(StdMapObserver::<u32>::new("test", unsafe { &mut MAP }));
|
||||||
let s = serde_json::to_string(&o).unwrap();
|
let s = serde_json::to_string(&o).unwrap();
|
||||||
println!("{}", s);
|
println!("{}", s);
|
||||||
let d: Box<dyn Observer> = serde_json::from_str(&s).unwrap();
|
let d: Box<dyn Observer> = serde_json::from_str(&s).unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user