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:
parent
93f67aa405
commit
04d87ccc89
@ -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)
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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(())
|
||||||
|
@ -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()))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user