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) return Stage.new_py(self)
class BaseMutator: class BaseMutator:
def mutate(self, state, input, stage_idx): def mutate(self, state, input):
pass pass
def post_exec(self, state, stage_idx, corpus_idx): def post_exec(self, state, corpus_idx):
pass pass
def as_mutator(self): def as_mutator(self):
return Mutator.new_py(self) return Mutator.new_py(self)

View File

@ -31,10 +31,11 @@ fn signals_set(idx: usize) {
unsafe { SIGNALS[idx] = 1 }; unsafe { SIGNALS[idx] = 1 };
} }
#[allow(clippy::similar_names)] #[allow(clippy::similar_names, clippy::manual_assert)]
pub fn main() { pub fn main() {
// Create an observation channel using the signals map // 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 // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -90,8 +91,6 @@ pub fn main() {
let exit_kind = Rc::new(Cell::new(None)); let exit_kind = Rc::new(Cell::new(None));
let stage_idx = 0;
let observers = tuple_list!(observer); let observers = tuple_list!(observer);
let shared_state = PushStageSharedState::new(fuzzer, state, observers, mgr); let shared_state = PushStageSharedState::new(fuzzer, state, observers, mgr);
@ -101,7 +100,6 @@ pub fn main() {
mutator, mutator,
Rc::new(RefCell::new(Some(shared_state))), Rc::new(RefCell::new(Some(shared_state))),
exit_kind.clone(), exit_kind.clone(),
stage_idx,
); );
// Loop, the input, getting a new entry from the push stage each iteration. // 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 where
S: HasRand, S: HasRand,
{ {
fn mutate( fn mutate(&mut self, state: &mut S, input: &mut PacketData) -> Result<MutationResult, Error> {
&mut self,
state: &mut S,
input: &mut PacketData,
_stage_idx: i32,
) -> Result<MutationResult, Error> {
// Lain uses its own instance of StdRand, but we want to keep it in sync with LibAFL's state. // 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()); self.inner.rng_mut().set_seed(state.rand_mut().next());
input.mutate(&mut self.inner, None); input.mutate(&mut self.inner, None);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -100,7 +100,7 @@ where
state.set_max_size(before_len); state.set_max_size(before_len);
start_timer!(state); 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); mark_feature_time!(state, PerfFeature::Mutate);
if mutated == MutationResult::Skipped { if mutated == MutationResult::Skipped {
@ -148,7 +148,7 @@ where
}; };
start_timer!(state); 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); mark_feature_time!(state, PerfFeature::MutatePostExec);
i = next_i; i = next_i;

View File

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

View File

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