Remove (almost) unused stage_idx (#1929)

* Remove (almost) unused stage_idx

* Fix text-based test

* fixed critical whitespace

* clippy

* more fmt

* fix push stage
This commit is contained in:
Dominik Maier 2024-03-14 13:14:57 +01:00 committed by GitHub
parent 93f67aa405
commit 04d87ccc89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 148 additions and 499 deletions

View File

@ -46,9 +46,9 @@ class BaseStage:
return Stage.new_py(self)
class BaseMutator:
def mutate(self, state, input, stage_idx):
def mutate(self, state, input):
pass
def post_exec(self, state, stage_idx, corpus_idx):
def post_exec(self, state, corpus_idx):
pass
def as_mutator(self):
return Mutator.new_py(self)

View File

@ -31,10 +31,11 @@ fn signals_set(idx: usize) {
unsafe { SIGNALS[idx] = 1 };
}
#[allow(clippy::similar_names)]
#[allow(clippy::similar_names, clippy::manual_assert)]
pub fn main() {
// Create an observation channel using the signals map
let observer = unsafe { StdMapObserver::new("signals", &mut SIGNALS) };
let observer =
unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) };
// Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer);
@ -90,8 +91,6 @@ pub fn main() {
let exit_kind = Rc::new(Cell::new(None));
let stage_idx = 0;
let observers = tuple_list!(observer);
let shared_state = PushStageSharedState::new(fuzzer, state, observers, mgr);
@ -101,7 +100,6 @@ pub fn main() {
mutator,
Rc::new(RefCell::new(Some(shared_state))),
exit_kind.clone(),
stage_idx,
);
// Loop, the input, getting a new entry from the push stage each iteration.

View File

@ -19,12 +19,7 @@ impl<S> Mutator<PacketData, S> for LainMutator
where
S: HasRand,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut PacketData,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut PacketData) -> Result<MutationResult, Error> {
// Lain uses its own instance of StdRand, but we want to keep it in sync with LibAFL's state.
self.inner.rng_mut().set_seed(state.rand_mut().next());
input.mutate(&mut self.inner, None);

View File

@ -25,12 +25,7 @@ use crate::{
pub struct EncodedRandMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedRandMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
if input.codes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -60,12 +55,7 @@ impl EncodedRandMutator {
pub struct EncodedIncMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedIncMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
if input.codes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -95,12 +85,7 @@ impl EncodedIncMutator {
pub struct EncodedDecMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDecMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
if input.codes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -130,12 +115,7 @@ impl EncodedDecMutator {
pub struct EncodedAddMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedAddMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
if input.codes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -169,12 +149,7 @@ impl EncodedAddMutator {
pub struct EncodedDeleteMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDeleteMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
let size = input.codes().len();
if size <= 2 {
return Ok(MutationResult::Skipped);
@ -212,12 +187,7 @@ impl<S> Mutator<EncodedInput, S> for EncodedInsertCopyMutator
where
S: HasRand + HasMaxSize,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
let max_size = state.max_size();
let size = input.codes().len();
if size == 0 {
@ -272,12 +242,7 @@ impl EncodedInsertCopyMutator {
pub struct EncodedCopyMutator;
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
let size = input.codes().len();
if size <= 1 {
return Ok(MutationResult::Skipped);
@ -317,12 +282,7 @@ impl<S> Mutator<S::Input, S> for EncodedCrossoverInsertMutator
where
S: UsesInput<Input = EncodedInput> + HasRand + HasCorpus + HasMaxSize,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
let size = input.codes().len();
// We don't want to use the testcase we're already using for splicing
@ -391,12 +351,7 @@ impl<S> Mutator<S::Input, S> for EncodedCrossoverReplaceMutator
where
S: UsesInput<Input = EncodedInput> + HasRand + HasCorpus,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut EncodedInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
let size = input.codes().len();
if size == 0 {
return Ok(MutationResult::Skipped);

View File

@ -36,7 +36,6 @@ where
&mut self,
state: &mut S,
input: &mut GramatronInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
if !input.terminals().is_empty() {
let size = state.rand_mut().below(input.terminals().len() as u64 + 1) as usize;
@ -109,7 +108,6 @@ where
&mut self,
state: &mut S,
input: &mut GramatronInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
if input.terminals().is_empty() {
return Ok(MutationResult::Skipped);
@ -180,7 +178,6 @@ where
&mut self,
state: &mut S,
input: &mut GramatronInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
if input.terminals().is_empty() {
return Ok(MutationResult::Skipped);

View File

@ -122,7 +122,6 @@ where
&mut self,
state: &mut S,
generalised_meta: &mut GeneralizedInputMetadata,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
extend_with_random_generalized(
state,
@ -163,7 +162,6 @@ where
&mut self,
state: &mut S,
generalised_meta: &mut GeneralizedInputMetadata,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
let mut mutated = MutationResult::Skipped;
@ -236,7 +234,6 @@ where
&mut self,
state: &mut S,
generalised_meta: &mut GeneralizedInputMetadata,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
let tokens_len = {
let meta = state.metadata_map().get::<Tokens>();
@ -347,7 +344,6 @@ where
&mut self,
state: &mut S,
generalised_meta: &mut GeneralizedInputMetadata,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
let gen = generalised_meta.generalized_mut();

View File

@ -91,12 +91,7 @@ pub enum MutationResult {
/// Simple as that.
pub trait Mutator<I, S>: Named {
/// Mutate a given input
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error>;
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error>;
/// Post-process given the outcome of the execution
/// `new_corpus_idx` will be `Some` if a new `Testcase` was created this execution.
@ -104,7 +99,6 @@ pub trait Mutator<I, S>: Named {
fn post_exec(
&mut self,
_state: &mut S,
_stage_idx: i32,
_new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
Ok(())
@ -120,7 +114,6 @@ pub trait MultiMutator<I, S>: Named {
&mut self,
state: &mut S,
input: &I,
stage_idx: i32,
max_count: Option<usize>,
) -> Result<Vec<I>, Error>;
@ -130,7 +123,6 @@ pub trait MultiMutator<I, S>: Named {
fn multi_post_exec(
&mut self,
_state: &mut S,
_stage_idx: i32,
_new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
Ok(())
@ -140,19 +132,13 @@ pub trait MultiMutator<I, S>: Named {
/// A `Tuple` of `Mutators` that can execute multiple `Mutators` in a row.
pub trait MutatorsTuple<I, S>: HasLen {
/// Runs the `mutate` function on all `Mutators` in this `Tuple`.
fn mutate_all(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error>;
fn mutate_all(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error>;
/// Runs the `post_exec` function on all `Mutators` in this `Tuple`.
/// `new_corpus_idx` will be `Some` if a new `Testcase` was created this execution.
fn post_exec_all(
&mut self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error>;
@ -162,7 +148,6 @@ pub trait MutatorsTuple<I, S>: HasLen {
index: MutationId,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error>;
/// Gets the [`Mutator`] at the given index and runs the `post_exec` function on it.
@ -171,7 +156,7 @@ pub trait MutatorsTuple<I, S>: HasLen {
&mut self,
index: usize,
state: &mut S,
stage_idx: i32,
corpus_idx: Option<CorpusId>,
) -> Result<(), Error>;
@ -184,12 +169,7 @@ pub trait MutatorsTuple<I, S>: HasLen {
impl<I, S> MutatorsTuple<I, S> for () {
#[inline]
fn mutate_all(
&mut self,
_state: &mut S,
_input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate_all(&mut self, _state: &mut S, _input: &mut I) -> Result<MutationResult, Error> {
Ok(MutationResult::Skipped)
}
@ -197,7 +177,6 @@ impl<I, S> MutatorsTuple<I, S> for () {
fn post_exec_all(
&mut self,
_state: &mut S,
_stage_idx: i32,
_new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
Ok(())
@ -209,7 +188,6 @@ impl<I, S> MutatorsTuple<I, S> for () {
_index: MutationId,
_state: &mut S,
_input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
Ok(MutationResult::Skipped)
}
@ -219,7 +197,6 @@ impl<I, S> MutatorsTuple<I, S> for () {
&mut self,
_index: usize,
_state: &mut S,
_stage_idx: i32,
_new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
Ok(())
@ -241,14 +218,9 @@ where
Head: Mutator<I, S>,
Tail: MutatorsTuple<I, S>,
{
fn mutate_all(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
let r = self.0.mutate(state, input, stage_idx)?;
if self.1.mutate_all(state, input, stage_idx)? == MutationResult::Mutated {
fn mutate_all(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let r = self.0.mutate(state, input)?;
if self.1.mutate_all(state, input)? == MutationResult::Mutated {
Ok(MutationResult::Mutated)
} else {
Ok(r)
@ -258,11 +230,10 @@ where
fn post_exec_all(
&mut self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
self.0.post_exec(state, stage_idx, new_corpus_idx)?;
self.1.post_exec_all(state, stage_idx, new_corpus_idx)
self.0.post_exec(state, new_corpus_idx)?;
self.1.post_exec_all(state, new_corpus_idx)
}
fn get_and_mutate(
@ -270,13 +241,11 @@ where
index: MutationId,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
if index.0 == 0 {
self.0.mutate(state, input, stage_idx)
self.0.mutate(state, input)
} else {
self.1
.get_and_mutate((index.0 - 1).into(), state, input, stage_idx)
self.1.get_and_mutate((index.0 - 1).into(), state, input)
}
}
@ -284,14 +253,12 @@ where
&mut self,
index: usize,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
if index == 0 {
self.0.post_exec(state, stage_idx, new_corpus_idx)
self.0.post_exec(state, new_corpus_idx)
} else {
self.1
.get_and_post_exec(index - 1, state, stage_idx, new_corpus_idx)
self.1.get_and_post_exec(index - 1, state, new_corpus_idx)
}
}
@ -331,22 +298,16 @@ impl<Tail, I, S> MutatorsTuple<I, S> for (Tail,)
where
Tail: MutatorsTuple<I, S>,
{
fn mutate_all(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.0.mutate_all(state, input, stage_idx)
fn mutate_all(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.0.mutate_all(state, input)
}
fn post_exec_all(
&mut self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
self.0.post_exec_all(state, stage_idx, new_corpus_idx)
self.0.post_exec_all(state, new_corpus_idx)
}
fn get_and_mutate(
@ -354,20 +315,17 @@ where
index: MutationId,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.0.get_and_mutate(index, state, input, stage_idx)
self.0.get_and_mutate(index, state, input)
}
fn get_and_post_exec(
&mut self,
index: usize,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
self.0
.get_and_post_exec(index, state, stage_idx, new_corpus_idx)
self.0.get_and_post_exec(index, state, new_corpus_idx)
}
fn names(&self) -> Vec<&str> {
@ -389,15 +347,10 @@ where
}
impl<I, S> MutatorsTuple<I, S> for Vec<Box<dyn Mutator<I, S>>> {
fn mutate_all(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate_all(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.iter_mut()
.try_fold(MutationResult::Skipped, |ret, mutator| {
if mutator.mutate(state, input, stage_idx)? == MutationResult::Mutated {
if mutator.mutate(state, input)? == MutationResult::Mutated {
Ok(MutationResult::Mutated)
} else {
Ok(ret)
@ -408,11 +361,10 @@ impl<I, S> MutatorsTuple<I, S> for Vec<Box<dyn Mutator<I, S>>> {
fn post_exec_all(
&mut self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
for mutator in self.iter_mut() {
mutator.post_exec(state, stage_idx, new_corpus_idx)?;
mutator.post_exec(state, new_corpus_idx)?;
}
Ok(())
}
@ -422,25 +374,23 @@ impl<I, S> MutatorsTuple<I, S> for Vec<Box<dyn Mutator<I, S>>> {
index: MutationId,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
let mutator = self
.get_mut(index.0)
.ok_or_else(|| Error::key_not_found("Mutator with id {index:?} not found."))?;
mutator.mutate(state, input, stage_idx)
mutator.mutate(state, input)
}
fn get_and_post_exec(
&mut self,
index: usize,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
let mutator = self
.get_mut(index)
.ok_or_else(|| Error::key_not_found("Mutator with id {index:?} not found."))?;
mutator.post_exec(state, stage_idx, new_corpus_idx)
mutator.post_exec(state, new_corpus_idx)
}
fn names_reversed(&self) -> Vec<&str> {
@ -501,14 +451,13 @@ pub mod pybind {
&mut self,
state: &mut PythonStdState,
input: &mut BytesInput,
stage_idx: i32,
) -> Result<MutationResult, Error> {
let mutated = Python::with_gil(|py| -> PyResult<bool> {
self.inner
.call_method1(
py,
"mutate",
(PythonStdStateWrapper::wrap(state), input.bytes(), stage_idx),
(PythonStdStateWrapper::wrap(state), input.bytes()),
)?
.extract(py)
})?;
@ -522,18 +471,14 @@ pub mod pybind {
fn post_exec(
&mut self,
state: &mut PythonStdState,
stage_idx: i32,
corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
Python::with_gil(|py| -> PyResult<()> {
self.inner.call_method1(
py,
"post_exec",
(
PythonStdStateWrapper::wrap(state),
stage_idx,
corpus_idx.map(|x| x.0),
),
(PythonStdStateWrapper::wrap(state), corpus_idx.map(|x| x.0)),
)?;
Ok(())
})?;
@ -609,20 +554,17 @@ pub mod pybind {
&mut self,
state: &mut PythonStdState,
input: &mut BytesInput,
stage_idx: i32,
) -> Result<MutationResult, Error> {
unwrap_me_mut!(self.wrapper, m, { m.mutate(state, input, stage_idx) })
unwrap_me_mut!(self.wrapper, m, { m.mutate(state, input) })
}
fn post_exec(
&mut self,
state: &mut PythonStdState,
stage_idx: i32,
corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
unwrap_me_mut!(self.wrapper, m, {
m.post_exec(state, stage_idx, corpus_idx)
})
unwrap_me_mut!(self.wrapper, m, { m.post_exec(state, corpus_idx) })
}
}

View File

@ -404,23 +404,13 @@ where
S: HasRand + HasMetadata + HasCorpus + HasSolutions,
{
#[inline]
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.finds_before = state.corpus().count() + state.solutions().count();
self.scheduled_mutate(state, input, stage_idx)
self.scheduled_mutate(state, input)
}
#[allow(clippy::cast_precision_loss)]
fn post_exec(
&mut self,
state: &mut S,
_stage_idx: i32,
_new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, _new_corpus_idx: Option<CorpusId>) -> Result<(), Error> {
let before = self.finds_before;
let after = state.corpus().count() + state.solutions().count();
@ -558,12 +548,7 @@ where
phantom: PhantomData,
})
}
fn core_mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn core_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let mut r = MutationResult::Skipped;
let mopt = state.metadata_map_mut().get_mut::<MOpt>().unwrap();
for i in 0..mopt.operator_num {
@ -572,9 +557,7 @@ where
for _i in 0..self.iterations(state, input) {
let idx = self.schedule(state, input);
let outcome = self
.mutations_mut()
.get_and_mutate(idx, state, input, stage_idx)?;
let outcome = self.mutations_mut().get_and_mutate(idx, state, input)?;
if outcome == MutationResult::Mutated {
r = MutationResult::Mutated;
}
@ -588,12 +571,7 @@ where
Ok(r)
}
fn pilot_mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn pilot_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let mut r = MutationResult::Skipped;
let swarm_now;
{
@ -608,9 +586,7 @@ where
for _i in 0..self.iterations(state, input) {
let idx = self.schedule(state, input);
let outcome = self
.mutations_mut()
.get_and_mutate(idx, state, input, stage_idx)?;
let outcome = self.mutations_mut().get_and_mutate(idx, state, input)?;
if outcome == MutationResult::Mutated {
r = MutationResult::Mutated;
}
@ -675,16 +651,11 @@ where
.unwrap()
}
fn scheduled_mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn scheduled_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let mode = self.mode;
match mode {
MOptMode::Corefuzzing => self.core_mutate(state, input, stage_idx),
MOptMode::Pilotfuzzing => self.pilot_mutate(state, input, stage_idx),
MOptMode::Corefuzzing => self.core_mutate(state, input),
MOptMode::Pilotfuzzing => self.pilot_mutate(state, input),
}
}
}

View File

@ -40,24 +40,18 @@ where
&mut self,
state: &mut S,
input: &mut MultipartInput<I>,
stage_idx: i32,
) -> Result<MutationResult, Error> {
if input.parts().is_empty() {
Ok(MutationResult::Skipped)
} else {
let selected = state.rand_mut().below(input.parts().len() as u64) as usize;
let mutated = input.part_mut(selected).unwrap();
self.mutate(state, mutated, stage_idx)
self.mutate(state, mutated)
}
}
fn post_exec(
&mut self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
M::post_exec(self, state, stage_idx, new_corpus_idx)
fn post_exec(&mut self, state: &mut S, new_corpus_idx: Option<CorpusId>) -> Result<(), Error> {
M::post_exec(self, state, new_corpus_idx)
}
}
@ -129,7 +123,6 @@ where
&mut self,
state: &mut S,
input: &mut MultipartInput<I>,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
// we can eat the slight bias; number of parts will be small
let name_choice = state.rand_mut().next() as usize;
@ -234,7 +227,6 @@ where
&mut self,
state: &mut S,
input: &mut MultipartInput<I>,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
// we can eat the slight bias; number of parts will be small
let name_choice = state.rand_mut().next() as usize;

View File

@ -122,12 +122,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -162,12 +157,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -200,12 +190,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -239,12 +224,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -278,12 +258,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -317,12 +292,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().is_empty() {
Ok(MutationResult::Skipped)
} else {
@ -365,7 +335,7 @@ macro_rules! add_mutator_impl {
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
if input.bytes().len() < size_of::<$size>() {
Ok(MutationResult::Skipped)
@ -428,12 +398,7 @@ macro_rules! interesting_mutator_impl {
I: HasBytesVec,
{
#[allow(clippy::cast_sign_loss)]
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
if input.bytes().len() < size_of::<$size>() {
Ok(MutationResult::Skipped)
} else {
@ -480,12 +445,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size <= 2 {
return Ok(MutationResult::Skipped);
@ -522,12 +482,7 @@ where
S: HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let max_size = state.max_size();
let size = input.bytes().len();
if size == 0 || size >= max_size {
@ -573,12 +528,7 @@ where
S: HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let max_size = state.max_size();
let size = input.bytes().len();
if size == 0 || size >= max_size {
@ -631,12 +581,7 @@ where
S: HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let max_size = state.max_size();
let size = input.bytes().len();
if size >= max_size {
@ -689,12 +634,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size == 0 {
return Ok(MutationResult::Skipped);
@ -732,12 +672,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size == 0 {
return Ok(MutationResult::Skipped);
@ -775,12 +710,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size <= 1 {
return Ok(MutationResult::Skipped);
@ -822,12 +752,7 @@ where
S: HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size <= 1 || size >= state.max_size() {
return Ok(MutationResult::Skipped);
@ -887,12 +812,7 @@ where
S: HasRand,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size <= 1 {
return Ok(MutationResult::Skipped);
@ -1125,12 +1045,7 @@ where
S: HasCorpus<Input = I> + HasRand + HasMaxSize,
I: Input + HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut S::Input,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
let size = input.bytes().len();
let max_size = state.max_size();
if size >= max_size {
@ -1213,12 +1128,7 @@ where
S: HasCorpus<Input = I> + HasRand,
I: Input + HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut S::Input,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size == 0 {
return Ok(MutationResult::Skipped);
@ -1295,12 +1205,7 @@ where
S::Input: HasBytesVec,
{
#[allow(clippy::cast_sign_loss)]
fn mutate(
&mut self,
state: &mut S,
input: &mut S::Input,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
// We don't want to use the testcase we're already using for splicing
let idx = random_corpus_id!(state.corpus(), state.rand_mut());
if let Some(cur) = state.corpus().current() {
@ -1508,7 +1413,7 @@ mod tests {
for input in &inputs {
let mut mutant = input.clone();
match mutations
.get_and_mutate(idx.into(), &mut state, &mut mutant, 0)
.get_and_mutate(idx.into(), &mut state, &mut mutant)
.unwrap()
{
MutationResult::Mutated => new_testcases.push(mutant),
@ -1534,7 +1439,7 @@ mod tests {
for _ in 0..iters {
let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
if mutator.mutate(&mut state, &mut mutated)? == MutationResult::Skipped {
continue;
}
let mut gaps = 0;
@ -1588,7 +1493,7 @@ mod tests {
for _ in 0..iters {
let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
if mutator.mutate(&mut state, &mut mutated)? == MutationResult::Skipped {
continue;
}
let mut expansion = 0;
@ -1637,7 +1542,7 @@ mod tests {
for _ in 0..iters {
let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
if mutator.mutate(&mut state, &mut mutated)? == MutationResult::Skipped {
continue;
}
let mut inserted = 0;
@ -1687,7 +1592,7 @@ mod tests {
for _ in 0..iters {
let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
if mutator.mutate(&mut state, &mut mutated)? == MutationResult::Skipped {
continue;
}
let mut inserted = 10;

View File

@ -35,7 +35,6 @@ impl<S> Mutator<NautilusInput, S> for NautilusRandomMutator<'_> {
&mut self,
_state: &mut S,
input: &mut NautilusInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
// TODO get rid of tmp
let mut tmp = vec![];
@ -96,7 +95,6 @@ impl<S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'_> {
&mut self,
_state: &mut S,
input: &mut NautilusInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
// TODO don't calc recursions here
if let Some(ref mut recursions) = input.tree.calc_recursions(self.ctx) {
@ -162,7 +160,6 @@ where
&mut self,
state: &mut S,
input: &mut NautilusInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
let meta = state
.metadata_map()

View File

@ -93,19 +93,12 @@ where
/// New default implementation for mutate.
/// Implementations must forward `mutate()` to this method
fn scheduled_mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn scheduled_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let mut r = MutationResult::Skipped;
let num = self.iterations(state, input);
for _ in 0..num {
let idx = self.schedule(state, input);
let outcome = self
.mutations_mut()
.get_and_mutate(idx, state, input, stage_idx)?;
let outcome = self.mutations_mut().get_and_mutate(idx, state, input)?;
if outcome == MutationResult::Mutated {
r = MutationResult::Mutated;
}
@ -157,13 +150,8 @@ where
S: HasRand,
{
#[inline]
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input, stage_idx)
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input)
}
}
@ -391,21 +379,11 @@ where
S: HasRand + HasCorpus,
SM: ScheduledMutator<I, MT, S>,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input, stage_idx)
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input)
}
fn post_exec(
&mut self,
state: &mut S,
_stage_idx: i32,
corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, corpus_idx: Option<CorpusId>) -> Result<(), Error> {
if let Some(idx) = corpus_idx {
let mut testcase = (*state.corpus_mut().get(idx)?).borrow_mut();
let mut log = Vec::<String>::new();
@ -456,21 +434,14 @@ where
state.rand_mut().below(MT::LEN as u64).into()
}
fn scheduled_mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_idx: i32,
) -> Result<MutationResult, Error> {
fn scheduled_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let mut r = MutationResult::Skipped;
let num = self.iterations(state, input);
self.mutation_log.clear();
for _ in 0..num {
let idx = self.schedule(state, input);
self.mutation_log.push(idx);
let outcome = self
.mutations_mut()
.get_and_mutate(idx, state, input, stage_idx)?;
let outcome = self.mutations_mut().get_and_mutate(idx, state, input)?;
if outcome == MutationResult::Mutated {
r = MutationResult::Mutated;
}
@ -542,7 +513,7 @@ mod tests {
rand.set_seed(5);
let mut splice = SpliceMutator::new();
splice.mutate(&mut state, &mut input, 0).unwrap();
splice.mutate(&mut state, &mut input).unwrap();
log::trace!("{:?}", input.bytes());
@ -584,8 +555,8 @@ mod tests {
let mut equal_in_a_row = 0;
for i in 0..42 {
havoc.mutate(&mut state, &mut input, i).unwrap();
for _ in 0..42 {
havoc.mutate(&mut state, &mut input).unwrap();
// Make sure we actually mutate something, at least sometimes
equal_in_a_row = if input == input_prior {

View File

@ -49,12 +49,7 @@ impl<S> MutatedTransformPost<S> for StringIdentificationMetadata
where
S: HasTestcase,
{
fn post_exec(
self,
state: &mut S,
_stage_idx: i32,
corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
fn post_exec(self, state: &mut S, corpus_idx: Option<CorpusId>) -> Result<(), Error> {
if let Some(corpus_idx) = corpus_idx {
let mut tc = state.testcase_mut(corpus_idx)?;
tc.add_metadata(self);
@ -284,12 +279,7 @@ impl<S> Mutator<UnicodeInput, S> for StringCategoryRandMutator
where
S: HasRand + HasMaxSize,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut UnicodeInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
if input.0.bytes().is_empty() {
return Ok(MutationResult::Skipped);
}
@ -347,12 +337,7 @@ impl<S> Mutator<UnicodeInput, S> for StringSubcategoryRandMutator
where
S: HasRand + HasMaxSize,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut UnicodeInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
if input.0.bytes().is_empty() {
return Ok(MutationResult::Skipped);
}
@ -398,12 +383,7 @@ impl<S> Mutator<UnicodeInput, S> for StringCategoryTokenReplaceMutator
where
S: HasRand + HasMaxSize + HasMetadata,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut UnicodeInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
if input.0.bytes().is_empty() {
return Ok(MutationResult::Skipped);
}
@ -462,12 +442,7 @@ impl<S> Mutator<UnicodeInput, S> for StringSubcategoryTokenReplaceMutator
where
S: HasRand + HasMaxSize + HasMetadata,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut UnicodeInput,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
if input.0.bytes().is_empty() {
return Ok(MutationResult::Skipped);
}
@ -544,7 +519,7 @@ mod test {
for _ in 0..(1 << 12) {
let metadata = extract_metadata(bytes.bytes());
let mut input = (bytes, metadata);
let _ = mutator.mutate(&mut state, &mut input, 0);
let _ = mutator.mutate(&mut state, &mut input);
println!("{:?}", core::str::from_utf8(input.0.bytes()).unwrap());
bytes = input.0;
}
@ -576,7 +551,7 @@ mod test {
for _ in 0..(1 << 12) {
let metadata = extract_metadata(bytes.bytes());
let mut input = (bytes, metadata);
let _ = mutator.mutate(&mut state, &mut input, 0);
let _ = mutator.mutate(&mut state, &mut input);
println!("{:?}", core::str::from_utf8(input.0.bytes()).unwrap());
bytes = input.0;
}

View File

@ -23,6 +23,7 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
use crate::mutators::str_decode;
use crate::{
corpus::{CorpusId, HasCurrentCorpusIdx},
inputs::{HasBytesVec, UsesInput},
mutators::{
buffer_self_copy, mutations::buffer_copy, MultiMutator, MutationResult, Mutator, Named,
@ -306,12 +307,7 @@ where
S: HasMetadata + HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let max_size = state.max_size();
let tokens_len = {
let Some(meta) = state.metadata_map().get::<Tokens>() else {
@ -373,12 +369,7 @@ where
S: UsesInput + HasMetadata + HasRand + HasMaxSize,
I: HasBytesVec,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size == 0 {
return Ok(MutationResult::Skipped);
@ -437,12 +428,7 @@ where
I: HasBytesVec,
{
#[allow(clippy::too_many_lines)]
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
let size = input.bytes().len();
if size == 0 {
return Ok(MutationResult::Skipped);
@ -629,6 +615,9 @@ pub struct AFLppRedQueen {
enable_transform: bool,
enable_arith: bool,
text_type: TextType,
/// We use this variable to check if we scheduled a new `corpus_idx`
/// - and, hence, need to recalculate `text_type`
last_corpus_idx: Option<CorpusId>,
}
impl AFLppRedQueen {
@ -1095,7 +1084,7 @@ impl AFLppRedQueen {
impl<I, S> MultiMutator<I, S> for AFLppRedQueen
where
S: UsesInput + HasMetadata + HasRand + HasMaxSize + HasCorpus,
S: UsesInput + HasMetadata + HasRand + HasMaxSize + HasCorpus + HasCurrentCorpusIdx,
I: HasBytesVec + From<Vec<u8>>,
{
#[allow(clippy::needless_range_loop)]
@ -1104,7 +1093,6 @@ where
&mut self,
state: &mut S,
input: &I,
stage_idx: i32,
max_count: Option<usize>,
) -> Result<Vec<I>, Error> {
// TODO
@ -1144,8 +1132,10 @@ where
// println!("orig: {:#?} new: {:#?}", orig_cmpvals, new_cmpvals);
// Compute when mutating it for the 1st time.
if stage_idx == 0 {
let current_corpus_idx = state.current_corpus_idx()?.ok_or_else(|| Error::key_not_found("No corpus-idx is currently being fuzzed, but called AFLppRedQueen::multi_mutated()."))?;
if self.last_corpus_idx.is_none() || self.last_corpus_idx.unwrap() != current_corpus_idx {
self.text_type = check_if_text(orig_bytes, orig_bytes.len());
self.last_corpus_idx = Some(current_corpus_idx);
}
// println!("approximate size: {cmp_len} x {input_len}");
for cmp_idx in 0..cmp_len {
@ -1696,6 +1686,7 @@ impl AFLppRedQueen {
enable_transform: false,
enable_arith: false,
text_type: TextType::None,
last_corpus_idx: None,
}
}
@ -1706,6 +1697,7 @@ impl AFLppRedQueen {
enable_transform: transform,
enable_arith: arith,
text_type: TextType::None,
last_corpus_idx: None,
}
}

View File

@ -112,13 +112,8 @@ where
S: HasRand + HasMetadata,
{
#[inline]
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
stage_id: i32,
) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input, stage_id)
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input)
}
}

View File

@ -29,12 +29,7 @@ use crate::{monitors::PerfFeature, state::HasClientPerfMonitor};
pub trait MutatedTransformPost<S>: Sized {
/// Perform any post-execution steps necessary for the transformed input (e.g., updating metadata)
#[inline]
fn post_exec(
self,
state: &mut S,
stage_idx: i32,
new_corpus_idx: Option<CorpusId>,
) -> Result<(), Error> {
fn post_exec(self, state: &mut S, new_corpus_idx: Option<CorpusId>) -> Result<(), Error> {
Ok(())
}
}
@ -123,11 +118,11 @@ where
drop(testcase);
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
for i in 0..num {
for _ in 0..num {
let mut input = input.clone();
start_timer!(state);
let mutated = self.mutator_mut().mutate(state, &mut input, i as i32)?;
let mutated = self.mutator_mut().mutate(state, &mut input)?;
mark_feature_time!(state, PerfFeature::Mutate);
if mutated == MutationResult::Skipped {
@ -139,8 +134,8 @@ where
let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, untransformed)?;
start_timer!(state);
self.mutator_mut().post_exec(state, i as i32, corpus_idx)?;
post.post_exec(state, i as i32, corpus_idx)?;
self.mutator_mut().post_exec(state, corpus_idx)?;
post.post_exec(state, corpus_idx)?;
mark_feature_time!(state, PerfFeature::MutatePostExec);
}
@ -354,14 +349,14 @@ where
};
drop(testcase);
let generated = self.mutator.multi_mutate(state, &input, 0, None)?;
let generated = self.mutator.multi_mutate(state, &input, None)?;
// println!("Generated {}", generated.len());
for (i, new_input) in generated.into_iter().enumerate() {
for new_input in generated {
// 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.multi_post_exec(state, i as i32, corpus_idx)?;
post.post_exec(state, i as i32, corpus_idx)?;
self.mutator.multi_post_exec(state, corpus_idx)?;
post.post_exec(state, corpus_idx)?;
}
// println!("Found {}", found);

View File

@ -53,8 +53,6 @@ where
testcases_to_do: usize,
testcases_done: usize,
stage_idx: i32,
mutator: M,
psh: PushStageHelper<CS, EM, OT, Z>,
@ -150,9 +148,7 @@ where
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
start_timer!(state);
self.mutator
.mutate(state, &mut input, self.stage_idx)
.unwrap();
self.mutator.mutate(state, &mut input).unwrap();
mark_feature_time!(state, PerfFeature::Mutate);
self.push_stage_helper_mut()
@ -176,8 +172,7 @@ where
fuzzer.process_execution(state, event_mgr, last_input, observers, &exit_kind, true)?;
start_timer!(state);
self.mutator
.post_exec(state, self.stage_idx, self.current_corpus_idx)?;
self.mutator.post_exec(state, self.current_corpus_idx)?;
mark_feature_time!(state, PerfFeature::MutatePostExec);
self.testcases_done += 1;
@ -234,7 +229,6 @@ where
mutator: M,
shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, OT, Z>>>>,
exit_kind: Rc<Cell<Option<ExitKind>>>,
stage_idx: i32,
) -> Self {
Self {
mutator,
@ -242,7 +236,6 @@ where
current_corpus_idx: None, // todo
testcases_to_do: 0,
testcases_done: 0,
stage_idx,
}
}
}

View File

@ -100,7 +100,7 @@ where
state.set_max_size(before_len);
start_timer!(state);
let mutated = self.mutator_mut().mutate(state, &mut input, i as i32)?;
let mutated = self.mutator_mut().mutate(state, &mut input)?;
mark_feature_time!(state, PerfFeature::Mutate);
if mutated == MutationResult::Skipped {
@ -148,7 +148,7 @@ where
};
start_timer!(state);
self.mutator_mut().post_exec(state, i as i32, corpus_idx)?;
self.mutator_mut().post_exec(state, corpus_idx)?;
mark_feature_time!(state, PerfFeature::MutatePostExec);
i = next_i;

View File

@ -195,36 +195,36 @@ where
(Some(fuzz_time), Some(iters)) => {
// perform n iterations or fuzz for provided time, whichever comes first
let start_time = current_time();
for i in 1..=iters {
for _ in 1..=iters {
if current_time() - start_time >= fuzz_time {
break;
}
self.perform_mutation(fuzzer, executor, state, manager, &input, i)?;
self.perform_mutation(fuzzer, executor, state, manager, &input)?;
}
}
(Some(fuzz_time), None) => {
// fuzz for provided time
let start_time = current_time();
for i in 1.. {
for _ in 1.. {
if current_time() - start_time >= fuzz_time {
break;
}
self.perform_mutation(fuzzer, executor, state, manager, &input, i)?;
self.perform_mutation(fuzzer, executor, state, manager, &input)?;
}
}
(None, Some(iters)) => {
// perform n iterations
for i in 1..=iters {
self.perform_mutation(fuzzer, executor, state, manager, &input, i)?;
for _ in 1..=iters {
self.perform_mutation(fuzzer, executor, state, manager, &input)?;
}
}
(None, None) => {
// fall back to random
let iters = self.iterations(state)? - self.execs_since_progress_start(state)?;
for i in 1..=iters {
self.perform_mutation(fuzzer, executor, state, manager, &input, i)?;
for _ in 1..=iters {
self.perform_mutation(fuzzer, executor, state, manager, &input)?;
}
}
}
@ -444,14 +444,11 @@ where
state: &mut Z::State,
manager: &mut EM,
input: &I,
stage_idx: u64,
) -> Result<(), Error> {
let mut input = input.clone();
start_timer!(state);
let mutated = self
.mutator_mut()
.mutate(state, &mut input, stage_idx as i32)?;
let mutated = self.mutator_mut().mutate(state, &mut input)?;
mark_feature_time!(state, PerfFeature::Mutate);
if mutated == MutationResult::Skipped {
@ -463,9 +460,8 @@ where
let (_, corpus_idx) = fuzzer.evaluate_input(state, executor, manager, untransformed)?;
start_timer!(state);
self.mutator_mut()
.post_exec(state, stage_idx as i32, corpus_idx)?;
post.post_exec(state, stage_idx as i32, corpus_idx)?;
self.mutator_mut().post_exec(state, corpus_idx)?;
post.post_exec(state, corpus_idx)?;
mark_feature_time!(state, PerfFeature::MutatePostExec);
Ok(())

View File

@ -87,7 +87,6 @@ struct MutatorProxy<'a, M, MT, S> {
/// The result of mutation, to be propagated to the mutational stage
result: Rc<RefCell<Result<MutationResult, Error>>>,
/// Stage index, which is used by libafl mutator implementations
stage_idx: i32,
phantom: PhantomData<(&'a mut (), MT)>,
}
@ -97,13 +96,11 @@ impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> {
state: &'a mut S,
mutator: &Rc<RefCell<M>>,
result: &Rc<RefCell<Result<MutationResult, Error>>>,
stage_idx: i32,
) -> Self {
Self {
state: Rc::new(RefCell::new(state)),
mutator: Rc::downgrade(mutator),
result: result.clone(),
stage_idx,
phantom: PhantomData,
}
}
@ -126,7 +123,6 @@ impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> {
false
},
mutator: self.mutator.clone(),
stage_idx: self.stage_idx,
result: self.result.clone(),
phantom: PhantomData,
}
@ -143,7 +139,7 @@ struct WeakMutatorProxy<F, M, MT, S> {
/// A weak reference to the mutator
mutator: Weak<RefCell<M>>,
/// The stage index to provide to the mutator, when executed.
stage_idx: i32,
/// The result of mutation, to be propagated to the mutational stage
result: Rc<RefCell<Result<MutationResult, Error>>>,
phantom: PhantomData<(MT, S)>,
@ -165,7 +161,7 @@ where
BytesInput::from(unsafe { core::slice::from_raw_parts(data, size) });
let old = state.max_size();
state.set_max_size(max_size);
let res = mutator.scheduled_mutate(state, &mut intermediary, self.stage_idx);
let res = mutator.scheduled_mutate(state, &mut intermediary);
state.set_max_size(old);
let succeeded = res.is_ok();
@ -295,13 +291,8 @@ where
SM: ScheduledMutator<BytesInput, MT, S> + 'static,
{
#[inline]
fn mutate(
&mut self,
state: &mut S,
input: &mut S::Input,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input, stage_idx)
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input)
}
}
@ -325,7 +316,6 @@ where
&mut self,
state: &mut S,
input: &mut S::Input,
stage_idx: i32,
) -> Result<MutationResult, Error> {
let seed = state.rand_mut().next();
let target = input.bytes();
@ -335,7 +325,7 @@ where
// we assume that the fuzzer did not use this mutator, but instead utilised their own
let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated)));
let proxy = MutatorProxy::new(state, &self.mutator, &result, stage_idx);
let proxy = MutatorProxy::new(state, &self.mutator, &result);
let old = MUTATOR.with(|mutator| {
let mut mutator = mutator.borrow_mut();
mutator.replace(Box::new(proxy.weak()))
@ -375,13 +365,8 @@ where
SM: ScheduledMutator<BytesInput, MT, S> + 'static,
{
#[inline]
fn mutate(
&mut self,
state: &mut S,
input: &mut S::Input,
stage_idx: i32,
) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input, stage_idx)
fn mutate(&mut self, state: &mut S, input: &mut S::Input) -> Result<MutationResult, Error> {
self.scheduled_mutate(state, input)
}
}
@ -405,7 +390,6 @@ where
&mut self,
state: &mut S,
input: &mut S::Input,
stage_idx: i32,
) -> Result<MutationResult, Error> {
// We don't want to use the testcase we're already using for splicing
let idx = random_corpus_id!(state.corpus(), state.rand_mut());
@ -426,7 +410,7 @@ where
// we assume that the fuzzer did not use this mutator, but instead utilised their own
let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated)));
let proxy = MutatorProxy::new(state, &self.mutator, &result, stage_idx);
let proxy = MutatorProxy::new(state, &self.mutator, &result);
let old = MUTATOR.with(|mutator| {
let mut mutator = mutator.borrow_mut();
mutator.replace(Box::new(proxy.weak()))