doh
This commit is contained in:
parent
60b0b16a60
commit
55c043ec73
@ -194,7 +194,7 @@ where
|
|||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
{
|
{
|
||||||
let mut added = 0;
|
let mut added = 0;
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
@ -234,7 +234,7 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
executor: E,
|
executor: E,
|
||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<(OT, I)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, OT, I> Engine<E, OT, I>
|
impl<E, OT, I> Engine<E, OT, I>
|
||||||
@ -263,24 +263,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Fuzzer<EM, E, OT, C, I, R>
|
pub trait Fuzzer<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, C, I, R>>];
|
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, FT, C, I, R>>];
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, C, I, R>>>;
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>>;
|
||||||
|
|
||||||
fn add_stage(&mut self, stage: Box<dyn Stage<EM, E, OT, C, I, R>>) {
|
fn add_stage(&mut self, stage: Box<dyn Stage<EM, E, OT, FT, C, I, R>>) {
|
||||||
self.stages_mut().push(stage);
|
self.stages_mut().push(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz_one<FT>(
|
fn fuzz_one(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT>,
|
state: &mut State<I, R, FT>,
|
||||||
@ -288,8 +289,6 @@ where
|
|||||||
engine: &mut Engine<E, OT, I>,
|
engine: &mut Engine<E, OT, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<usize, AflError>
|
) -> Result<usize, AflError>
|
||||||
where
|
|
||||||
FT: FeedbacksTuple<I>
|
|
||||||
{
|
{
|
||||||
let (_, idx) = corpus.next(rand)?;
|
let (_, idx) = corpus.next(rand)?;
|
||||||
|
|
||||||
@ -301,15 +300,15 @@ where
|
|||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz_loop<FT>(
|
fn fuzz_loop(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R, FT>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, OT, I>,
|
engine: &mut Engine<E, OT, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
) -> Result<(), AflError> where
|
) -> Result<(), AflError>
|
||||||
FT: FeedbacksTuple<I>{
|
{
|
||||||
let mut last = current_milliseconds();
|
let mut last = current_milliseconds();
|
||||||
loop {
|
loop {
|
||||||
self.fuzz_one(rand, state, corpus, engine, manager)?;
|
self.fuzz_one(rand, state, corpus, engine, manager)?;
|
||||||
@ -325,41 +324,44 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdFuzzer<EM, E, OT, C, I, R>
|
pub struct StdFuzzer<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
stages: Vec<Box<dyn Stage<EM, E, OT, C, I, R>>>,
|
stages: Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, E, OT, C, I, R> Fuzzer<EM, E, OT, C, I, R> for StdFuzzer<EM, E, OT, C, I, R>
|
impl<EM, E, OT, FT, C, I, R> Fuzzer<EM, E, OT, FT, C, I, R> for StdFuzzer<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, C, I, R>>] {
|
fn stages(&self) -> &[Box<dyn Stage<EM, E, OT, FT, C, I, R>>] {
|
||||||
&self.stages
|
&self.stages
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, C, I, R>>> {
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<EM, E, OT, FT, C, I, R>>> {
|
||||||
&mut self.stages
|
&mut self.stages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<EM, E, OT, C, I, R> StdFuzzer<EM, E, OT, C, I, R>
|
impl<EM, E, OT, FT, C, I, R> StdFuzzer<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -403,8 +405,8 @@ mod tests {
|
|||||||
let testcase = Testcase::new(vec![0; 4]).into();
|
let testcase = Testcase::new(vec![0; 4]).into();
|
||||||
corpus.add(testcase);
|
corpus.add(testcase);
|
||||||
|
|
||||||
let executor = InMemoryExecutor::<BytesInput, _>::new(harness, tuple_list!());
|
let executor = InMemoryExecutor::new(harness, tuple_list!());
|
||||||
let mut state = State::new();
|
let mut state = State::<BytesInput, _, _>::new();
|
||||||
|
|
||||||
let mut events_manager = LoggerEventManager::new(stderr());
|
let mut events_manager = LoggerEventManager::new(stderr());
|
||||||
let mut engine = Engine::new(executor);
|
let mut engine = Engine::new(executor);
|
||||||
|
@ -16,11 +16,13 @@ use std::io::Write;
|
|||||||
|
|
||||||
use crate::engines::State;
|
use crate::engines::State;
|
||||||
use crate::executors::Executor;
|
use crate::executors::Executor;
|
||||||
|
use crate::observers::ObserversTuple;
|
||||||
|
use crate::feedbacks::FeedbacksTuple;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::serde_anymap::{Ptr, PtrMut};
|
use crate::serde_anymap::{SerdeAny, Ptr, PtrMut};
|
||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
use crate::{corpus::Corpus, serde_anymap::SerdeAny};
|
use crate::corpus::Corpus;
|
||||||
|
|
||||||
/// Indicate if an event worked or not
|
/// Indicate if an event worked or not
|
||||||
pub enum BrokerEventResult {
|
pub enum BrokerEventResult {
|
||||||
@ -33,7 +35,7 @@ pub enum BrokerEventResult {
|
|||||||
pub trait ShowStats {}
|
pub trait ShowStats {}
|
||||||
|
|
||||||
/// A custom event, for own messages, with own handler.
|
/// A custom event, for own messages, with own handler.
|
||||||
pub trait CustomEvent<I>: SerdeAny + Serialize
|
pub trait CustomEvent<I, OT>: SerdeAny + Serialize
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -48,9 +50,10 @@ 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")]
|
#[serde(bound = "I: serde::de::DeserializeOwned")]
|
||||||
pub enum Event<'a, I>
|
pub enum Event<'a, I, OT>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
|
OT: ObserversTuple
|
||||||
{
|
{
|
||||||
LoadInitial {
|
LoadInitial {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
@ -59,7 +62,7 @@ where
|
|||||||
NewTestcase {
|
NewTestcase {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
input: Ptr<'a, I>,
|
input: Ptr<'a, I>,
|
||||||
observers: PtrMut<'a, crate::observers::observer_serde::NamedSerdeAnyMap>,
|
observers: PtrMut<'a, OT>,
|
||||||
corpus_count: usize,
|
corpus_count: usize,
|
||||||
},
|
},
|
||||||
UpdateStats {
|
UpdateStats {
|
||||||
@ -90,14 +93,15 @@ where
|
|||||||
Custom {
|
Custom {
|
||||||
sender_id: u64,
|
sender_id: u64,
|
||||||
// TODO: Allow custom events
|
// TODO: Allow custom events
|
||||||
// custom_event: Box<dyn CustomEvent<I>>,
|
// custom_event: Box<dyn CustomEvent<I, OT>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> Event<'a, I>
|
impl<'a, I, OT> Event<'a, I, OT>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
//CE: CustomEvent<I>,
|
OT: ObserversTuple
|
||||||
|
//CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
@ -159,29 +163,31 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventManager<C, E, I, R>
|
pub trait EventManager<C, E, OT, FT, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Fire an Event
|
/// Fire an Event
|
||||||
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError>;
|
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError>;
|
||||||
|
|
||||||
/// Lookup for incoming events and process them.
|
/// Lookup for incoming events and process them.
|
||||||
/// Return the number of processes events or an error
|
/// Return the number of processes events or an error
|
||||||
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError>;
|
fn process(&mut self, state: &mut State<I, R, FT>, corpus: &mut C) -> Result<usize, AflError>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
fn on_recv(&self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
// TODO: Better way to move out of testcase, or get ref
|
// TODO: Better way to move out of testcase, or get ref
|
||||||
//Ok(corpus.add(self.testcase.take().unwrap()))
|
//Ok(corpus.add(self.testcase.take().unwrap()))
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO the broker has a state? do we need to pass state and corpus?
|
// TODO the broker has a state? do we need to pass state and corpus?
|
||||||
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
|
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
|
||||||
match event {
|
match event {
|
||||||
Event::LoadInitial {
|
Event::LoadInitial {
|
||||||
sender_id: _,
|
sender_id: _,
|
||||||
@ -238,8 +244,8 @@ where
|
|||||||
|
|
||||||
fn handle_in_client(
|
fn handle_in_client(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event<I>,
|
event: Event<I, OT>,
|
||||||
_state: &mut State<I, R>,
|
_state: &mut State<I, R, FT>,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
match event {
|
match event {
|
||||||
@ -263,7 +269,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*TODO
|
/*TODO
|
||||||
fn on_recv(&self, state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
fn on_recv(&self, state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
println!(
|
println!(
|
||||||
"#{}\t exec/s: {}",
|
"#{}\t exec/s: {}",
|
||||||
state.executions(),
|
state.executions(),
|
||||||
@ -275,10 +281,16 @@ where
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct LoggerEventManager<C, E, I, R, W>
|
pub struct LoggerEventManager<C, E, OT, FT, I, R, W>
|
||||||
where
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
W: Write,
|
W: Write,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
writer: W,
|
writer: W,
|
||||||
count: usize,
|
count: usize,
|
||||||
@ -288,21 +300,23 @@ where
|
|||||||
execs_over_sec: u64,
|
execs_over_sec: u64,
|
||||||
corpus_count: usize,
|
corpus_count: usize,
|
||||||
|
|
||||||
phantom: PhantomData<(C, E, I, R)>,
|
phantom: PhantomData<(C, E, OT, FT, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<C, E, I, R, W> EventManager<C, E, I, R> for LoggerEventManager<C, E, I, R, W>
|
impl<C, E, OT, FT, I, R, W> EventManager<C, E, OT, FT, I, R> for LoggerEventManager<C, E, OT, FT, I, R, W>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
W: Write,
|
W: Write,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError> {
|
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError> {
|
||||||
match self.handle_in_broker(&event)? {
|
match self.handle_in_broker(&event)? {
|
||||||
BrokerEventResult::Forward => (), //self.handle_in_client(event, state, corpus)?,
|
BrokerEventResult::Forward => (), //self.handle_in_client(event, state, corpus)?,
|
||||||
// Ignore broker-only events
|
// Ignore broker-only events
|
||||||
@ -311,13 +325,13 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
|
fn process(&mut self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<usize, AflError> {
|
||||||
let c = self.count;
|
let c = self.count;
|
||||||
self.count = 0;
|
self.count = 0;
|
||||||
Ok(c)
|
Ok(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
|
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
|
||||||
match event {
|
match event {
|
||||||
Event::NewTestcase {
|
Event::NewTestcase {
|
||||||
sender_id: _,
|
sender_id: _,
|
||||||
@ -377,11 +391,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<C, E, I, R, W> LoggerEventManager<C, E, I, R, W>
|
impl<C, E, OT, FT, I, R, W> LoggerEventManager<C, E, OT, FT, I, R, W>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
W: Write,
|
W: Write,
|
||||||
//TODO CE: CustomEvent,
|
//TODO CE: CustomEvent,
|
||||||
@ -400,16 +416,18 @@ where
|
|||||||
|
|
||||||
/// Eventmanager for multi-processed application
|
/// Eventmanager for multi-processed application
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct LlmpBrokerEventManager<C, E, I, R>
|
pub struct LlmpBrokerEventManager<C, E, OT, FT, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
llmp_broker: llmp::LlmpBroker,
|
llmp_broker: llmp::LlmpBroker,
|
||||||
phantom: PhantomData<(C, E, I, R)>,
|
phantom: PhantomData<(C, E, OT, FT, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -424,35 +442,39 @@ const _LLMP_TAG_EVENT_TO_BOTH: llmp::Tag = 0x2B0741;
|
|||||||
|
|
||||||
/// Eventmanager for multi-processed application
|
/// Eventmanager for multi-processed application
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub struct LlmpClientEventManager<C, E, I, R>
|
pub struct LlmpClientEventManager<C, E, OT, FT, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
_llmp_client: llmp::LlmpClient,
|
_llmp_client: llmp::LlmpClient,
|
||||||
phantom: PhantomData<(C, E, I, R)>,
|
phantom: PhantomData<(C, E, OT, FT, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<C, E, I, R> EventManager<C, E, I, R> for LlmpBrokerEventManager<C, E, I, R>
|
impl<C, E, OT, FT, I, R> EventManager<C, E, OT, FT, I, R> for LlmpBrokerEventManager<C, E, OT, FT, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Fire an Event
|
/// Fire an Event
|
||||||
fn fire<'a>(&mut self, event: Event<'a, I>) -> Result<(), AflError> {
|
fn fire<'a>(&mut self, event: Event<'a, I, OT>) -> Result<(), AflError> {
|
||||||
let serialized = postcard::to_allocvec(&event)?;
|
let serialized = postcard::to_allocvec(&event)?;
|
||||||
self.llmp_broker
|
self.llmp_broker
|
||||||
.send_buf(LLMP_TAG_EVENT_TO_CLIENT, &serialized)?;
|
.send_buf(LLMP_TAG_EVENT_TO_CLIENT, &serialized)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
|
fn process(&mut self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<usize, AflError> {
|
||||||
// TODO: iterators
|
// TODO: iterators
|
||||||
/*
|
/*
|
||||||
let mut handled = vec![];
|
let mut handled = vec![];
|
||||||
@ -481,13 +503,13 @@ where
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
fn on_recv(&self, _state: &mut State<I, R, FT>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
// TODO: Better way to move out of testcase, or get ref
|
// TODO: Better way to move out of testcase, or get ref
|
||||||
//Ok(corpus.add(self.testcase.take().unwrap()))
|
//Ok(corpus.add(self.testcase.take().unwrap()))
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_in_broker(&mut self, event: &Event<I>) -> Result<BrokerEventResult, AflError> {
|
fn handle_in_broker(&mut self, event: &Event<I, OT>) -> Result<BrokerEventResult, AflError> {
|
||||||
match event {
|
match event {
|
||||||
Event::LoadInitial {
|
Event::LoadInitial {
|
||||||
sender_id: _,
|
sender_id: _,
|
||||||
@ -542,8 +564,8 @@ where
|
|||||||
|
|
||||||
fn handle_in_client(
|
fn handle_in_client(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event<I>,
|
event: Event<I, OT>,
|
||||||
/*client: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
|
_state: &mut State<I, R, FT>,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
match event {
|
match event {
|
||||||
@ -572,17 +594,17 @@ mod tests {
|
|||||||
|
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
use crate::inputs::bytes::BytesInput;
|
use crate::inputs::bytes::BytesInput;
|
||||||
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
use crate::observers::{Observer, StdMapObserver, ObserversTuple};
|
||||||
use crate::observers::{Observer, StdMapObserver};
|
use crate::tuples::{MatchNameAndType, Named, tuple_list, tuple_list_type};
|
||||||
use crate::serde_anymap::{Ptr, PtrMut};
|
use crate::serde_anymap::{Ptr, PtrMut};
|
||||||
|
|
||||||
static mut MAP: [u32; 4] = [0; 4];
|
static mut MAP: [u32; 4] = [0; 4];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_event_serde() {
|
fn test_event_serde() {
|
||||||
let mut map = NamedSerdeAnyMap::new();
|
|
||||||
let obv = StdMapObserver::new("test", unsafe { &mut MAP });
|
let obv = StdMapObserver::new("test", unsafe { &mut MAP });
|
||||||
map.insert(Box::new(obv), &"key".to_string());
|
let mut map = tuple_list!(obv);
|
||||||
|
|
||||||
let i = BytesInput::new(vec![0]);
|
let i = BytesInput::new(vec![0]);
|
||||||
let e = Event::NewTestcase {
|
let e = Event::NewTestcase {
|
||||||
@ -594,19 +616,16 @@ mod tests {
|
|||||||
|
|
||||||
let j = serde_json::to_string(&e).unwrap();
|
let j = serde_json::to_string(&e).unwrap();
|
||||||
|
|
||||||
let d: Event<BytesInput> = serde_json::from_str(&j).unwrap();
|
let d: Event<BytesInput, tuple_list_type!(StdMapObserver<u32>)> = serde_json::from_str(&j).unwrap();
|
||||||
match d {
|
match d {
|
||||||
Event::NewTestcase {
|
Event::NewTestcase {
|
||||||
sender_id: _,
|
sender_id: _,
|
||||||
input: _,
|
input: _,
|
||||||
observers: obs,
|
observers,
|
||||||
corpus_count: _,
|
corpus_count: _,
|
||||||
} => {
|
} => {
|
||||||
let o = obs
|
let o = observers.as_ref().match_name_type::<StdMapObserver<u32>>("test").unwrap();
|
||||||
.as_ref()
|
assert_eq!("test", o.name());
|
||||||
.get::<StdMapObserver<u32>>(&"key".to_string())
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!("test".to_string(), *o.name());
|
|
||||||
}
|
}
|
||||||
_ => panic!("mistmatch".to_string()),
|
_ => panic!("mistmatch".to_string()),
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ pub type MinMapFeedback<T, O> = MapFeedback<T, MinReducer<T>, O>;
|
|||||||
/// Feedbacks evaluate the observers.
|
/// Feedbacks evaluate the observers.
|
||||||
/// Basically, they reduce the information provided by an observer to a value,
|
/// Basically, they reduce the information provided by an observer to a value,
|
||||||
/// indicating the "interestingness" of the last run.
|
/// indicating the "interestingness" of the last run.
|
||||||
pub trait Feedback<I>: Named
|
pub trait Feedback<I>: Named + 'static
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FeedbacksTuple<I>: TupleList + MatchType + MatchNameAndType
|
pub trait FeedbacksTuple<I>: MatchType + MatchNameAndType
|
||||||
where
|
where
|
||||||
I: Input
|
I: Input
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ I: Input{
|
|||||||
|
|
||||||
impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) where
|
impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) where
|
||||||
Head: Feedback<I>,
|
Head: Feedback<I>,
|
||||||
Tail: FeedbacksTuple<I>,
|
Tail: FeedbacksTuple<I> + TupleList,
|
||||||
I: Input
|
I: Input
|
||||||
{
|
{
|
||||||
fn is_interesting_all<OT: ObserversTuple>(&mut self, input: &I, observers: &OT) -> Result<u32, AflError> {
|
fn is_interesting_all<OT: ObserversTuple>(&mut self, input: &I, observers: &OT) -> Result<u32, AflError> {
|
||||||
@ -90,7 +90,7 @@ impl<Head, Tail, I> FeedbacksTuple<I> for (Head, Tail) where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A Reducer function is used to aggregate values for the novelty search
|
/// A Reducer function is used to aggregate values for the novelty search
|
||||||
pub trait Reducer<T>
|
pub trait Reducer<T>: 'static
|
||||||
where
|
where
|
||||||
T: Integer + Copy + 'static,
|
T: Integer + Copy + 'static,
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
extern crate num;
|
extern crate num;
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
use alloc::string::String;
|
|
||||||
use core::any::Any;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::serde_anymap::ArrayMut;
|
use crate::serde_anymap::ArrayMut;
|
||||||
@ -26,21 +23,23 @@ pub trait Observer: Named + 'static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ObserversTuple: TupleList + MatchNameAndType + MatchType + serde::Serialize + serde::de::DeserializeOwned {
|
pub trait ObserversTuple: MatchNameAndType + MatchType + serde::Serialize + serde::de::DeserializeOwned {
|
||||||
fn reset_all(&mut self) -> Result<(), AflError>;
|
fn reset_all(&mut self) -> Result<(), AflError>;
|
||||||
fn post_exec_all(&mut self) -> Result<(), AflError>;
|
fn post_exec_all(&mut self) -> Result<(), AflError>;
|
||||||
fn for_each(&self, f: fn(&dyn Observer));
|
//fn for_each(&self, f: fn(&dyn Observer));
|
||||||
|
//fn for_each_mut(&mut self, f: fn(&mut dyn Observer));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObserversTuple for () {
|
impl ObserversTuple for () {
|
||||||
fn reset_all(&mut self) -> Result<(), AflError> { Ok(()) }
|
fn reset_all(&mut self) -> Result<(), AflError> { Ok(()) }
|
||||||
fn post_exec_all(&mut self) -> Result<(), AflError> { Ok(()) }
|
fn post_exec_all(&mut self) -> Result<(), AflError> { Ok(()) }
|
||||||
fn for_each(&self, f: fn(&dyn Observer)) { }
|
//fn for_each(&self, f: fn(&dyn Observer)) { }
|
||||||
|
//fn for_each_mut(&mut self, f: fn(&mut dyn Observer)) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Head, Tail> ObserversTuple for (Head, Tail) where
|
impl<Head, Tail> ObserversTuple for (Head, Tail) where
|
||||||
Head: Observer,
|
Head: Observer + serde::Serialize + serde::de::DeserializeOwned,
|
||||||
Tail: ObserversTuple,
|
Tail: ObserversTuple + TupleList,
|
||||||
{
|
{
|
||||||
fn reset_all(&mut self) -> Result<(), AflError> {
|
fn reset_all(&mut self) -> Result<(), AflError> {
|
||||||
self.0.reset()?;
|
self.0.reset()?;
|
||||||
@ -52,10 +51,15 @@ impl<Head, Tail> ObserversTuple for (Head, Tail) where
|
|||||||
self.1.post_exec_all()
|
self.1.post_exec_all()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each(&self, f: fn(&dyn Observer)) {
|
/*fn for_each(&self, f: fn(&dyn Observer)) {
|
||||||
f(self.0);
|
f(&self.0);
|
||||||
self.1.for_each(f)
|
self.1.for_each(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn for_each_mut(&mut self, f: fn(&mut dyn Observer)) {
|
||||||
|
f(&mut self.0);
|
||||||
|
self.1.for_each_mut(f)
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
|
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
|
||||||
|
@ -7,15 +7,16 @@ use crate::events::EventManager;
|
|||||||
use crate::executors::{HasObservers, Executor};
|
use crate::executors::{HasObservers, Executor};
|
||||||
use crate::observers::ObserversTuple;
|
use crate::observers::ObserversTuple;
|
||||||
use crate::feedbacks::FeedbacksTuple;
|
use crate::feedbacks::FeedbacksTuple;
|
||||||
|
use crate::tuples::{TupleList, MatchType};
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
/// A stage is one step in the fuzzing process.
|
/// A stage is one step in the fuzzing process.
|
||||||
/// Multiple stages will be scheduled one by one for each input.
|
/// Multiple stages will be scheduled one by one for each input.
|
||||||
pub trait Stage<EM, E, OT, C, I, R>
|
pub trait Stage<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I> + HasObservers<OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
FT: FeedbacksTuple<I>,
|
FT: FeedbacksTuple<I>,
|
||||||
@ -34,3 +35,84 @@ where
|
|||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError>;
|
) -> Result<(), AflError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait StagesTuple<EM, E, OT, FT, C, I, R>
|
||||||
|
where
|
||||||
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
|
E: Executor<I> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
fn perform_all(
|
||||||
|
&mut self,
|
||||||
|
rand: &mut R,
|
||||||
|
state: &mut State<I, R, FT>,
|
||||||
|
corpus: &mut C,
|
||||||
|
engine: &mut Engine<E, OT, I>,
|
||||||
|
manager: &mut EM,
|
||||||
|
corpus_idx: usize,
|
||||||
|
) -> Result<(), AflError>;
|
||||||
|
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>));
|
||||||
|
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>));
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for ()
|
||||||
|
where
|
||||||
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
|
E: Executor<I> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
fn perform_all(
|
||||||
|
&mut self,
|
||||||
|
rand: &mut R,
|
||||||
|
state: &mut State<I, R, FT>,
|
||||||
|
corpus: &mut C,
|
||||||
|
engine: &mut Engine<E, OT, I>,
|
||||||
|
manager: &mut EM,
|
||||||
|
corpus_idx: usize,
|
||||||
|
) -> Result<(), AflError> { Ok(()) }
|
||||||
|
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) { }
|
||||||
|
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Head, Tail, EM, E, OT, FT, C, I, R> StagesTuple<EM, E, OT, FT, C, I, R> for (Head, Tail) where
|
||||||
|
Head: Stage<EM, E, OT, FT, C, I, R>,
|
||||||
|
Tail: StagesTuple<EM, E, OT, FT, C, I, R> + TupleList,
|
||||||
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
|
E: Executor<I> + HasObservers<OT>,
|
||||||
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
fn perform_all(
|
||||||
|
&mut self,
|
||||||
|
rand: &mut R,
|
||||||
|
state: &mut State<I, R, FT>,
|
||||||
|
corpus: &mut C,
|
||||||
|
engine: &mut Engine<E, OT, I>,
|
||||||
|
manager: &mut EM,
|
||||||
|
corpus_idx: usize,
|
||||||
|
) -> Result<(), AflError> {
|
||||||
|
self.0.perform(rand, state, corpus, engine, manager, corpus_idx)?;
|
||||||
|
self.1.perform_all(rand, state, corpus, engine, manager, corpus_idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each(&self, f: fn(&dyn Stage<EM, E, OT, FT, C, I, R>)) {
|
||||||
|
f(&self.0);
|
||||||
|
self.1.for_each(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each_mut(&mut self, f: fn(&mut dyn Stage<EM, E, OT, FT, C, I, R>)) {
|
||||||
|
f(&mut self.0);
|
||||||
|
self.1.for_each_mut(f)
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::events::EventManager;
|
use crate::events::EventManager;
|
||||||
use crate::executors::Executor;
|
use crate::executors::{HasObservers, Executor};
|
||||||
use crate::observers::ObserversTuple;
|
use crate::observers::ObserversTuple;
|
||||||
|
use crate::feedbacks::FeedbacksTuple;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::mutators::Mutator;
|
use crate::mutators::Mutator;
|
||||||
use crate::stages::Corpus;
|
use crate::stages::Corpus;
|
||||||
@ -18,12 +19,13 @@ use crate::serde_anymap::{Ptr, PtrMut};
|
|||||||
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
||||||
/// Mutational stages will usually have a range of mutations that are
|
/// Mutational stages will usually have a range of mutations that are
|
||||||
/// being applied to the input one by one, between executions.
|
/// being applied to the input one by one, between executions.
|
||||||
pub trait MutationalStage<M, EM, E, OT, C, I, R>: Stage<EM, E, OT, C, I, R>
|
pub trait MutationalStage<M, EM, E, OT, FT, C, I, R>: Stage<EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I, OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -45,9 +47,9 @@ where
|
|||||||
fn perform_mutational(
|
fn perform_mutational(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, I>,
|
engine: &mut Engine<E, OT, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
@ -84,26 +86,28 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default mutational stage
|
/// The default mutational stage
|
||||||
pub struct StdMutationalStage<M, EM, E, OT, C, I, R>
|
pub struct StdMutationalStage<M, EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I, OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
mutator: M,
|
mutator: M,
|
||||||
phantom: PhantomData<(EM, E, OT, C, I, R)>,
|
phantom: PhantomData<(EM, E, OT, FT, C, I, R)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, EM, E, OT, C, I, R> MutationalStage<M, EM, E, OT, C, I, R> for StdMutationalStage<M, EM, E, OT, C, I, R>
|
impl<M, EM, E, OT, FT, C, I, R> MutationalStage<M, EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I, OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -121,12 +125,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, EM, E, OT, C, I, R> Stage<EM, E, OT, C, I, R> for StdMutationalStage<M, EM, E, OT, C, I, R>
|
impl<M, EM, E, OT, FT, C, I, R> Stage<EM, E, OT, FT, C, I, R> for StdMutationalStage<M, EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I, OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -135,9 +140,9 @@ where
|
|||||||
fn perform(
|
fn perform(
|
||||||
&mut self,
|
&mut self,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
state: &mut State<I, R>,
|
state: &mut State<I, R, FT>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<E, I>,
|
engine: &mut Engine<E, OT, I>,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
corpus_idx: usize,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
@ -145,12 +150,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, EM, E, OT, C, I, R> StdMutationalStage<M, EM, E, OT, C, I, R>
|
impl<M, EM, E, OT, FT, C, I, R> StdMutationalStage<M, EM, E, OT, FT, C, I, R>
|
||||||
where
|
where
|
||||||
M: Mutator<C, I, R>,
|
M: Mutator<C, I, R>,
|
||||||
EM: EventManager<C, E, I, R>,
|
EM: EventManager<C, E, OT, FT, I, R>,
|
||||||
E: Executor<I, OT>,
|
E: Executor<I> + HasObservers<OT>,
|
||||||
OT: ObserversTuple,
|
OT: ObserversTuple,
|
||||||
|
FT: FeedbacksTuple<I>,
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user