Named Mutators and MultiMutator API change (#1387)
* Mutators need names (alternative to #1379) * Signature of MultiMutator shouldn't be the same as the normal mutator * Named for python, remove mutator for multi_mutator * fmt * clippy edition warning * clippy * mac_count doc fix, return cleanup
This commit is contained in:
parent
90e9f3c786
commit
006dcac00c
@ -1,4 +1,5 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"libafl",
|
||||
"libafl_derive",
|
||||
|
@ -26,7 +26,7 @@ use libafl::{
|
||||
monitors::SimpleMonitor,
|
||||
mutators::{
|
||||
scheduled::havoc_mutations, token_mutations::AFLppRedQueen, tokens_mutations,
|
||||
MutationResult, StdMOptMutator, Tokens,
|
||||
StdMOptMutator, Tokens,
|
||||
},
|
||||
observers::{
|
||||
AFLppCmpMap, AFLppForkserverCmpObserver, HitcountsMapObserver, StdMapObserver, TimeObserver,
|
||||
@ -35,7 +35,7 @@ use libafl::{
|
||||
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
|
||||
},
|
||||
stages::{
|
||||
calibrate::CalibrationStage, mutational::MultipleMutationalStage,
|
||||
calibrate::CalibrationStage, mutational::MultiMutationalStage,
|
||||
power::StdPowerMutationalStage, tracing::AFLppCmplogTracingStage, ColorizationStage,
|
||||
IfStage,
|
||||
},
|
||||
@ -368,7 +368,7 @@ fn fuzz(
|
||||
let tracing = AFLppCmplogTracingStage::with_cmplog_observer_name(cmplog_executor, "cmplog");
|
||||
|
||||
// Setup a randomic Input2State stage
|
||||
let rq = MultipleMutationalStage::new(AFLppRedQueen::with_cmplog_options(true, true));
|
||||
let rq = MultiMutationalStage::new(AFLppRedQueen::with_cmplog_options(true, true));
|
||||
|
||||
let cb = |_fuzzer: &mut _,
|
||||
_executor: &mut _,
|
||||
|
@ -80,7 +80,7 @@ pub enum MutationResult {
|
||||
|
||||
/// A mutator takes input, and mutates it.
|
||||
/// Simple as that.
|
||||
pub trait Mutator<I, S> {
|
||||
pub trait Mutator<I, S>: Named {
|
||||
/// Mutate a given input
|
||||
fn mutate(
|
||||
&mut self,
|
||||
@ -90,6 +90,7 @@ pub trait Mutator<I, S> {
|
||||
) -> Result<MutationResult, Error>;
|
||||
|
||||
/// Post-process given the outcome of the execution
|
||||
#[inline]
|
||||
fn post_exec(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
@ -102,18 +103,20 @@ pub trait Mutator<I, S> {
|
||||
|
||||
/// A mutator that takes input, and returns a vector of mutated inputs.
|
||||
/// Simple as that.
|
||||
pub trait MultipleMutator<I, S> {
|
||||
/// Mutate a given input
|
||||
fn mutate(
|
||||
pub trait MultiMutator<I, S>: Named {
|
||||
/// Mutate a given input up to `max_count` times,
|
||||
/// or as many times as appropriate, if no `max_count` is given
|
||||
fn multi_mutate(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
input: &I,
|
||||
vec: &mut Vec<I>,
|
||||
stage_idx: i32,
|
||||
) -> Result<MutationResult, Error>;
|
||||
max_count: Option<usize>,
|
||||
) -> Result<Vec<I>, Error>;
|
||||
|
||||
/// Post-process given the outcome of the execution
|
||||
fn post_exec(
|
||||
#[inline]
|
||||
fn multi_post_exec(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_stage_idx: i32,
|
||||
@ -158,9 +161,13 @@ pub trait MutatorsTuple<I, S>: HasConstLen {
|
||||
stage_idx: i32,
|
||||
corpus_idx: Option<CorpusId>,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
/// Gets all names of the wrapped [`Mutator`]`s`.
|
||||
fn names(&self) -> Vec<&str>;
|
||||
}
|
||||
|
||||
impl<I, S> MutatorsTuple<I, S> for () {
|
||||
#[inline]
|
||||
fn mutate_all(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
@ -170,6 +177,7 @@ impl<I, S> MutatorsTuple<I, S> for () {
|
||||
Ok(MutationResult::Skipped)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn post_exec_all(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
@ -179,6 +187,7 @@ impl<I, S> MutatorsTuple<I, S> for () {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_and_mutate(
|
||||
&mut self,
|
||||
_index: MutationId,
|
||||
@ -189,6 +198,7 @@ impl<I, S> MutatorsTuple<I, S> for () {
|
||||
Ok(MutationResult::Skipped)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_and_post_exec(
|
||||
&mut self,
|
||||
_index: usize,
|
||||
@ -198,11 +208,16 @@ impl<I, S> MutatorsTuple<I, S> for () {
|
||||
) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn names(&self) -> Vec<&str> {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Head, Tail, I, S> MutatorsTuple<I, S> for (Head, Tail)
|
||||
where
|
||||
Head: Mutator<I, S> + Named,
|
||||
Head: Mutator<I, S>,
|
||||
Tail: MutatorsTuple<I, S>,
|
||||
{
|
||||
fn mutate_all(
|
||||
@ -258,16 +273,25 @@ where
|
||||
.get_and_post_exec(index - 1, state, stage_idx, corpus_idx)
|
||||
}
|
||||
}
|
||||
|
||||
fn names(&self) -> Vec<&str> {
|
||||
let mut ret = self.1.names();
|
||||
ret.insert(0, self.0.name());
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// `Mutator` Python bindings
|
||||
#[cfg(feature = "python")]
|
||||
#[allow(missing_docs)]
|
||||
pub mod pybind {
|
||||
use pyo3::prelude::*;
|
||||
use core::ffi::CStr;
|
||||
|
||||
use pyo3::{prelude::*, AsPyPointer};
|
||||
|
||||
use super::{MutationResult, Mutator};
|
||||
use crate::{
|
||||
bolts::tuples::Named,
|
||||
corpus::CorpusId,
|
||||
inputs::{BytesInput, HasBytesVec},
|
||||
mutators::scheduled::pybind::PythonStdHavocMutator,
|
||||
@ -287,6 +311,14 @@ pub mod pybind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for PyObjectMutator {
|
||||
fn name(&self) -> &str {
|
||||
unsafe { CStr::from_ptr((*(*self.inner.as_ptr()).ob_type).tp_name) }
|
||||
.to_str()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mutator<BytesInput, PythonStdState> for PyObjectMutator {
|
||||
fn mutate(
|
||||
&mut self,
|
||||
@ -386,6 +418,15 @@ pub mod pybind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for PythonMutator {
|
||||
fn name(&self) -> &str {
|
||||
match &self.wrapper {
|
||||
PythonMutatorWrapper::Python(pyo) => pyo.name(),
|
||||
PythonMutatorWrapper::StdHavoc(_) => "StdHavocPythonMutator",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mutator<BytesInput, PythonStdState> for PythonMutator {
|
||||
fn mutate(
|
||||
&mut self,
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! The `MOpt` mutator scheduler, see <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
|
||||
use alloc::{string::ToString, vec::Vec};
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{
|
||||
fmt::{self, Debug},
|
||||
marker::PhantomData,
|
||||
@ -9,7 +12,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::MutationId;
|
||||
use crate::{
|
||||
bolts::rands::{Rand, StdRand},
|
||||
bolts::{
|
||||
rands::{Rand, StdRand},
|
||||
tuples::Named,
|
||||
},
|
||||
corpus::{Corpus, CorpusId},
|
||||
mutators::{ComposedByMutations, MutationResult, Mutator, MutatorsTuple, ScheduledMutator},
|
||||
state::{HasCorpus, HasMetadata, HasRand, HasSolutions},
|
||||
@ -365,6 +371,7 @@ where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand + HasMetadata + HasCorpus + HasSolutions,
|
||||
{
|
||||
name: String,
|
||||
mode: MOptMode,
|
||||
finds_before: usize,
|
||||
mutations: MT,
|
||||
@ -539,6 +546,7 @@ where
|
||||
state.add_metadata::<MOpt>(MOpt::new(mutations.len(), swarm_num, rand_seed)?);
|
||||
}
|
||||
Ok(Self {
|
||||
name: format!("StdMOptMutator[{}]", mutations.names().join(",")),
|
||||
mode: MOptMode::Pilotfuzzing,
|
||||
finds_before: 0,
|
||||
mutations,
|
||||
@ -632,6 +640,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> Named for StdMOptMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand + HasMetadata + HasCorpus + HasSolutions,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> ScheduledMutator<I, MT, S> for StdMOptMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
|
@ -13,7 +13,7 @@ pub use crate::mutators::{mutations::*, token_mutations::*};
|
||||
use crate::{
|
||||
bolts::{
|
||||
rands::Rand,
|
||||
tuples::{tuple_list, tuple_list_type, NamedTuple},
|
||||
tuples::{tuple_list, tuple_list_type, Named, NamedTuple},
|
||||
AsMutSlice, AsSlice,
|
||||
},
|
||||
corpus::{Corpus, CorpusId},
|
||||
@ -106,6 +106,7 @@ where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand,
|
||||
{
|
||||
name: String,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
@ -126,6 +127,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> Named for StdScheduledMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> Mutator<I, S> for StdScheduledMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
@ -185,6 +196,7 @@ where
|
||||
/// Create a new [`StdScheduledMutator`] instance specifying mutations
|
||||
pub fn new(mutations: MT) -> Self {
|
||||
StdScheduledMutator {
|
||||
name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")),
|
||||
mutations,
|
||||
max_stack_pow: 7,
|
||||
phantom: PhantomData,
|
||||
@ -194,6 +206,7 @@ where
|
||||
/// Create a new [`StdScheduledMutator`] instance specifying mutations and the maximun number of iterations
|
||||
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: u64) -> Self {
|
||||
StdScheduledMutator {
|
||||
name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")),
|
||||
mutations,
|
||||
max_stack_pow,
|
||||
phantom: PhantomData,
|
||||
@ -279,6 +292,7 @@ where
|
||||
S: HasRand + HasCorpus,
|
||||
SM: ScheduledMutator<I, MT, S>,
|
||||
{
|
||||
name: String,
|
||||
scheduled: SM,
|
||||
mutation_log: Vec<MutationId>,
|
||||
phantom: PhantomData<(I, MT, S)>,
|
||||
@ -300,6 +314,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S, SM> Named for LoggerScheduledMutator<I, MT, S, SM>
|
||||
where
|
||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||
S: HasRand + HasCorpus,
|
||||
SM: ScheduledMutator<I, MT, S>,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S, SM> Mutator<I, S> for LoggerScheduledMutator<I, MT, S, SM>
|
||||
where
|
||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||
@ -403,9 +428,11 @@ where
|
||||
S: HasRand + HasCorpus,
|
||||
SM: ScheduledMutator<I, MT, S>,
|
||||
{
|
||||
/// Create a new [`StdScheduledMutator`] instance without mutations and corpus
|
||||
/// Create a new [`LoggerScheduledMutator`] instance without mutations and corpus
|
||||
/// This mutator logs all mutators.
|
||||
pub fn new(scheduled: SM) -> Self {
|
||||
Self {
|
||||
name: format!("LoggerScheduledMutator[{}]", scheduled.name()),
|
||||
scheduled,
|
||||
mutation_log: vec![],
|
||||
phantom: PhantomData,
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
bolts::{rands::Rand, AsSlice},
|
||||
inputs::{HasBytesVec, UsesInput},
|
||||
mutators::{
|
||||
buffer_self_copy, mutations::buffer_copy, MultipleMutator, MutationResult, Mutator, Named,
|
||||
buffer_self_copy, mutations::buffer_copy, MultiMutator, MutationResult, Mutator, Named,
|
||||
},
|
||||
observers::cmp::{AFLppCmpValuesMetadata, CmpValues, CmpValuesMetadata},
|
||||
stages::TaintMetadata,
|
||||
@ -1090,37 +1090,37 @@ impl AFLppRedQueen {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, S> MultipleMutator<I, S> for AFLppRedQueen
|
||||
impl<I, S> MultiMutator<I, S> for AFLppRedQueen
|
||||
where
|
||||
S: UsesInput + HasMetadata + HasRand + HasMaxSize + HasCorpus,
|
||||
I: HasBytesVec + From<Vec<u8>>,
|
||||
{
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn mutate(
|
||||
fn multi_mutate(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
input: &I,
|
||||
ret: &mut Vec<I>,
|
||||
stage_idx: i32,
|
||||
) -> Result<MutationResult, Error> {
|
||||
max_count: Option<usize>,
|
||||
) -> Result<Vec<I>, Error> {
|
||||
// TODO
|
||||
// handle 128-bits logs
|
||||
let size = input.bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let (cmp_len, cmp_meta, taint_meta) = {
|
||||
let cmp_meta = state.metadata_map().get::<AFLppCmpValuesMetadata>();
|
||||
let taint_meta = state.metadata_map().get::<TaintMetadata>();
|
||||
if cmp_meta.is_none() || taint_meta.is_none() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let cmp_len = cmp_meta.unwrap().headers().len();
|
||||
if cmp_len == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
return Ok(vec![]);
|
||||
}
|
||||
(cmp_len, cmp_meta.unwrap(), taint_meta.unwrap())
|
||||
};
|
||||
@ -1135,7 +1135,7 @@ where
|
||||
let orig_bytes = input.bytes();
|
||||
|
||||
let taint = taint_meta.ranges();
|
||||
let mut vec = vec![];
|
||||
let mut ret = max_count.map_or_else(Vec::new, Vec::with_capacity);
|
||||
let mut gathered_tokens = Tokens::new();
|
||||
// println!("orig: {:#?} new: {:#?}", orig_cmpvals, new_cmpvals);
|
||||
|
||||
@ -1172,6 +1172,13 @@ where
|
||||
}
|
||||
|
||||
for cmp_buf_idx in 0..input_len {
|
||||
if let Some(max_count) = max_count {
|
||||
if ret.len() >= max_count {
|
||||
// TODO: does this bias towards earlier mutations?
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let taint_len = match taint.get(taint_idx) {
|
||||
Some(t) => {
|
||||
if cmp_buf_idx < t.start {
|
||||
@ -1213,7 +1220,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1229,7 +1236,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1247,7 +1254,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1263,7 +1270,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
*/
|
||||
@ -1301,7 +1308,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1318,7 +1325,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1336,7 +1343,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1352,7 +1359,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1390,7 +1397,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// swapped
|
||||
@ -1407,7 +1414,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1425,7 +1432,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1442,7 +1449,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1483,7 +1490,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1500,7 +1507,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1518,7 +1525,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Swapped
|
||||
@ -1535,7 +1542,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1574,7 +1581,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
// Compare v1 against v0
|
||||
@ -1589,7 +1596,7 @@ where
|
||||
taint_len,
|
||||
input_len,
|
||||
hshape,
|
||||
&mut vec,
|
||||
&mut ret,
|
||||
);
|
||||
|
||||
let is_ascii_or_utf8 = self.text_type.is_ascii_or_utf8();
|
||||
@ -1663,16 +1670,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let mut mutated = false;
|
||||
for item in vec {
|
||||
ret.push(I::from(item));
|
||||
mutated = true;
|
||||
}
|
||||
|
||||
if mutated {
|
||||
Ok(MutationResult::Mutated)
|
||||
if let Some(max_count) = max_count {
|
||||
Ok(ret.into_iter().take(max_count).map(I::from).collect())
|
||||
} else {
|
||||
Ok(MutationResult::Skipped)
|
||||
Ok(ret.into_iter().map(I::from).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
//! Instead of a random mutator for a random amount of iterations, we can run
|
||||
//! a specific mutator for a specified amount of iterations
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::{
|
||||
fmt::{self, Debug},
|
||||
marker::PhantomData,
|
||||
@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use crate::mutators::{mutations::*, token_mutations::*};
|
||||
use crate::{
|
||||
bolts::{calculate_cumulative_sum_in_place, rands::Rand},
|
||||
bolts::{calculate_cumulative_sum_in_place, rands::Rand, tuples::Named},
|
||||
impl_serdeany,
|
||||
mutators::{
|
||||
ComposedByMutations, MutationId, MutationResult, Mutator, MutatorsTuple, ScheduledMutator,
|
||||
@ -80,6 +80,7 @@ where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand,
|
||||
{
|
||||
name: String,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
@ -134,6 +135,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> Named for TuneableScheduledMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
S: HasRand,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, MT, S> ScheduledMutator<I, MT, S> for TuneableScheduledMutator<I, MT, S>
|
||||
where
|
||||
MT: MutatorsTuple<I, S>,
|
||||
@ -215,6 +226,7 @@ where
|
||||
state.add_metadata(TuneableScheduledMutatorMetadata::default());
|
||||
}
|
||||
TuneableScheduledMutator {
|
||||
name: format!("TuneableMutator[{}]", mutations.names().join(", ")),
|
||||
mutations,
|
||||
max_stack_pow: 7,
|
||||
phantom: PhantomData,
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
fuzzer::Evaluator,
|
||||
inputs::Input,
|
||||
mark_feature_time,
|
||||
mutators::{MultipleMutator, MutationResult, Mutator},
|
||||
mutators::{MultiMutator, MutationResult, Mutator},
|
||||
stages::Stage,
|
||||
start_timer,
|
||||
state::{HasClientPerfMonitor, HasCorpus, HasRand, UsesState},
|
||||
@ -260,28 +260,28 @@ where
|
||||
|
||||
/// The default mutational stage
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MultipleMutationalStage<E, EM, I, M, Z> {
|
||||
pub struct MultiMutationalStage<E, EM, I, M, Z> {
|
||||
mutator: M,
|
||||
#[allow(clippy::type_complexity)]
|
||||
phantom: PhantomData<(E, EM, I, Z)>,
|
||||
}
|
||||
|
||||
impl<E, EM, I, M, Z> UsesState for MultipleMutationalStage<E, EM, I, M, Z>
|
||||
impl<E, EM, I, M, Z> UsesState for MultiMutationalStage<E, EM, I, M, Z>
|
||||
where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
M: MultipleMutator<I, Z::State>,
|
||||
M: MultiMutator<I, Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
{
|
||||
type State = Z::State;
|
||||
}
|
||||
|
||||
impl<E, EM, I, M, Z> Stage<E, EM, Z> for MultipleMutationalStage<E, EM, I, M, Z>
|
||||
impl<E, EM, I, M, Z> Stage<E, EM, Z> for MultiMutationalStage<E, EM, I, M, Z>
|
||||
where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
M: MultipleMutator<I, Z::State>,
|
||||
M: MultiMutator<I, Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
I: MutatedTransform<Self::Input, Self::State> + Clone,
|
||||
@ -303,14 +303,13 @@ where
|
||||
};
|
||||
drop(testcase);
|
||||
|
||||
let mut generated = vec![];
|
||||
let _ = self.mutator.mutate(state, &input, &mut generated, 0)?;
|
||||
let generated = self.mutator.multi_mutate(state, &input, 0, None)?;
|
||||
// println!("Generated {}", generated.len());
|
||||
for (i, new_input) in generated.into_iter().enumerate() {
|
||||
// Time is measured directly the `evaluate_input` function
|
||||
let (untransformed, post) = new_input.try_transform_into(state)?;
|
||||
let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, untransformed)?;
|
||||
self.mutator.post_exec(state, i as i32, corpus_idx)?;
|
||||
self.mutator.multi_post_exec(state, i as i32, corpus_idx)?;
|
||||
post.post_exec(state, i as i32, corpus_idx)?;
|
||||
}
|
||||
// println!("Found {}", found);
|
||||
@ -319,11 +318,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, M, Z> MultipleMutationalStage<E, EM, Z::Input, M, Z>
|
||||
impl<E, EM, M, Z> MultiMutationalStage<E, EM, Z::Input, M, Z>
|
||||
where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
M: MultipleMutator<Z::Input, Z::State>,
|
||||
M: MultiMutator<Z::Input, Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
{
|
||||
@ -333,11 +332,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, EM, I, M, Z> MultipleMutationalStage<E, EM, I, M, Z>
|
||||
impl<E, EM, I, M, Z> MultiMutationalStage<E, EM, I, M, Z>
|
||||
where
|
||||
E: UsesState<State = Z::State>,
|
||||
EM: UsesState<State = Z::State>,
|
||||
M: MultipleMutator<I, Z::State>,
|
||||
M: MultiMutator<I, Z::State>,
|
||||
Z: Evaluator<E, EM>,
|
||||
Z::State: HasClientPerfMonitor + HasCorpus + HasRand,
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user