Reduce generics for various Has* traits (#456)

Specifically for Has{Rand,Corpus,Solutions,FeedbackStates}

The Has* family of traits offer getters and get-mut-ers. The previous
implementation had a fully generic return type:

    trait HasX<X: TraitX> {
        get_x(&self) -> &Self::X;
        get_mut_x(&mut self) -> &mut Self::X;
    }

meaning a single type could implement both `HasRand<Romu>` and
`HasRand<XorShift>`. The advantage of having multiple implementations is
not clear at this time, so it vastly simplifies the trait (and its
impls) to bring the return type in the body as an associated type:

    trait HasX {
        type X: TraitX;
        get_x(&self) -> &Self::X;
        get_mut_x(&mut self) -> &mut Self::X;
    }

This comes with the limitation that any type that impls these traits can
only do so once, choosing only one associated type.

* HasRand's only generic parameter (Rand) is now an associated type
* HasCorpus and HasSolutions are now only generic over the Input type
  they store
* HasFeedbackStates generic parameter now associated type
This commit is contained in:
Evan Richter 2022-01-06 03:41:02 -06:00 committed by GitHub
parent 30eb1508de
commit 250ec8d1e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 586 additions and 1583 deletions

View File

@ -41,7 +41,7 @@ pub fn main() {
let feedback_state = MapFeedbackState::with_observer(&observer); let feedback_state = MapFeedbackState::with_observer(&observer);
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let feedback = MaxMapFeedback::<_, BytesInput, _, _, _>::new(&feedback_state, &observer); let feedback = MaxMapFeedback::<BytesInput, _, _, _>::new(&feedback_state, &observer);
// A feedback to choose if an input is a solution or not // A feedback to choose if an input is a solution or not
let objective = CrashFeedback::new(); let objective = CrashFeedback::new();

View File

@ -29,8 +29,8 @@ impl FavFactor<PacketData> for PacketLenFavFactor {
} }
} }
pub type PacketLenMinimizerCorpusScheduler<C, CS, R, S> = pub type PacketLenMinimizerCorpusScheduler<CS, S> =
MinimizerCorpusScheduler<C, CS, PacketLenFavFactor, PacketData, MapIndexesMetadata, R, S>; MinimizerCorpusScheduler<CS, PacketLenFavFactor, PacketData, MapIndexesMetadata, S>;
#[derive(Serialize, Deserialize, Default, Clone, Debug)] #[derive(Serialize, Deserialize, Default, Clone, Debug)]
pub struct PacketLenFeedback { pub struct PacketLenFeedback {

View File

@ -10,23 +10,13 @@ use libafl::{
use crate::input::PacketData; use crate::input::PacketData;
use core::marker::PhantomData;
use lain::traits::Mutatable; use lain::traits::Mutatable;
pub struct LainMutator<R, S> pub struct LainMutator {
where
S: HasRand<R>,
R: Rand,
{
inner: lain::mutator::Mutator<StdRand>, inner: lain::mutator::Mutator<StdRand>,
phantom: PhantomData<*const (R, S)>,
} }
impl<R, S> Mutator<PacketData, S> for LainMutator<R, S> impl<S: HasRand> Mutator<PacketData, S> for LainMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -40,35 +30,22 @@ where
} }
} }
impl<R, S> Named for LainMutator<R, S> impl Named for LainMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"LainMutator" "LainMutator"
} }
} }
impl<R, S> LainMutator<R, S> impl LainMutator {
where
S: HasRand<R>,
R: Rand,
{
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
inner: lain::mutator::Mutator::new(StdRand::with_seed(0)), inner: lain::mutator::Mutator::new(StdRand::with_seed(0)),
phantom: PhantomData,
} }
} }
} }
impl<R, S> Default for LainMutator<R, S> impl Default for LainMutator {
where
S: HasRand<R>,
R: Rand,
{
#[must_use] #[must_use]
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()

View File

@ -81,29 +81,26 @@ where
/// corpus that exercise all the requested features (e.g. all the coverage seen so far) /// corpus that exercise all the requested features (e.g. all the coverage seen so far)
/// prioritizing [`Testcase`]`s` using [`FavFactor`] /// prioritizing [`Testcase`]`s` using [`FavFactor`]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MinimizerCorpusScheduler<C, CS, F, I, M, R, S> pub struct MinimizerCorpusScheduler<CS, F, I, M, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt, M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata, S: HasCorpus<I> + HasMetadata,
C: Corpus<I>,
{ {
base: CS, base: CS,
skip_non_favored_prob: u64, skip_non_favored_prob: u64,
phantom: PhantomData<(C, F, I, M, R, S)>, phantom: PhantomData<(F, I, M, S)>,
} }
impl<C, CS, F, I, M, R, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<C, CS, F, I, M, R, S> impl<CS, F, I, M, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<CS, F, I, M, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt, M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata + HasRand<R>, S: HasCorpus<I> + HasMetadata + HasRand,
C: Corpus<I>,
R: Rand,
{ {
/// Add an entry to the corpus and return its index /// Add an entry to the corpus and return its index
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> { fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
@ -145,15 +142,13 @@ where
} }
} }
impl<C, CS, F, I, M, R, S> MinimizerCorpusScheduler<C, CS, F, I, M, R, S> impl<CS, F, I, M, S> MinimizerCorpusScheduler<CS, F, I, M, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: FavFactor<I>, F: FavFactor<I>,
I: Input, I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt, M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata + HasRand<R>, S: HasCorpus<I> + HasMetadata + HasRand,
C: Corpus<I>,
R: Rand,
{ {
/// Update the `Corpus` score using the `MinimizerCorpusScheduler` /// Update the `Corpus` score using the `MinimizerCorpusScheduler`
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
@ -284,10 +279,10 @@ where
} }
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`. /// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`.
pub type LenTimeMinimizerCorpusScheduler<C, CS, I, M, R, S> = pub type LenTimeMinimizerCorpusScheduler<CS, I, M, S> =
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, M, R, S>; MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, M, S>;
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s` /// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`
/// that exercise all the entries registered in the [`MapIndexesMetadata`]. /// that exercise all the entries registered in the [`MapIndexesMetadata`].
pub type IndexesLenTimeMinimizerCorpusScheduler<C, CS, I, R, S> = pub type IndexesLenTimeMinimizerCorpusScheduler<CS, I, S> =
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, R, S>; MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, S>;

View File

@ -30,7 +30,7 @@ pub mod powersched;
pub use powersched::PowerQueueCorpusScheduler; pub use powersched::PowerQueueCorpusScheduler;
use alloc::borrow::ToOwned; use alloc::borrow::ToOwned;
use core::{cell::RefCell, marker::PhantomData}; use core::cell::RefCell;
use crate::{ use crate::{
bolts::rands::Rand, bolts::rands::Rand,
@ -108,22 +108,12 @@ where
/// Feed the fuzzer simpply with a random testcase on request /// Feed the fuzzer simpply with a random testcase on request
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RandCorpusScheduler<C, I, R, S> pub struct RandCorpusScheduler;
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
phantom: PhantomData<(C, I, R, S)>,
}
impl<C, I, R, S> CorpusScheduler<I, S> for RandCorpusScheduler<C, I, R, S> impl<I, S> CorpusScheduler<I, S> for RandCorpusScheduler
where where
S: HasCorpus<C, I> + HasRand<R>, S: HasCorpus<I> + HasRand,
C: Corpus<I>,
I: Input, I: Input,
R: Rand,
{ {
/// Gets the next entry at random /// Gets the next entry at random
fn next(&self, state: &mut S) -> Result<usize, Error> { fn next(&self, state: &mut S) -> Result<usize, Error> {
@ -138,29 +128,15 @@ where
} }
} }
impl<C, I, R, S> RandCorpusScheduler<C, I, R, S> impl RandCorpusScheduler {
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
/// Create a new [`RandCorpusScheduler`] that just schedules randomly. /// Create a new [`RandCorpusScheduler`] that just schedules randomly.
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
impl<C, I, R, S> Default for RandCorpusScheduler<C, I, R, S> impl Default for RandCorpusScheduler {
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
@ -168,4 +144,4 @@ where
/// A [`StdCorpusScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s /// A [`StdCorpusScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s
/// The current `Std` is a [`RandCorpusScheduler`], although this may change in the future, if another [`CorpusScheduler`] delivers better results. /// The current `Std` is a [`RandCorpusScheduler`], although this may change in the future, if another [`CorpusScheduler`] delivers better results.
pub type StdCorpusScheduler<C, I, R, S> = RandCorpusScheduler<C, I, R, S>; pub type StdCorpusScheduler = RandCorpusScheduler;

View File

@ -1,7 +1,6 @@
//! The queue corpus scheduler for power schedules. //! The queue corpus scheduler for power schedules.
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use core::marker::PhantomData;
use crate::{ use crate::{
corpus::{Corpus, CorpusScheduler, PowerScheduleTestcaseMetaData}, corpus::{Corpus, CorpusScheduler, PowerScheduleTestcaseMetaData},
@ -13,30 +12,17 @@ use crate::{
/// A corpus scheduler using power schedules /// A corpus scheduler using power schedules
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PowerQueueCorpusScheduler<C, I, S> pub struct PowerQueueCorpusScheduler;
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
phantom: PhantomData<(C, I, S)>,
}
impl<C, I, S> Default for PowerQueueCorpusScheduler<C, I, S> impl Default for PowerQueueCorpusScheduler {
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl<C, I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler<C, I, S> impl<I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler
where where
S: HasCorpus<C, I> + HasMetadata, S: HasCorpus<I> + HasMetadata,
C: Corpus<I>,
I: Input, I: Input,
{ {
/// Add an entry to the corpus and return its index /// Add an entry to the corpus and return its index
@ -92,17 +78,10 @@ where
} }
} }
impl<C, I, S> PowerQueueCorpusScheduler<C, I, S> impl PowerQueueCorpusScheduler {
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
/// Create a new [`PowerQueueCorpusScheduler`] /// Create a new [`PowerQueueCorpusScheduler`]
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }

View File

@ -1,7 +1,6 @@
//! The queue corpus scheduler implements an AFL-like queue mechanism //! The queue corpus scheduler implements an AFL-like queue mechanism
use alloc::borrow::ToOwned; use alloc::borrow::ToOwned;
use core::marker::PhantomData;
use crate::{ use crate::{
corpus::{Corpus, CorpusScheduler}, corpus::{Corpus, CorpusScheduler},
@ -12,19 +11,11 @@ use crate::{
/// Walk the corpus in a queue-like fashion /// Walk the corpus in a queue-like fashion
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct QueueCorpusScheduler<C, I, S> pub struct QueueCorpusScheduler;
where
S: HasCorpus<C, I>,
C: Corpus<I>,
I: Input,
{
phantom: PhantomData<(C, I, S)>,
}
impl<C, I, S> CorpusScheduler<I, S> for QueueCorpusScheduler<C, I, S> impl<I, S> CorpusScheduler<I, S> for QueueCorpusScheduler
where where
S: HasCorpus<C, I>, S: HasCorpus<I>,
C: Corpus<I>,
I: Input, I: Input,
{ {
/// Gets the next entry in the queue /// Gets the next entry in the queue
@ -48,27 +39,15 @@ where
} }
} }
impl<C, I, S> QueueCorpusScheduler<C, I, S> impl QueueCorpusScheduler {
where
S: HasCorpus<C, I>,
C: Corpus<I>,
I: Input,
{
/// Creates a new `QueueCorpusScheduler` /// Creates a new `QueueCorpusScheduler`
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
impl<C, I, S> Default for QueueCorpusScheduler<C, I, S> impl Default for QueueCorpusScheduler {
where
S: HasCorpus<C, I>,
C: Corpus<I>,
I: Input,
{
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }

View File

@ -11,10 +11,7 @@ use crate::{
}; };
use alloc::{string::ToString, vec::Vec}; use alloc::{string::ToString, vec::Vec};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use core::{ use core::sync::atomic::{compiler_fence, Ordering};
marker::PhantomData,
sync::atomic::{compiler_fence, Ordering},
};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
@ -232,11 +229,9 @@ where
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[allow(clippy::default_trait_access)] #[allow(clippy::default_trait_access)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP> pub struct SimpleRestartingEventManager<I, MT, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>, MT: Monitor, //CE: CustomEvent<I, OT>,
{ {
@ -244,17 +239,12 @@ where
simple_event_mgr: SimpleEventManager<I, MT>, simple_event_mgr: SimpleEventManager<I, MT>,
/// [`StateRestorer`] for restarts /// [`StateRestorer`] for restarts
staterestorer: StateRestorer<SP>, staterestorer: StateRestorer<SP>,
/// Phantom data
_phantom: PhantomData<&'a (C, I, S, SC)>,
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> EventFirer<I> impl<I, MT, SP> EventFirer<I> for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>, MT: Monitor, //CE: CustomEvent<I, OT>,
{ {
@ -264,10 +254,8 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> EventRestarter<S> impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize, S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
@ -282,10 +270,8 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, E, I, MT, S, SC, SP, Z> EventProcessor<E, I, S, Z> impl<E, I, S, SP, MT, Z> EventProcessor<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize, S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
@ -297,10 +283,8 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, E, I, MT, S, SC, SP, Z> EventManager<E, I, S, Z> impl<E, I, S, SP, MT, Z> EventManager<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize, S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
@ -309,24 +293,18 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> ProgressReporter<I> impl<I, MT, SP> ProgressReporter<I> for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
I: Input, I: Input,
C: Corpus<I>,
S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>, MT: Monitor, //CE: CustomEvent<I, OT>,
{ {
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> HasEventManagerId impl<I, MT, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, SP>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: Serialize,
SP: ShMemProvider, SP: ShMemProvider,
MT: Monitor, MT: Monitor,
{ {
@ -337,12 +315,9 @@ where
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[allow(clippy::type_complexity, clippy::too_many_lines)] #[allow(clippy::type_complexity, clippy::too_many_lines)]
impl<'a, C, I, MT, S, SC, SP> SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP> impl<'a, I, MT, SP> SimpleRestartingEventManager<I, MT, SP>
where where
C: Corpus<I>,
I: Input, I: Input,
S: DeserializeOwned + Serialize + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
SP: ShMemProvider, SP: ShMemProvider,
MT: Monitor, //TODO CE: CustomEvent, MT: Monitor, //TODO CE: CustomEvent,
{ {
@ -351,7 +326,6 @@ where
Self { Self {
staterestorer, staterestorer,
simple_event_mgr: SimpleEventManager::new(monitor), simple_event_mgr: SimpleEventManager::new(monitor),
_phantom: PhantomData {},
} }
} }
@ -359,7 +333,10 @@ where
/// This [`EventManager`] is simple and single threaded, /// This [`EventManager`] is simple and single threaded,
/// but can still used shared maps to recover from crashes and timeouts. /// but can still used shared maps to recover from crashes and timeouts.
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
pub fn launch(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error> { pub fn launch<S>(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
where
S: DeserializeOwned + Serialize + HasCorpus<I> + HasSolutions<I>,
{
// We start ourself as child process to actually fuzz // We start ourself as child process to actually fuzz
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() { let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
// First, create a place to store state in, for restarts. // First, create a place to store state in, for restarts.

View File

@ -34,7 +34,6 @@ use crate::bolts::os::windows_exceptions::setup_exception_handler;
use windows::Win32::System::Threading::SetThreadStackGuarantee; use windows::Win32::System::Threading::SetThreadStackGuarantee;
use crate::{ use crate::{
corpus::Corpus,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{Executor, ExitKind, HasObservers}, executors::{Executor, ExitKind, HasObservers},
feedbacks::Feedback, feedbacks::Feedback,
@ -127,7 +126,7 @@ where
/// * `harness_fn` - the harness, executiong the function /// * `harness_fn` - the harness, executiong the function
/// * `observers` - the observers observing the target during execution /// * `observers` - the observers observing the target during execution
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
pub fn new<EM, OC, OF, Z>( pub fn new<EM, OF, Z>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
_fuzzer: &mut Z, _fuzzer: &mut Z,
@ -136,12 +135,11 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
let handlers = InProcessHandlers::new::<Self, EM, I, OC, OF, OT, S, Z>()?; let handlers = InProcessHandlers::new::<Self, EM, I, OF, OT, S, Z>()?;
#[cfg(windows)] #[cfg(windows)]
unsafe { unsafe {
/* /*
@ -267,15 +265,14 @@ impl InProcessHandlers {
} }
/// Create new [`InProcessHandlers`]. /// Create new [`InProcessHandlers`].
pub fn new<E, EM, I, OC, OF, OT, S, Z>() -> Result<Self, Error> pub fn new<E, EM, I, OF, OT, S, Z>() -> Result<Self, Error>
where where
I: Input, I: Input,
E: HasObservers<I, OT, S>, E: HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
#[cfg(unix)] #[cfg(unix)]
@ -285,18 +282,10 @@ impl InProcessHandlers {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OC, OF, OT, S, Z> crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, OT, S, Z>
as *const _,
timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, OT, S, Z>
as *const _, as *const _,
timeout_handler: unix_signal_handler::inproc_timeout_handler::<
E,
EM,
I,
OC,
OF,
OT,
S,
Z,
> as *const _,
}) })
} }
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]
@ -310,7 +299,6 @@ impl InProcessHandlers {
E, E,
EM, EM,
I, I,
OC,
OF, OF,
OT, OT,
S, S,
@ -320,7 +308,6 @@ impl InProcessHandlers {
E, E,
EM, EM,
I, I,
OC,
OF, OF,
OT, OT,
S, S,
@ -493,7 +480,7 @@ mod unix_signal_handler {
} }
#[cfg(unix)] #[cfg(unix)]
pub unsafe fn inproc_timeout_handler<E, EM, I, OC, OF, OT, S, Z>( pub unsafe fn inproc_timeout_handler<E, EM, I, OF, OT, S, Z>(
_signal: Signal, _signal: Signal,
_info: siginfo_t, _info: siginfo_t,
_context: &mut ucontext_t, _context: &mut ucontext_t,
@ -502,9 +489,8 @@ mod unix_signal_handler {
E: HasObservers<I, OT, S>, E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
I: Input, I: Input,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
@ -571,7 +557,7 @@ mod unix_signal_handler {
/// Will be used for signal handling. /// Will be used for signal handling.
/// It will store the current State to shmem, then exit. /// It will store the current State to shmem, then exit.
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub unsafe fn inproc_crash_handler<E, EM, I, OC, OF, OT, S, Z>( pub unsafe fn inproc_crash_handler<E, EM, I, OF, OT, S, Z>(
signal: Signal, signal: Signal,
_info: siginfo_t, _info: siginfo_t,
_context: &mut ucontext_t, _context: &mut ucontext_t,
@ -580,9 +566,8 @@ mod unix_signal_handler {
E: HasObservers<I, OT, S>, E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
I: Input, I: Input,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
@ -748,7 +733,7 @@ mod windows_exception_handler {
EnterCriticalSection, LeaveCriticalSection, RTL_CRITICAL_SECTION, EnterCriticalSection, LeaveCriticalSection, RTL_CRITICAL_SECTION,
}; };
pub unsafe extern "system" fn inproc_timeout_handler<E, EM, I, OC, OF, OT, S, Z>( pub unsafe extern "system" fn inproc_timeout_handler<E, EM, I, OF, OT, S, Z>(
_p0: *mut u8, _p0: *mut u8,
global_state: *mut c_void, global_state: *mut c_void,
_p1: *mut u8, _p1: *mut u8,
@ -756,9 +741,8 @@ mod windows_exception_handler {
E: HasObservers<I, OT, S>, E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
I: Input, I: Input,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
@ -847,16 +831,15 @@ mod windows_exception_handler {
// println!("TIMER INVOKED!"); // println!("TIMER INVOKED!");
} }
pub unsafe fn inproc_crash_handler<E, EM, I, OC, OF, OT, S, Z>( pub unsafe fn inproc_crash_handler<E, EM, I, OF, OT, S, Z>(
exception_pointers: *mut EXCEPTION_POINTERS, exception_pointers: *mut EXCEPTION_POINTERS,
data: &mut InProcessExecutorHandlerData, data: &mut InProcessExecutorHandlerData,
) where ) where
E: HasObservers<I, OT, S>, E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
I: Input, I: Input,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
@ -1085,7 +1068,7 @@ where
SP: ShMemProvider, SP: ShMemProvider,
{ {
/// Creates a new [`InProcessForkExecutor`] /// Creates a new [`InProcessForkExecutor`]
pub fn new<EM, OC, OF, Z>( pub fn new<EM, OF, Z>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
_fuzzer: &mut Z, _fuzzer: &mut Z,
@ -1095,9 +1078,8 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
Ok(Self { Ok(Self {

View File

@ -9,11 +9,14 @@ use num_traits::PrimInt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
bolts::{tuples::Named, AsSlice, HasRefCnt}, bolts::{
tuples::{MatchName, Named},
AsSlice, HasRefCnt,
},
corpus::Testcase, corpus::Testcase,
events::{Event, EventFirer}, events::{Event, EventFirer},
executors::ExitKind, executors::ExitKind,
feedbacks::{Feedback, FeedbackState, FeedbackStatesTuple}, feedbacks::{Feedback, FeedbackState},
inputs::Input, inputs::Input,
monitors::UserStats, monitors::UserStats,
observers::{MapObserver, ObserversTuple}, observers::{MapObserver, ObserversTuple},
@ -22,21 +25,20 @@ use crate::{
}; };
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``. /// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
pub type AflMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, OrReducer, S, T>; pub type AflMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, OrReducer, S, T>;
/// A [`MapFeedback`] that strives to maximize the map contents. /// A [`MapFeedback`] that strives to maximize the map contents.
pub type MaxMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, MaxReducer, S, T>; pub type MaxMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, MaxReducer, S, T>;
/// A [`MapFeedback`] that strives to minimize the map contents. /// A [`MapFeedback`] that strives to minimize the map contents.
pub type MinMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, MinReducer, S, T>; pub type MinMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, MinReducer, S, T>;
/// A [`MapFeedback`] that strives to maximize the map contents, /// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous. /// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapPow2Feedback<FT, I, O, S, T> = pub type MaxMapPow2Feedback<I, O, S, T> = MapFeedback<I, NextPow2IsNovel, O, MaxReducer, S, T>;
MapFeedback<FT, I, NextPow2IsNovel, O, MaxReducer, S, T>;
/// A [`MapFeedback`] that strives to maximize the map contents, /// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous. /// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapOneOrFilledFeedback<FT, I, O, S, T> = pub type MaxMapOneOrFilledFeedback<I, O, S, T> =
MapFeedback<FT, I, OneOrFilledIsNovel, O, MaxReducer, S, T>; MapFeedback<I, OneOrFilledIsNovel, O, MaxReducer, S, T>;
/// A `Reducer` function is used to aggregate values for the novelty search /// A `Reducer` function is used to aggregate values for the novelty search
pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static + Debug pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static + Debug
@ -329,14 +331,13 @@ where
/// The most common AFL-like feedback type /// The most common AFL-like feedback type
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")] #[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct MapFeedback<FT, I, N, O, R, S, T> pub struct MapFeedback<I, N, O, R, S, T>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
N: IsNovel<T>, N: IsNovel<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates,
FT: FeedbackStatesTuple,
{ {
/// Indexes used in the last observation /// Indexes used in the last observation
indexes: Option<Vec<usize>>, indexes: Option<Vec<usize>>,
@ -347,18 +348,17 @@ where
/// Name identifier of the observer /// Name identifier of the observer
observer_name: String, observer_name: String,
/// Phantom Data of Reducer /// Phantom Data of Reducer
phantom: PhantomData<(FT, I, N, S, R, O, T)>, phantom: PhantomData<(I, N, S, R, O, T)>,
} }
impl<FT, I, N, O, R, S, T> Feedback<I, S> for MapFeedback<FT, I, N, O, R, S, T> impl<I, N, O, R, S, T> Feedback<I, S> for MapFeedback<I, N, O, R, S, T>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
N: IsNovel<T>, N: IsNovel<T>,
I: Input, I: Input,
S: HasFeedbackStates<FT> + HasClientPerfMonitor + Debug, S: HasFeedbackStates + HasClientPerfMonitor + Debug,
FT: FeedbackStatesTuple,
{ {
fn is_interesting<EM, OT>( fn is_interesting<EM, OT>(
&mut self, &mut self,
@ -459,14 +459,13 @@ where
} }
} }
impl<FT, I, N, O, R, S, T> Named for MapFeedback<FT, I, N, O, R, S, T> impl<I, N, O, R, S, T> Named for MapFeedback<I, N, O, R, S, T>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>, R: Reducer<T>,
N: IsNovel<T>, N: IsNovel<T>,
O: MapObserver<T>, O: MapObserver<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates,
FT: FeedbackStatesTuple,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -474,7 +473,7 @@ where
} }
} }
impl<FT, I, N, O, R, S, T> MapFeedback<FT, I, N, O, R, S, T> impl<I, N, O, R, S, T> MapFeedback<I, N, O, R, S, T>
where where
T: PrimInt T: PrimInt
+ Default + Default
@ -487,8 +486,7 @@ where
R: Reducer<T>, R: Reducer<T>,
N: IsNovel<T>, N: IsNovel<T>,
O: MapObserver<T>, O: MapObserver<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates,
FT: FeedbackStatesTuple,
{ {
/// Create new `MapFeedback` /// Create new `MapFeedback`
#[must_use] #[must_use]

View File

@ -233,7 +233,7 @@ pub enum ExecuteInputResult {
/// Your default fuzzer instance, for everyday use. /// Your default fuzzer instance, for everyday use.
#[derive(Debug)] #[derive(Debug)]
pub struct StdFuzzer<C, CS, F, I, OF, OT, S, SC> pub struct StdFuzzer<CS, F, I, OF, OT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -244,11 +244,10 @@ where
scheduler: CS, scheduler: CS,
feedback: F, feedback: F,
objective: OF, objective: OF,
phantom: PhantomData<(C, I, OT, S, SC)>, phantom: PhantomData<(I, OT, S)>,
} }
impl<C, CS, F, I, OF, OT, S, SC> HasCorpusScheduler<CS, I, S> impl<CS, F, I, OF, OT, S> HasCorpusScheduler<CS, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -265,7 +264,7 @@ where
} }
} }
impl<C, CS, F, I, OF, OT, S, SC> HasFeedback<F, I, S> for StdFuzzer<C, CS, F, I, OF, OT, S, SC> impl<CS, F, I, OF, OT, S> HasFeedback<F, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -282,7 +281,7 @@ where
} }
} }
impl<C, CS, F, I, OF, OT, S, SC> HasObjective<I, OF, S> for StdFuzzer<C, CS, F, I, OF, OT, S, SC> impl<CS, F, I, OF, OT, S> HasObjective<I, OF, S> for StdFuzzer<CS, F, I, OF, OT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -299,17 +298,14 @@ where
} }
} }
impl<C, CS, F, I, OF, OT, S, SC> ExecutionProcessor<I, OT, S> impl<CS, F, I, OF, OT, S> ExecutionProcessor<I, OT, S> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
C: Corpus<I>,
SC: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
I: Input, I: Input,
OF: Feedback<I, S>, OF: Feedback<I, S>,
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned, OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions, S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
{ {
/// Evaluate if a set of observation channels has an interesting state /// Evaluate if a set of observation channels has an interesting state
fn process_execution<EM>( fn process_execution<EM>(
@ -416,17 +412,14 @@ where
} }
} }
impl<C, CS, F, I, OF, OT, S, SC> EvaluatorObservers<I, OT, S> impl<CS, F, I, OF, OT, S> EvaluatorObservers<I, OT, S> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned, OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
F: Feedback<I, S>, F: Feedback<I, S>,
I: Input, I: Input,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions, S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
SC: Corpus<I>,
{ {
/// Process one input, adding to the respective corpuses if needed and firing the right events /// Process one input, adding to the respective corpuses if needed and firing the right events
#[inline] #[inline]
@ -448,10 +441,8 @@ where
} }
} }
impl<C, CS, E, EM, F, I, OF, OT, S, SC> Evaluator<E, EM, I, S> impl<CS, E, EM, F, I, OF, OT, S> Evaluator<E, EM, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
E: Executor<EM, I, S, Self> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Self> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned, OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
@ -459,8 +450,7 @@ where
F: Feedback<I, S>, F: Feedback<I, S>,
I: Input, I: Input,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions, S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
SC: Corpus<I>,
{ {
/// Process one input, adding to the respective corpuses if needed and firing the right events /// Process one input, adding to the respective corpuses if needed and firing the right events
#[inline] #[inline]
@ -517,8 +507,7 @@ where
} }
} }
impl<C, CS, E, EM, F, I, OF, OT, S, ST, SC> Fuzzer<E, EM, I, S, ST> impl<CS, E, EM, F, I, OF, OT, S, ST> Fuzzer<E, EM, I, S, ST> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventManager<E, I, S, Self>, EM: EventManager<E, I, S, Self>,
@ -568,7 +557,7 @@ where
} }
} }
impl<C, CS, F, I, OF, OT, S, SC> StdFuzzer<C, CS, F, I, OF, OT, S, SC> impl<CS, F, I, OF, OT, S> StdFuzzer<CS, F, I, OF, OT, S>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,
@ -635,8 +624,7 @@ where
OT: ObserversTuple<I, S>; OT: ObserversTuple<I, S>;
} }
impl<C, CS, F, I, OF, OT, S, SC> ExecutesInput<I, OT, S, Self> impl<CS, F, I, OF, OT, S> ExecutesInput<I, OT, S, Self> for StdFuzzer<CS, F, I, OF, OT, S>
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
where where
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
F: Feedback<I, S>, F: Feedback<I, S>,

View File

@ -33,19 +33,17 @@ pub struct Automaton {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
/// Generates random inputs from a grammar automatron /// Generates random inputs from a grammar automatron
pub struct GramatronGenerator<'a, R, S> pub struct GramatronGenerator<'a, S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
automaton: &'a Automaton, automaton: &'a Automaton,
phantom: PhantomData<(R, S)>, phantom: PhantomData<S>,
} }
impl<'a, R, S> Generator<GramatronInput, S> for GramatronGenerator<'a, R, S> impl<'a, S> Generator<GramatronInput, S> for GramatronGenerator<'a, S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
fn generate(&mut self, state: &mut S) -> Result<GramatronInput, Error> { fn generate(&mut self, state: &mut S) -> Result<GramatronInput, Error> {
let mut input = GramatronInput::new(vec![]); let mut input = GramatronInput::new(vec![]);
@ -58,10 +56,9 @@ where
} }
} }
impl<'a, R, S> GramatronGenerator<'a, R, S> impl<'a, S> GramatronGenerator<'a, S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Returns a new [`GramatronGenerator`] /// Returns a new [`GramatronGenerator`]
#[must_use] #[must_use]

View File

@ -35,19 +35,17 @@ where
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
/// Generates random bytes /// Generates random bytes
pub struct RandBytesGenerator<R, S> pub struct RandBytesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
max_size: usize, max_size: usize,
phantom: PhantomData<(R, S)>, phantom: PhantomData<S>,
} }
impl<R, S> Generator<BytesInput, S> for RandBytesGenerator<R, S> impl<S> Generator<BytesInput, S> for RandBytesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> { fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
let mut size = state.rand_mut().below(self.max_size as u64); let mut size = state.rand_mut().below(self.max_size as u64);
@ -67,10 +65,9 @@ where
} }
} }
impl<R, S> RandBytesGenerator<R, S> impl<S> RandBytesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes. /// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
#[must_use] #[must_use]
@ -84,19 +81,17 @@ where
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
/// Generates random printable characters /// Generates random printable characters
pub struct RandPrintablesGenerator<R, S> pub struct RandPrintablesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
max_size: usize, max_size: usize,
phantom: PhantomData<(R, S)>, phantom: PhantomData<S>,
} }
impl<R, S> Generator<BytesInput, S> for RandPrintablesGenerator<R, S> impl<S> Generator<BytesInput, S> for RandPrintablesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> { fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
let mut size = state.rand_mut().below(self.max_size as u64); let mut size = state.rand_mut().below(self.max_size as u64);
@ -117,10 +112,9 @@ where
} }
} }
impl<R, S> RandPrintablesGenerator<R, S> impl<S> RandPrintablesGenerator<S>
where where
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters. /// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters.
#[must_use] #[must_use]

View File

@ -1,10 +1,7 @@
//! Mutations for [`EncodedInput`]s //! Mutations for [`EncodedInput`]s
//! //!
use alloc::vec::Vec; use alloc::vec::Vec;
use core::{ use core::cmp::{max, min};
cmp::{max, min},
marker::PhantomData,
};
use crate::{ use crate::{
bolts::{ bolts::{
@ -23,19 +20,9 @@ use crate::{
/// Set a code in the input as a random value /// Set a code in the input as a random value
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedRandMutator<R, S> pub struct EncodedRandMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedRandMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedRandMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -52,45 +39,25 @@ where
} }
} }
impl<R, S> Named for EncodedRandMutator<R, S> impl Named for EncodedRandMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedRandMutator" "EncodedRandMutator"
} }
} }
impl<R, S> EncodedRandMutator<R, S> impl EncodedRandMutator {
where
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedRandMutator`]. /// Creates a new [`EncodedRandMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Increment a random code in the input /// Increment a random code in the input
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedIncMutator<R, S> pub struct EncodedIncMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedIncMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedIncMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -107,45 +74,25 @@ where
} }
} }
impl<R, S> Named for EncodedIncMutator<R, S> impl Named for EncodedIncMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedIncMutator" "EncodedIncMutator"
} }
} }
impl<R, S> EncodedIncMutator<R, S> impl EncodedIncMutator {
where /// Creates a new [`EncodedIncMutator`].
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedRandMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Decrement a random code in the input /// Decrement a random code in the input
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedDecMutator<R, S> pub struct EncodedDecMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedDecMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDecMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -162,45 +109,25 @@ where
} }
} }
impl<R, S> Named for EncodedDecMutator<R, S> impl Named for EncodedDecMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedDecMutator" "EncodedDecMutator"
} }
} }
impl<R, S> EncodedDecMutator<R, S> impl EncodedDecMutator {
where /// Creates a new [`EncodedDecMutator`].
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedRandMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Adds or subtracts a random value up to `ARITH_MAX` to a random place in the codes [`Vec`]. /// Adds or subtracts a random value up to `ARITH_MAX` to a random place in the codes [`Vec`].
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedAddMutator<R, S> pub struct EncodedAddMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedAddMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedAddMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -221,45 +148,25 @@ where
} }
} }
impl<R, S> Named for EncodedAddMutator<R, S> impl Named for EncodedAddMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedAddMutator" "EncodedAddMutator"
} }
} }
impl<R, S> EncodedAddMutator<R, S> impl EncodedAddMutator {
where
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedAddMutator`]. /// Creates a new [`EncodedAddMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Codes delete mutation for encoded inputs /// Codes delete mutation for encoded inputs
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedDeleteMutator<R, S> pub struct EncodedDeleteMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedDeleteMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDeleteMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -279,45 +186,29 @@ where
} }
} }
impl<R, S> Named for EncodedDeleteMutator<R, S> impl Named for EncodedDeleteMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedDeleteMutator" "EncodedDeleteMutator"
} }
} }
impl<R, S> EncodedDeleteMutator<R, S> impl EncodedDeleteMutator {
where
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedDeleteMutator`]. /// Creates a new [`EncodedDeleteMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Insert mutation for encoded inputs /// Insert mutation for encoded inputs
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedInsertCopyMutator<R, S> pub struct EncodedInsertCopyMutator {
where
S: HasRand<R> + HasMaxSize,
R: Rand,
{
tmp_buf: Vec<u32>, tmp_buf: Vec<u32>,
phantom: PhantomData<(R, S)>,
} }
impl<R, S> Mutator<EncodedInput, S> for EncodedInsertCopyMutator<R, S> impl<S> Mutator<EncodedInput, S> for EncodedInsertCopyMutator
where where
S: HasRand<R> + HasMaxSize, S: HasRand + HasMaxSize,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -358,46 +249,25 @@ where
} }
} }
impl<R, S> Named for EncodedInsertCopyMutator<R, S> impl Named for EncodedInsertCopyMutator {
where
S: HasRand<R> + HasMaxSize,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedInsertCopyMutator" "EncodedInsertCopyMutator"
} }
} }
impl<R, S> EncodedInsertCopyMutator<R, S> impl EncodedInsertCopyMutator {
where
S: HasRand<R> + HasMaxSize,
R: Rand,
{
/// Creates a new [`EncodedInsertCopyMutator`]. /// Creates a new [`EncodedInsertCopyMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
tmp_buf: vec![],
phantom: PhantomData,
}
} }
} }
/// Codes copy mutation for encoded inputs /// Codes copy mutation for encoded inputs
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedCopyMutator<R, S> pub struct EncodedCopyMutator;
where
S: HasRand<R>,
R: Rand,
{
phantom: PhantomData<(R, S)>,
}
impl<R, S> Mutator<EncodedInput, S> for EncodedCopyMutator<R, S> impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
where
S: HasRand<R>,
R: Rand,
{
fn mutate( fn mutate(
&mut self, &mut self,
state: &mut S, state: &mut S,
@ -419,46 +289,27 @@ where
} }
} }
impl<R, S> Named for EncodedCopyMutator<R, S> impl Named for EncodedCopyMutator {
where
S: HasRand<R>,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedCopyMutator" "EncodedCopyMutator"
} }
} }
impl<R, S> EncodedCopyMutator<R, S> impl EncodedCopyMutator {
where
S: HasRand<R>,
R: Rand,
{
/// Creates a new [`EncodedCopyMutator`]. /// Creates a new [`EncodedCopyMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Crossover insert mutation for encoded inputs /// Crossover insert mutation for encoded inputs
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedCrossoverInsertMutator<C, R, S> pub struct EncodedCrossoverInsertMutator;
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
{
phantom: PhantomData<(C, R, S)>,
}
impl<C, R, S> Mutator<EncodedInput, S> for EncodedCrossoverInsertMutator<C, R, S> impl<S> Mutator<EncodedInput, S> for EncodedCrossoverInsertMutator
where where
C: Corpus<EncodedInput>, S: HasRand + HasCorpus<EncodedInput> + HasMaxSize,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -512,48 +363,27 @@ where
} }
} }
impl<C, R, S> Named for EncodedCrossoverInsertMutator<C, R, S> impl Named for EncodedCrossoverInsertMutator {
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedCrossoverInsertMutator" "EncodedCrossoverInsertMutator"
} }
} }
impl<C, R, S> EncodedCrossoverInsertMutator<C, R, S> impl EncodedCrossoverInsertMutator {
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
{
/// Creates a new [`EncodedCrossoverInsertMutator`]. /// Creates a new [`EncodedCrossoverInsertMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Crossover replace mutation for encoded inputs /// Crossover replace mutation for encoded inputs
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EncodedCrossoverReplaceMutator<C, R, S> pub struct EncodedCrossoverReplaceMutator;
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput>,
{
phantom: PhantomData<(C, R, S)>,
}
impl<C, R, S> Mutator<EncodedInput, S> for EncodedCrossoverReplaceMutator<C, R, S> impl<S> Mutator<EncodedInput, S> for EncodedCrossoverReplaceMutator
where where
C: Corpus<EncodedInput>, S: HasRand + HasCorpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput>,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -599,50 +429,33 @@ where
} }
} }
impl<C, R, S> Named for EncodedCrossoverReplaceMutator<C, R, S> impl Named for EncodedCrossoverReplaceMutator {
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput>,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"EncodedCrossoverReplaceMutator" "EncodedCrossoverReplaceMutator"
} }
} }
impl<C, R, S> EncodedCrossoverReplaceMutator<C, R, S> impl EncodedCrossoverReplaceMutator {
where
C: Corpus<EncodedInput>,
R: Rand,
S: HasRand<R> + HasCorpus<C, EncodedInput>,
{
/// Creates a new [`EncodedCrossoverReplaceMutator`]. /// Creates a new [`EncodedCrossoverReplaceMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// Get the mutations that compose the encoded mutator /// Get the mutations that compose the encoded mutator
#[must_use] #[must_use]
pub fn encoded_mutations<C, R, S>() -> tuple_list_type!( pub fn encoded_mutations() -> tuple_list_type!(
EncodedRandMutator<R, S>, EncodedRandMutator,
EncodedIncMutator<R, S>, EncodedIncMutator,
EncodedDecMutator<R, S>, EncodedDecMutator,
EncodedAddMutator<R, S>, EncodedAddMutator,
EncodedDeleteMutator<R, S>, EncodedDeleteMutator,
EncodedInsertCopyMutator<R, S>, EncodedInsertCopyMutator,
EncodedCopyMutator<R, S>, EncodedCopyMutator,
EncodedCrossoverInsertMutator<C, R, S>, EncodedCrossoverInsertMutator,
EncodedCrossoverReplaceMutator<C, R, S>, EncodedCrossoverReplaceMutator,
) ) {
where
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
C: Corpus<EncodedInput>,
R: Rand,
{
tuple_list!( tuple_list!(
EncodedRandMutator::new(), EncodedRandMutator::new(),
EncodedIncMutator::new(), EncodedIncMutator::new(),

View File

@ -1,7 +1,7 @@
//! Gramatron is the rewritten gramatron fuzzer in rust. //! Gramatron is the rewritten gramatron fuzzer in rust.
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details. //! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
use alloc::vec::Vec; use alloc::vec::Vec;
use core::{cmp::max, marker::PhantomData}; use core::cmp::max;
use hashbrown::HashMap; use hashbrown::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -17,18 +17,16 @@ use crate::{
/// A random mutator for grammar fuzzing /// A random mutator for grammar fuzzing
#[derive(Debug)] #[derive(Debug)]
pub struct GramatronRandomMutator<'a, R, S> pub struct GramatronRandomMutator<'a, S>
where where
S: HasRand<R> + HasMetadata, S: HasRand + HasMetadata,
R: Rand,
{ {
generator: &'a GramatronGenerator<'a, R, S>, generator: &'a GramatronGenerator<'a, S>,
} }
impl<'a, R, S> Mutator<GramatronInput, S> for GramatronRandomMutator<'a, R, S> impl<'a, S> Mutator<GramatronInput, S> for GramatronRandomMutator<'a, S>
where where
S: HasRand<R> + HasMetadata, S: HasRand + HasMetadata,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -48,24 +46,22 @@ where
} }
} }
impl<'a, R, S> Named for GramatronRandomMutator<'a, R, S> impl<'a, S> Named for GramatronRandomMutator<'a, S>
where where
S: HasRand<R> + HasMetadata, S: HasRand + HasMetadata,
R: Rand,
{ {
fn name(&self) -> &str { fn name(&self) -> &str {
"GramatronRandomMutator" "GramatronRandomMutator"
} }
} }
impl<'a, R, S> GramatronRandomMutator<'a, R, S> impl<'a, S> GramatronRandomMutator<'a, S>
where where
S: HasRand<R> + HasMetadata, S: HasRand + HasMetadata,
R: Rand,
{ {
/// Creates a new [`GramatronRandomMutator`]. /// Creates a new [`GramatronRandomMutator`].
#[must_use] #[must_use]
pub fn new(generator: &'a GramatronGenerator<'a, R, S>) -> Self { pub fn new(generator: &'a GramatronGenerator<'a, S>) -> Self {
Self { generator } Self { generator }
} }
} }
@ -94,20 +90,11 @@ impl GramatronIdxMapMetadata {
/// A [`Mutator`] that mutates a [`GramatronInput`] by splicing inputs together. /// A [`Mutator`] that mutates a [`GramatronInput`] by splicing inputs together.
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct GramatronSpliceMutator<C, R, S> pub struct GramatronSpliceMutator;
where
C: Corpus<GramatronInput>,
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
R: Rand,
{
phantom: PhantomData<(C, R, S)>,
}
impl<C, R, S> Mutator<GramatronInput, S> for GramatronSpliceMutator<C, R, S> impl<S> Mutator<GramatronInput, S> for GramatronSpliceMutator
where where
C: Corpus<GramatronInput>, S: HasRand + HasCorpus<GramatronInput> + HasMetadata,
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -155,49 +142,31 @@ where
} }
} }
impl<C, R, S> Named for GramatronSpliceMutator<C, R, S> impl Named for GramatronSpliceMutator {
where
C: Corpus<GramatronInput>,
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"GramatronSpliceMutator" "GramatronSpliceMutator"
} }
} }
impl<'a, C, R, S> GramatronSpliceMutator<C, R, S> impl GramatronSpliceMutator {
where
C: Corpus<GramatronInput>,
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
R: Rand,
{
/// Creates a new [`GramatronSpliceMutator`]. /// Creates a new [`GramatronSpliceMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// A mutator that uses Gramatron for grammar fuzzing and mutation. /// A mutator that uses Gramatron for grammar fuzzing and mutation.
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct GramatronRecursionMutator<R, S> pub struct GramatronRecursionMutator {
where
S: HasRand<R> + HasMetadata,
R: Rand,
{
counters: HashMap<usize, (usize, usize, usize)>, counters: HashMap<usize, (usize, usize, usize)>,
states: Vec<usize>, states: Vec<usize>,
temp: Vec<Terminal>, temp: Vec<Terminal>,
phantom: PhantomData<(R, S)>,
} }
impl<R, S> Mutator<GramatronInput, S> for GramatronRecursionMutator<R, S> impl<S> Mutator<GramatronInput, S> for GramatronRecursionMutator
where where
S: HasRand<R> + HasMetadata, S: HasRand + HasMetadata,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -266,29 +235,16 @@ where
} }
} }
impl<R, S> Named for GramatronRecursionMutator<R, S> impl Named for GramatronRecursionMutator {
where
S: HasRand<R> + HasMetadata,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"GramatronRecursionMutator" "GramatronRecursionMutator"
} }
} }
impl<R, S> GramatronRecursionMutator<R, S> impl GramatronRecursionMutator {
where
S: HasRand<R> + HasMetadata,
R: Rand,
{
/// Creates a new [`GramatronRecursionMutator`]. /// Creates a new [`GramatronRecursionMutator`].
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
counters: HashMap::default(),
states: vec![],
temp: vec![],
phantom: PhantomData,
}
} }
} }

View File

@ -360,29 +360,23 @@ pub enum MOptMode {
/// This is the main struct of `MOpt`, an `AFL` mutator. /// This is the main struct of `MOpt`, an `AFL` mutator.
/// See the original `MOpt` implementation in <https://github.com/puppet-meteor/MOpt-AFL> /// See the original `MOpt` implementation in <https://github.com/puppet-meteor/MOpt-AFL>
pub struct StdMOptMutator<C, I, MT, R, S, SC> pub struct StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
mode: MOptMode, mode: MOptMode,
finds_before: usize, finds_before: usize,
mutations: MT, mutations: MT,
phantom: PhantomData<(C, I, R, S, SC)>, phantom: PhantomData<(I, S)>,
} }
impl<C, I, MT, R, S, SC> Debug for StdMOptMutator<C, I, MT, R, S, SC> impl<I, MT, S> Debug for StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
@ -394,14 +388,11 @@ where
} }
} }
impl<C, I, MT, R, S, SC> Mutator<I, S> for StdMOptMutator<C, I, MT, R, S, SC> impl<I, MT, S> Mutator<I, S> for StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
#[inline] #[inline]
fn mutate( fn mutate(
@ -532,14 +523,11 @@ where
} }
} }
impl<C, I, MT, R, S, SC> StdMOptMutator<C, I, MT, R, S, SC> impl<I, MT, S> StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
/// Create a new [`StdMOptMutator`]. /// Create a new [`StdMOptMutator`].
pub fn new(state: &mut S, mutations: MT, swarm_num: usize) -> Result<Self, Error> { pub fn new(state: &mut S, mutations: MT, swarm_num: usize) -> Result<Self, Error> {
@ -619,14 +607,11 @@ where
} }
} }
impl<C, I, MT, R, S, SC> ComposedByMutations<I, MT, S> for StdMOptMutator<C, I, MT, R, S, SC> impl<I, MT, S> ComposedByMutations<I, MT, S> for StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
/// Get the mutations /// Get the mutations
#[inline] #[inline]
@ -641,14 +626,11 @@ where
} }
} }
impl<C, I, MT, R, S, SC> ScheduledMutator<I, MT, S> for StdMOptMutator<C, I, MT, R, S, SC> impl<I, MT, S> ScheduledMutator<I, MT, S> for StdMOptMutator<I, MT, S>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
{ {
/// Compute the number of iterations used to apply stacked mutations /// Compute the number of iterations used to apply stacked mutations
fn iterations(&self, state: &mut S, _: &I) -> u64 { fn iterations(&self, state: &mut S, _: &I) -> u64 {

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@
use crate::{ use crate::{
bolts::tuples::Named, bolts::tuples::Named,
corpus::Corpus,
feedbacks::NautilusChunksMetadata, feedbacks::NautilusChunksMetadata,
generators::nautilus::NautilusContext, generators::nautilus::NautilusContext,
inputs::nautilus::NautilusInput, inputs::nautilus::NautilusInput,
@ -11,7 +10,7 @@ use crate::{
Error, Error,
}; };
use core::{fmt::Debug, marker::PhantomData}; use core::fmt::Debug;
use grammartec::mutator::Mutator as BackingMutator; use grammartec::mutator::Mutator as BackingMutator;
use grammartec::{ use grammartec::{
context::Context, context::Context,
@ -30,7 +29,7 @@ impl Debug for NautilusRandomMutator<'_> {
} }
} }
impl<'a, S> Mutator<NautilusInput, S> for NautilusRandomMutator<'a> { impl<S> Mutator<NautilusInput, S> for NautilusRandomMutator<'_> {
fn mutate( fn mutate(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
@ -60,7 +59,7 @@ impl<'a, S> Mutator<NautilusInput, S> for NautilusRandomMutator<'a> {
} }
} }
impl<'a> Named for NautilusRandomMutator<'a> { impl Named for NautilusRandomMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &str {
"NautilusRandomMutator" "NautilusRandomMutator"
} }
@ -91,7 +90,7 @@ impl Debug for NautilusRecursionMutator<'_> {
} }
} }
impl<'a, S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'a> { impl<S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'_> {
fn mutate( fn mutate(
&mut self, &mut self,
_state: &mut S, _state: &mut S,
@ -124,7 +123,7 @@ impl<'a, S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'a> {
} }
} }
impl<'a> Named for NautilusRecursionMutator<'a> { impl Named for NautilusRecursionMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &str {
"NautilusRecursionMutator" "NautilusRecursionMutator"
} }
@ -143,22 +142,20 @@ impl<'a> NautilusRecursionMutator<'a> {
} }
/// The splicing mutator for `Nautilus` that can splice inputs together /// The splicing mutator for `Nautilus` that can splice inputs together
pub struct NautilusSpliceMutator<'a, C> { pub struct NautilusSpliceMutator<'a> {
ctx: &'a Context, ctx: &'a Context,
mutator: BackingMutator, mutator: BackingMutator,
phantom: PhantomData<C>,
} }
impl Debug for NautilusSpliceMutator<'_, ()> { impl Debug for NautilusSpliceMutator<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NautilusSpliceMutator {{}}") write!(f, "NautilusSpliceMutator {{}}")
} }
} }
impl<'a, S, C> Mutator<NautilusInput, S> for NautilusSpliceMutator<'a, C> impl<S> Mutator<NautilusInput, S> for NautilusSpliceMutator<'_>
where where
C: Corpus<NautilusInput>, S: HasCorpus<NautilusInput> + HasMetadata,
S: HasCorpus<C, NautilusInput> + HasMetadata,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -194,13 +191,13 @@ where
} }
} }
impl<'a, C> Named for NautilusSpliceMutator<'a, C> { impl Named for NautilusSpliceMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &str {
"NautilusSpliceMutator" "NautilusSpliceMutator"
} }
} }
impl<'a, C> NautilusSpliceMutator<'a, C> { impl<'a> NautilusSpliceMutator<'a> {
/// Creates a new [`NautilusSpliceMutator`]. /// Creates a new [`NautilusSpliceMutator`].
#[must_use] #[must_use]
pub fn new(context: &'a NautilusContext) -> Self { pub fn new(context: &'a NautilusContext) -> Self {
@ -208,7 +205,6 @@ impl<'a, C> NautilusSpliceMutator<'a, C> {
Self { Self {
ctx: &context.ctx, ctx: &context.ctx,
mutator, mutator,
phantom: PhantomData,
} }
} }
} }

View File

@ -14,9 +14,9 @@ use crate::{
AsSlice, AsSlice,
}, },
corpus::Corpus, corpus::Corpus,
inputs::{HasBytesVec, Input}, inputs::Input,
mutators::{MutationResult, Mutator, MutatorsTuple}, mutators::{MutationResult, Mutator, MutatorsTuple},
state::{HasCorpus, HasMaxSize, HasMetadata, HasRand}, state::{HasCorpus, HasMetadata, HasRand},
Error, Error,
}; };
@ -95,24 +95,22 @@ where
} }
/// A [`Mutator`] that schedules one of the embedded mutations on each call. /// A [`Mutator`] that schedules one of the embedded mutations on each call.
pub struct StdScheduledMutator<I, MT, R, S> pub struct StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
mutations: MT, mutations: MT,
max_iterations: u64, max_iterations: u64,
phantom: PhantomData<(I, R, S)>, phantom: PhantomData<(I, S)>,
} }
impl<I, MT, R, S> Debug for StdScheduledMutator<I, MT, R, S> impl<I, MT, S> Debug for StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
@ -124,12 +122,11 @@ where
} }
} }
impl<I, MT, R, S> Mutator<I, S> for StdScheduledMutator<I, MT, R, S> impl<I, MT, S> Mutator<I, S> for StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
#[inline] #[inline]
fn mutate( fn mutate(
@ -142,12 +139,11 @@ where
} }
} }
impl<I, MT, R, S> ComposedByMutations<I, MT, S> for StdScheduledMutator<I, MT, R, S> impl<I, MT, S> ComposedByMutations<I, MT, S> for StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Get the mutations /// Get the mutations
#[inline] #[inline]
@ -162,12 +158,11 @@ where
} }
} }
impl<I, MT, R, S> ScheduledMutator<I, MT, S> for StdScheduledMutator<I, MT, R, S> impl<I, MT, S> ScheduledMutator<I, MT, S> for StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Compute the number of iterations used to apply stacked mutations /// Compute the number of iterations used to apply stacked mutations
fn iterations(&self, state: &mut S, _: &I) -> u64 { fn iterations(&self, state: &mut S, _: &I) -> u64 {
@ -181,12 +176,11 @@ where
} }
} }
impl<I, MT, R, S> StdScheduledMutator<I, MT, R, S> impl<I, MT, S> StdScheduledMutator<I, MT, S>
where where
I: Input, I: Input,
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
R: Rand, S: HasRand,
S: HasRand<R>,
{ {
/// Create a new [`StdScheduledMutator`] instance specifying mutations /// Create a new [`StdScheduledMutator`] instance specifying mutations
pub fn new(mutations: MT) -> Self { pub fn new(mutations: MT) -> Self {
@ -209,41 +203,35 @@ where
/// Get the mutations that compose the Havoc mutator /// Get the mutations that compose the Havoc mutator
#[must_use] #[must_use]
pub fn havoc_mutations<C, I, R, S>() -> tuple_list_type!( pub fn havoc_mutations() -> tuple_list_type!(
BitFlipMutator<I, R, S>, BitFlipMutator,
ByteFlipMutator<I, R, S>, ByteFlipMutator,
ByteIncMutator<I, R, S>, ByteIncMutator,
ByteDecMutator<I, R, S>, ByteDecMutator,
ByteNegMutator<I, R, S>, ByteNegMutator,
ByteRandMutator<I, R, S>, ByteRandMutator,
ByteAddMutator<I, R, S>, ByteAddMutator,
WordAddMutator<I, R, S>, WordAddMutator,
DwordAddMutator<I, R, S>, DwordAddMutator,
QwordAddMutator<I, R, S>, QwordAddMutator,
ByteInterestingMutator<I, R, S>, ByteInterestingMutator,
WordInterestingMutator<I, R, S>, WordInterestingMutator,
DwordInterestingMutator<I, R, S>, DwordInterestingMutator,
BytesDeleteMutator<I, R, S>, BytesDeleteMutator,
BytesDeleteMutator<I, R, S>, BytesDeleteMutator,
BytesDeleteMutator<I, R, S>, BytesDeleteMutator,
BytesDeleteMutator<I, R, S>, BytesDeleteMutator,
BytesExpandMutator<I, R, S>, BytesExpandMutator,
BytesInsertMutator<I, R, S>, BytesInsertMutator,
BytesRandInsertMutator<I, R, S>, BytesRandInsertMutator,
BytesSetMutator<I, R, S>, BytesSetMutator,
BytesRandSetMutator<I, R, S>, BytesRandSetMutator,
BytesCopyMutator<I, R, S>, BytesCopyMutator,
BytesInsertCopyMutator<I, R, S>, BytesInsertCopyMutator,
BytesSwapMutator<I, R, S>, BytesSwapMutator,
CrossoverInsertMutator<C, I, R, S>, CrossoverInsertMutator,
CrossoverReplaceMutator<C, I, R, S>, CrossoverReplaceMutator,
) ) {
where
I: Input + HasBytesVec,
S: HasRand<R> + HasCorpus<C, I> + HasMetadata + HasMaxSize,
C: Corpus<I>,
R: Rand,
{
tuple_list!( tuple_list!(
BitFlipMutator::new(), BitFlipMutator::new(),
ByteFlipMutator::new(), ByteFlipMutator::new(),
@ -277,39 +265,28 @@ where
/// Get the mutations that uses the Tokens metadata /// Get the mutations that uses the Tokens metadata
#[must_use] #[must_use]
pub fn tokens_mutations<C, I, R, S>( pub fn tokens_mutations() -> tuple_list_type!(TokenInsert, TokenReplace) {
) -> tuple_list_type!(TokenInsert<I, R, S>, TokenReplace<I, R, S>)
where
I: Input + HasBytesVec,
S: HasRand<R> + HasCorpus<C, I> + HasMetadata + HasMaxSize,
C: Corpus<I>,
R: Rand,
{
tuple_list!(TokenInsert::new(), TokenReplace::new(),) tuple_list!(TokenInsert::new(), TokenReplace::new(),)
} }
/// A logging [`Mutator`] that wraps around a [`StdScheduledMutator`]. /// A logging [`Mutator`] that wraps around a [`StdScheduledMutator`].
pub struct LoggerScheduledMutator<C, I, MT, R, S, SM> pub struct LoggerScheduledMutator<I, MT, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
scheduled: SM, scheduled: SM,
mutation_log: Vec<usize>, mutation_log: Vec<usize>,
phantom: PhantomData<(C, I, MT, R, S)>, phantom: PhantomData<(I, MT, S)>,
} }
impl<C, I, MT, R, S, SM> Debug for LoggerScheduledMutator<C, I, MT, R, S, SM> impl<I, MT, S, SM> Debug for LoggerScheduledMutator<I, MT, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -322,13 +299,11 @@ where
} }
} }
impl<C, I, MT, R, S, SM> Mutator<I, S> for LoggerScheduledMutator<C, I, MT, R, S, SM> impl<I, MT, S, SM> Mutator<I, S> for LoggerScheduledMutator<I, MT, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
fn mutate( fn mutate(
@ -362,14 +337,11 @@ where
} }
} }
impl<C, I, MT, R, S, SM> ComposedByMutations<I, MT, S> impl<I, MT, S, SM> ComposedByMutations<I, MT, S> for LoggerScheduledMutator<I, MT, S, SM>
for LoggerScheduledMutator<C, I, MT, R, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
#[inline] #[inline]
@ -383,13 +355,11 @@ where
} }
} }
impl<C, I, MT, R, S, SM> ScheduledMutator<I, MT, S> for LoggerScheduledMutator<C, I, MT, R, S, SM> impl<I, MT, S, SM> ScheduledMutator<I, MT, S> for LoggerScheduledMutator<I, MT, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
/// Compute the number of iterations used to apply stacked mutations /// Compute the number of iterations used to apply stacked mutations
@ -428,13 +398,11 @@ where
} }
} }
impl<C, I, MT, R, S, SM> LoggerScheduledMutator<C, I, MT, R, S, SM> impl<I, MT, S, SM> LoggerScheduledMutator<I, MT, S, SM>
where where
C: Corpus<I>,
I: Input, I: Input,
MT: MutatorsTuple<I, S> + NamedTuple, MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand, S: HasRand + HasCorpus<I>,
S: HasRand<R> + HasCorpus<C, I>,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
/// Create a new [`StdScheduledMutator`] instance without mutations and corpus /// Create a new [`StdScheduledMutator`] instance without mutations and corpus

View File

@ -1,7 +1,7 @@
//! Tokens are what afl calls extras or dictionaries. //! Tokens are what afl calls extras or dictionaries.
//! They may be inserted as part of mutations during fuzzing. //! They may be inserted as part of mutations during fuzzing.
use alloc::vec::Vec; use alloc::vec::Vec;
use core::{marker::PhantomData, mem::size_of}; use core::mem::size_of;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -127,20 +127,12 @@ impl Tokens {
/// Inserts a random token at a random position in the `Input`. /// Inserts a random token at a random position in the `Input`.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TokenInsert<I, R, S> pub struct TokenInsert;
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
phantom: PhantomData<(I, R, S)>,
}
impl<I, R, S> Mutator<I, S> for TokenInsert<I, R, S> impl<I, S> Mutator<I, S> for TokenInsert
where where
I: Input + HasBytesVec, I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize, S: HasMetadata + HasRand + HasMaxSize,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -184,49 +176,29 @@ where
} }
} }
impl<I, R, S> Named for TokenInsert<I, R, S> impl Named for TokenInsert {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"TokenInsert" "TokenInsert"
} }
} }
impl<I, R, S> TokenInsert<I, R, S> impl TokenInsert {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
/// Create a `TokenInsert` `Mutation`. /// Create a `TokenInsert` `Mutation`.
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// A `TokenReplace` [`Mutator`] replaces a random part of the input with one of a range of tokens. /// A `TokenReplace` [`Mutator`] replaces a random part of the input with one of a range of tokens.
/// From AFL terms, this is called as `Dictionary` mutation (which doesn't really make sense ;) ). /// From AFL terms, this is called as `Dictionary` mutation (which doesn't really make sense ;) ).
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TokenReplace<I, R, S> pub struct TokenReplace;
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
phantom: PhantomData<(I, R, S)>,
}
impl<I, R, S> Mutator<I, S> for TokenReplace<I, R, S> impl<I, S> Mutator<I, S> for TokenReplace
where where
I: Input + HasBytesVec, I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize, S: HasMetadata + HasRand + HasMaxSize,
R: Rand,
{ {
fn mutate( fn mutate(
&mut self, &mut self,
@ -266,49 +238,29 @@ where
} }
} }
impl<I, R, S> Named for TokenReplace<I, R, S> impl Named for TokenReplace {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"TokenReplace" "TokenReplace"
} }
} }
impl<I, R, S> TokenReplace<I, R, S> impl TokenReplace {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
/// Creates a new `TokenReplace` struct. /// Creates a new `TokenReplace` struct.
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }
/// A `I2SRandReplace` [`Mutator`] replaces a random matching input-2-state comparison operand with the other. /// A `I2SRandReplace` [`Mutator`] replaces a random matching input-2-state comparison operand with the other.
/// it needs a valid [`CmpValuesMetadata`] in the state. /// it needs a valid [`CmpValuesMetadata`] in the state.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct I2SRandReplace<I, R, S> pub struct I2SRandReplace;
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
phantom: PhantomData<(I, R, S)>,
}
impl<I, R, S> Mutator<I, S> for I2SRandReplace<I, R, S> impl<I, S> Mutator<I, S> for I2SRandReplace
where where
I: Input + HasBytesVec, I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize, S: HasMetadata + HasRand + HasMaxSize,
R: Rand,
{ {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn mutate( fn mutate(
@ -471,29 +423,17 @@ where
} }
} }
impl<I, R, S> Named for I2SRandReplace<I, R, S> impl Named for I2SRandReplace {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
fn name(&self) -> &str { fn name(&self) -> &str {
"I2SRandReplace" "I2SRandReplace"
} }
} }
impl<I, R, S> I2SRandReplace<I, R, S> impl I2SRandReplace {
where
I: Input + HasBytesVec,
S: HasMetadata + HasRand<R> + HasMaxSize,
R: Rand,
{
/// Creates a new `I2SRandReplace` struct. /// Creates a new `I2SRandReplace` struct.
#[must_use] #[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self
phantom: PhantomData,
}
} }
} }

View File

@ -2,10 +2,11 @@
use crate::{ use crate::{
bolts::current_time, bolts::current_time,
bolts::tuples::MatchName,
corpus::{Corpus, PowerScheduleTestcaseMetaData}, corpus::{Corpus, PowerScheduleTestcaseMetaData},
events::{EventFirer, LogSeverity}, events::{EventFirer, LogSeverity},
executors::{Executor, ExitKind, HasObservers}, executors::{Executor, ExitKind, HasObservers},
feedbacks::{FeedbackStatesTuple, MapFeedbackState}, feedbacks::MapFeedbackState,
fuzzer::Evaluator, fuzzer::Evaluator,
inputs::Input, inputs::Input,
observers::{MapObserver, ObserversTuple}, observers::{MapObserver, ObserversTuple},
@ -23,40 +24,31 @@ use serde::{Deserialize, Serialize};
/// The calibration stage will measure the average exec time and the target's stability for this input. /// The calibration stage will measure the average exec time and the target's stability for this input.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z> pub struct CalibrationStage<I, O, OT, S, T>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
EM: EventFirer<I>,
FT: FeedbackStatesTuple,
I: Input, I: Input,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata, S: HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{ {
map_observer_name: String, map_observer_name: String,
stage_max: usize, stage_max: usize,
#[allow(clippy::type_complexity)] phantom: PhantomData<(I, O, OT, S, T)>,
phantom: PhantomData<(C, E, EM, FT, I, O, OT, S, T, Z)>,
} }
const CAL_STAGE_START: usize = 4; const CAL_STAGE_START: usize = 4;
const CAL_STAGE_MAX: usize = 16; const CAL_STAGE_MAX: usize = 16;
impl<C, E, EM, FT, I, O, OT, S, T, Z> Stage<E, EM, S, Z> impl<E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z> for CalibrationStage<I, O, OT, S, T>
for CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
EM: EventFirer<I>, EM: EventFirer<I>,
FT: FeedbackStatesTuple,
I: Input, I: Input,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata + HasFeedbackStates<FT> + HasClientPerfMonitor, S: HasCorpus<I> + HasMetadata + HasFeedbackStates + HasClientPerfMonitor,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
#[inline] #[inline]
@ -314,18 +306,13 @@ impl PowerScheduleMetadata {
crate::impl_serdeany!(PowerScheduleMetadata); crate::impl_serdeany!(PowerScheduleMetadata);
impl<C, E, EM, FT, I, O, OT, S, T, Z> CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z> impl<I, O, OT, S, T> CalibrationStage<I, O, OT, S, T>
where where
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
EM: EventFirer<I>,
FT: FeedbackStatesTuple,
I: Input, I: Input,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata, S: HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{ {
/// Create a new [`CalibrationStage`]. /// Create a new [`CalibrationStage`].
pub fn new(state: &mut S, map_observer_name: &O) -> Self { pub fn new(state: &mut S, map_observer_name: &O) -> Self {

View File

@ -17,25 +17,23 @@ use super::{Stage, TracingStage};
/// Wraps a [`TracingStage`] to add concolic observing. /// Wraps a [`TracingStage`] to add concolic observing.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ConcolicTracingStage<C, EM, I, OT, S, TE, Z> pub struct ConcolicTracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
inner: TracingStage<C, EM, I, OT, S, TE, Z>, inner: TracingStage<EM, I, OT, S, TE, Z>,
observer_name: String, observer_name: String,
} }
impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for ConcolicTracingStage<C, EM, I, OT, S, TE, Z> impl<E, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for ConcolicTracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
#[inline] #[inline]
fn perform( fn perform(
@ -67,16 +65,15 @@ where
} }
} }
impl<C, EM, I, OT, S, TE, Z> ConcolicTracingStage<C, EM, I, OT, S, TE, Z> impl<EM, I, OT, S, TE, Z> ConcolicTracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
/// Creates a new default tracing stage using the given [`Executor`], observing traces from a [`ConcolicObserver`] with the given name. /// Creates a new default tracing stage using the given [`Executor`], observing traces from a [`ConcolicObserver`] with the given name.
pub fn new(inner: TracingStage<C, EM, I, OT, S, TE, Z>, observer_name: String) -> Self { pub fn new(inner: TracingStage<EM, I, OT, S, TE, Z>, observer_name: String) -> Self {
Self { Self {
inner, inner,
observer_name, observer_name,
@ -345,21 +342,19 @@ fn generate_mutations(iter: impl Iterator<Item = (SymExprRef, SymExpr)>) -> Vec<
/// A mutational stage that uses Z3 to solve concolic constraints attached to the [`crate::corpus::Testcase`] by the [`ConcolicTracingStage`]. /// A mutational stage that uses Z3 to solve concolic constraints attached to the [`crate::corpus::Testcase`] by the [`ConcolicTracingStage`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SimpleConcolicMutationalStage<C, EM, I, S, Z> pub struct SimpleConcolicMutationalStage<EM, I, S, Z>
where where
I: Input, I: Input,
C: Corpus<I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
{ {
_phantom: PhantomData<(C, EM, I, S, Z)>, _phantom: PhantomData<(EM, I, S, Z)>,
} }
#[cfg(feature = "concolic_mutation")] #[cfg(feature = "concolic_mutation")]
impl<E, C, EM, I, S, Z> Stage<E, EM, S, Z> for SimpleConcolicMutationalStage<C, EM, I, S, Z> impl<E, EM, I, S, Z> Stage<E, EM, S, Z> for SimpleConcolicMutationalStage<EM, I, S, Z>
where where
I: Input + HasBytesVec, I: Input + HasBytesVec,
C: Corpus<I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
#[inline] #[inline]
@ -399,11 +394,10 @@ where
} }
} }
impl<C, EM, I, S, Z> Default for SimpleConcolicMutationalStage<C, EM, I, S, Z> impl<EM, I, S, Z> Default for SimpleConcolicMutationalStage<EM, I, S, Z>
where where
I: Input, I: Input,
C: Corpus<I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
{ {
fn default() -> Self { fn default() -> Self {
Self { Self {

View File

@ -32,8 +32,7 @@ pub mod sync;
pub use sync::*; pub use sync::*;
use crate::{ use crate::{
bolts::rands::Rand, corpus::CorpusScheduler,
corpus::{Corpus, CorpusScheduler},
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter}, events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
executors::{Executor, HasObservers}, executors::{Executor, HasObservers},
inputs::Input, inputs::Input,
@ -164,32 +163,28 @@ where
/// Allows us to use a [`push::PushStage`] as a normal [`Stage`] /// Allows us to use a [`push::PushStage`] as a normal [`Stage`]
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
#[derive(Debug)] #[derive(Debug)]
pub struct PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z> pub struct PushStageAdapter<CS, EM, I, OT, PS, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>, PS: PushStage<CS, EM, I, OT, S, Z>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
push_stage: PS, push_stage: PS,
phantom: PhantomData<(C, CS, EM, I, OT, R, S, Z)>, phantom: PhantomData<(CS, EM, I, OT, S, Z)>,
} }
impl<C, CS, EM, I, OT, PS, R, S, Z> PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z> impl<CS, EM, I, OT, PS, S, Z> PushStageAdapter<CS, EM, I, OT, PS, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>, PS: PushStage<CS, EM, I, OT, S, Z>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Create a new [`PushStageAdapter`], warpping the given [`PushStage`] /// Create a new [`PushStageAdapter`], warpping the given [`PushStage`]
@ -203,18 +198,15 @@ where
} }
} }
impl<C, CS, E, EM, I, OT, PS, R, S, Z> Stage<E, EM, S, Z> impl<CS, E, EM, I, OT, PS, S, Z> Stage<E, EM, S, Z> for PushStageAdapter<CS, EM, I, OT, PS, S, Z>
for PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>, PS: PushStage<CS, EM, I, OT, S, Z>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutesInput<I, OT, S, Z> Z: ExecutesInput<I, OT, S, Z>
+ ExecutionProcessor<I, OT, S> + ExecutionProcessor<I, OT, S>
+ EvaluatorObservers<I, OT, S> + EvaluatorObservers<I, OT, S>

View File

@ -24,12 +24,11 @@ use crate::monitors::PerfFeature;
/// A Mutational stage is the stage in a fuzzing run that mutates inputs. /// A Mutational stage is the stage in a fuzzing run that mutates inputs.
/// Mutational stages will usually have a range of mutations that are /// Mutational stages will usually have a range of mutations that are
/// being applied to the input one by one, between executions. /// being applied to the input one by one, between executions.
pub trait MutationalStage<C, E, EM, I, M, S, Z>: Stage<E, EM, S, Z> pub trait MutationalStage<E, EM, I, M, S, Z>: Stage<E, EM, S, Z>
where where
C: Corpus<I>,
M: Mutator<I, S>, M: Mutator<I, S>,
I: Input, I: Input,
S: HasClientPerfMonitor + HasCorpus<C, I>, S: HasClientPerfMonitor + HasCorpus<I>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// The mutator registered for this stage /// The mutator registered for this stage
@ -84,28 +83,23 @@ pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
/// The default mutational stage /// The default mutational stage
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StdMutationalStage<C, E, EM, I, M, R, S, Z> pub struct StdMutationalStage<E, EM, I, M, S, Z>
where where
C: Corpus<I>,
M: Mutator<I, S>, M: Mutator<I, S>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
mutator: M, mutator: M,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, I, R, S, Z)>, phantom: PhantomData<(E, EM, I, S, Z)>,
} }
impl<C, E, EM, I, M, R, S, Z> MutationalStage<C, E, EM, I, M, S, Z> impl<E, EM, I, M, S, Z> MutationalStage<E, EM, I, M, S, Z> for StdMutationalStage<E, EM, I, M, S, Z>
for StdMutationalStage<C, E, EM, I, M, R, S, Z>
where where
C: Corpus<I>,
M: Mutator<I, S>, M: Mutator<I, S>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// The mutator, added to this stage /// The mutator, added to this stage
@ -126,13 +120,11 @@ where
} }
} }
impl<C, E, EM, I, M, R, S, Z> Stage<E, EM, S, Z> for StdMutationalStage<C, E, EM, I, M, R, S, Z> impl<E, EM, I, M, S, Z> Stage<E, EM, S, Z> for StdMutationalStage<E, EM, I, M, S, Z>
where where
C: Corpus<I>,
M: Mutator<I, S>, M: Mutator<I, S>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
#[inline] #[inline]
@ -154,13 +146,11 @@ where
} }
} }
impl<C, E, EM, I, M, R, S, Z> StdMutationalStage<C, E, EM, I, M, R, S, Z> impl<E, EM, I, M, S, Z> StdMutationalStage<E, EM, I, M, S, Z>
where where
C: Corpus<I>,
M: Mutator<I, S>, M: Mutator<I, S>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// Creates a new default mutational stage /// Creates a new default mutational stage

View File

@ -34,16 +34,15 @@ const HAVOC_MAX_MULT: f64 = 64.0;
/// The mutational stage using power schedules /// The mutational stage using power schedules
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> pub struct PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata, S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
map_observer_name: String, map_observer_name: String,
@ -51,20 +50,19 @@ where
/// The employed power schedule strategy /// The employed power schedule strategy
strat: PowerSchedule, strat: PowerSchedule,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, I, O, OT, S, T, Z)>, phantom: PhantomData<(E, EM, I, O, OT, S, T, Z)>,
} }
impl<C, E, EM, I, M, O, OT, S, T, Z> MutationalStage<C, E, EM, I, M, S, Z> impl<E, EM, I, M, O, OT, S, T, Z> MutationalStage<E, EM, I, M, S, Z>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata, S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// The mutator, added to this stage /// The mutator, added to this stage
@ -155,17 +153,16 @@ where
} }
} }
impl<C, E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z> impl<E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata, S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
#[inline] #[inline]
@ -183,16 +180,15 @@ where
} }
} }
impl<C, E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> impl<E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
O: MapObserver<T>, O: MapObserver<T>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata, S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// Creates a new [`PowerMutationalStage`] /// Creates a new [`PowerMutationalStage`]

View File

@ -16,8 +16,8 @@ use core::{
}; };
use crate::{ use crate::{
bolts::{current_time, rands::Rand}, bolts::current_time,
corpus::{Corpus, CorpusScheduler}, corpus::CorpusScheduler,
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter}, events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
executors::ExitKind, executors::ExitKind,
inputs::Input, inputs::Input,
@ -32,15 +32,13 @@ const STATS_TIMEOUT_DEFAULT: Duration = Duration::from_secs(15);
// The shared state for all [`PushStage`]s // The shared state for all [`PushStage`]s
/// Should be stored inside a `[Rc<RefCell<_>>`] /// Should be stored inside a `[Rc<RefCell<_>>`]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PushStageSharedState<C, CS, EM, I, OT, R, S, Z> pub struct PushStageSharedState<CS, EM, I, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// The [`crate::state::State`] /// The [`crate::state::State`]
@ -51,18 +49,16 @@ where
pub event_mgr: EM, pub event_mgr: EM,
/// The [`crate::observers::ObserversTuple`] /// The [`crate::observers::ObserversTuple`]
pub observers: OT, pub observers: OT,
phantom: PhantomData<(C, CS, I, OT, R, S, Z)>, phantom: PhantomData<(CS, I, OT, S, Z)>,
} }
impl<C, CS, EM, I, OT, R, S, Z> PushStageSharedState<C, CS, EM, I, OT, R, S, Z> impl<CS, EM, I, OT, S, Z> PushStageSharedState<CS, EM, I, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s /// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s
@ -80,15 +76,13 @@ where
/// Helper class for the [`PushStage`] trait, taking care of borrowing the shared state /// Helper class for the [`PushStage`] trait, taking care of borrowing the shared state
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PushStageHelper<C, CS, EM, I, OT, R, S, Z> pub struct PushStageHelper<CS, EM, I, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// If this stage has already been initalized. /// If this stage has already been initalized.
@ -98,7 +92,7 @@ where
pub last_monitor_time: Duration, pub last_monitor_time: Duration,
/// The shared state, keeping track of the corpus and the fuzzer /// The shared state, keeping track of the corpus and the fuzzer
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>, pub shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
/// If the last iteraation failed /// If the last iteraation failed
pub errored: bool, pub errored: bool,
@ -109,26 +103,24 @@ where
pub current_input: Option<I>, // Todo: Get rid of copy pub current_input: Option<I>, // Todo: Get rid of copy
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, CS, (), EM, I, R, OT, S, Z)>, phantom: PhantomData<(CS, (), EM, I, OT, S, Z)>,
exit_kind: Rc<Cell<Option<ExitKind>>>, exit_kind: Rc<Cell<Option<ExitKind>>>,
} }
impl<C, CS, EM, I, OT, R, S, Z> PushStageHelper<C, CS, EM, I, OT, R, S, Z> impl<CS, EM, I, OT, S, Z> PushStageHelper<CS, EM, I, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Create a new [`PushStageHelper`] /// Create a new [`PushStageHelper`]
#[must_use] #[must_use]
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn new( pub fn new(
shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>, shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
exit_kind_ref: Rc<Cell<Option<ExitKind>>>, exit_kind_ref: Rc<Cell<Option<ExitKind>>>,
) -> Self { ) -> Self {
Self { Self {
@ -145,17 +137,14 @@ where
/// Sets the shared state for this helper (and all other helpers owning the same [`RefCell`]) /// Sets the shared state for this helper (and all other helpers owning the same [`RefCell`])
#[inline] #[inline]
pub fn set_shared_state( pub fn set_shared_state(&mut self, shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>) {
&mut self,
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>,
) {
(&mut *self.shared_state.borrow_mut()).replace(shared_state); (&mut *self.shared_state.borrow_mut()).replace(shared_state);
} }
/// Takes the shared state from this helper, replacing it with `None` /// Takes the shared state from this helper, replacing it with `None`
#[inline] #[inline]
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn take_shared_state(&mut self) -> Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>> { pub fn take_shared_state(&mut self) -> Option<PushStageSharedState<CS, EM, I, OT, S, Z>> {
let shared_state_ref = &mut (*self.shared_state).borrow_mut(); let shared_state_ref = &mut (*self.shared_state).borrow_mut();
shared_state_ref.take() shared_state_ref.take()
} }
@ -176,7 +165,7 @@ where
/// Resets this state after a full stage iter. /// Resets this state after a full stage iter.
fn end_of_iter( fn end_of_iter(
&mut self, &mut self,
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>, shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>,
errored: bool, errored: bool,
) { ) {
self.set_shared_state(shared_state); self.set_shared_state(shared_state);
@ -191,21 +180,19 @@ where
/// A push stage is a generator that returns a single testcase for each call. /// A push stage is a generator that returns a single testcase for each call.
/// It's an iterator so we can chain it. /// It's an iterator so we can chain it.
/// After it has finished once, we will call it agan for the next fuzzer round. /// After it has finished once, we will call it agan for the next fuzzer round.
pub trait PushStage<C, CS, EM, I, OT, R, S, Z>: Iterator pub trait PushStage<CS, EM, I, OT, S, Z>: Iterator
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Gets the [`PushStageHelper`] /// Gets the [`PushStageHelper`]
fn push_stage_helper(&self) -> &PushStageHelper<C, CS, EM, I, OT, R, S, Z>; fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, I, OT, S, Z>;
/// Gets the [`PushStageHelper`], mut /// Gets the [`PushStageHelper`], mut
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<C, CS, EM, I, OT, R, S, Z>; fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<CS, EM, I, OT, S, Z>;
/// Set the current corpus index this stagve works on /// Set the current corpus index this stagve works on
fn set_current_corpus_idx(&mut self, corpus_idx: usize) { fn set_current_corpus_idx(&mut self, corpus_idx: usize) {

View File

@ -35,16 +35,14 @@ pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
/// ///
/// The default mutational push stage /// The default mutational push stage
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z> pub struct StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
current_corpus_idx: Option<usize>, current_corpus_idx: Option<usize>,
@ -55,19 +53,17 @@ where
mutator: M, mutator: M,
psh: PushStageHelper<C, CS, EM, I, OT, R, S, Z>, psh: PushStageHelper<CS, EM, I, OT, S, Z>,
} }
impl<C, CS, EM, I, M, OT, R, S, Z> StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z> impl<CS, EM, I, M, OT, S, Z> StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Gets the number of iterations as a random number /// Gets the number of iterations as a random number
@ -82,17 +78,15 @@ where
} }
} }
impl<C, CS, EM, I, M, OT, R, S, Z> PushStage<C, CS, EM, I, OT, R, S, Z> impl<CS, EM, I, M, OT, S, Z> PushStage<CS, EM, I, OT, S, Z>
for StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z> for StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Creates a new default mutational stage /// Creates a new default mutational stage
@ -186,26 +180,24 @@ where
} }
#[inline] #[inline]
fn push_stage_helper(&self) -> &PushStageHelper<C, CS, EM, I, OT, R, S, Z> { fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, I, OT, S, Z> {
&self.psh &self.psh
} }
#[inline] #[inline]
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<C, CS, EM, I, OT, R, S, Z> { fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<CS, EM, I, OT, S, Z> {
&mut self.psh &mut self.psh
} }
} }
impl<C, CS, EM, I, M, OT, R, S, Z> Iterator for StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z> impl<CS, EM, I, M, OT, S, Z> Iterator for StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
type Item = Result<I, Error>; type Item = Result<I, Error>;
@ -215,16 +207,14 @@ where
} }
} }
impl<C, CS, EM, I, M, OT, R, S, Z> StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z> impl<CS, EM, I, M, OT, S, Z> StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where where
C: Corpus<I>,
CS: CorpusScheduler<I, S>, CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId, EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input, I: Input,
M: Mutator<I, S>, M: Mutator<I, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>, Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{ {
/// Creates a new default mutational stage /// Creates a new default mutational stage
@ -232,7 +222,7 @@ where
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn new( pub fn new(
mutator: M, mutator: M,
shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>, shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
exit_kind: Rc<Cell<Option<ExitKind>>>, exit_kind: Rc<Cell<Option<ExitKind>>>,
stage_idx: i32, stage_idx: i32,
) -> Self { ) -> Self {

View File

@ -10,8 +10,6 @@ use std::{
}; };
use crate::{ use crate::{
bolts::rands::Rand,
corpus::Corpus,
fuzzer::Evaluator, fuzzer::Evaluator,
inputs::Input, inputs::Input,
stages::Stage, stages::Stage,
@ -38,28 +36,24 @@ impl SyncFromDiskMetadata {
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++ /// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
#[derive(Debug)] #[derive(Debug)]
pub struct SyncFromDiskStage<C, CB, E, EM, I, R, S, Z> pub struct SyncFromDiskStage<CB, E, EM, I, S, Z>
where where
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>, CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
sync_dir: PathBuf, sync_dir: PathBuf,
load_callback: CB, load_callback: CB,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, I, R, S, Z)>, phantom: PhantomData<(E, EM, I, S, Z)>,
} }
impl<C, CB, E, EM, I, R, S, Z> Stage<E, EM, S, Z> for SyncFromDiskStage<C, CB, E, EM, I, R, S, Z> impl<CB, E, EM, I, S, Z> Stage<E, EM, S, Z> for SyncFromDiskStage<CB, E, EM, I, S, Z>
where where
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>, CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
#[inline] #[inline]
@ -99,13 +93,11 @@ where
} }
} }
impl<C, CB, E, EM, I, R, S, Z> SyncFromDiskStage<C, CB, E, EM, I, R, S, Z> impl<CB, E, EM, I, S, Z> SyncFromDiskStage<CB, E, EM, I, S, Z>
where where
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>, CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// Creates a new [`SyncFromDiskStage`] /// Creates a new [`SyncFromDiskStage`]
@ -163,13 +155,11 @@ where
} }
} }
impl<C, E, EM, I, R, S, Z> impl<E, EM, I, S, Z>
SyncFromDiskStage<C, fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, R, S, Z> SyncFromDiskStage<fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, S, Z>
where where
C: Corpus<I>,
I: Input, I: Input,
R: Rand, S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
Z: Evaluator<E, EM, I, S>, Z: Evaluator<E, EM, I, S>,
{ {
/// Creates a new [`SyncFromDiskStage`] invoking `Input::from_file` to load inputs /// Creates a new [`SyncFromDiskStage`] invoking `Input::from_file` to load inputs

View File

@ -19,26 +19,24 @@ use crate::monitors::PerfFeature;
/// A stage that runs a tracer executor /// A stage that runs a tracer executor
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct TracingStage<C, EM, I, OT, S, TE, Z> pub struct TracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
tracer_executor: TE, tracer_executor: TE,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, EM, I, OT, S, TE, Z)>, phantom: PhantomData<(EM, I, OT, S, TE, Z)>,
} }
impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<C, EM, I, OT, S, TE, Z> impl<E, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
#[inline] #[inline]
fn perform( fn perform(
@ -82,13 +80,12 @@ where
} }
} }
impl<C, EM, I, OT, S, TE, Z> TracingStage<C, EM, I, OT, S, TE, Z> impl<EM, I, OT, S, TE, Z> TracingStage<EM, I, OT, S, TE, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
/// Creates a new default stage /// Creates a new default stage
pub fn new(tracer_executor: TE) -> Self { pub fn new(tracer_executor: TE) -> Self {
@ -106,20 +103,19 @@ where
/// A stage that runs the shadow executor using also the shadow observers /// A stage that runs the shadow executor using also the shadow observers
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z> { pub struct ShadowTracingStage<E, EM, I, OT, S, SOT, Z> {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, I, OT, S, SOT, Z)>, phantom: PhantomData<(E, EM, I, OT, S, SOT, Z)>,
} }
impl<C, E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z> impl<E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
for ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z> for ShadowTracingStage<E, EM, I, OT, S, SOT, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
SOT: ObserversTuple<I, S>, SOT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I> + Debug, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I> + Debug,
{ {
#[inline] #[inline]
fn perform( fn perform(
@ -163,14 +159,13 @@ where
} }
} }
impl<C, E, EM, I, OT, S, SOT, Z> ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z> impl<E, EM, I, OT, S, SOT, Z> ShadowTracingStage<E, EM, I, OT, S, SOT, Z>
where where
I: Input, I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
SOT: ObserversTuple<I, S>, SOT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>, S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{ {
/// Creates a new default stage /// Creates a new default stage
pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self { pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self {

View File

@ -32,15 +32,13 @@ pub const DEFAULT_MAX_SIZE: usize = 1_048_576;
pub trait State: Serialize + DeserializeOwned {} pub trait State: Serialize + DeserializeOwned {}
/// Trait for elements offering a corpus /// Trait for elements offering a corpus
pub trait HasCorpus<C, I> pub trait HasCorpus<I: Input> {
where /// The associated type implementing [`Corpus`].
C: Corpus<I>, type Corpus: Corpus<I>;
I: Input,
{
/// The testcase corpus /// The testcase corpus
fn corpus(&self) -> &C; fn corpus(&self) -> &Self::Corpus;
/// The testcase corpus (mut) /// The testcase corpus (mut)
fn corpus_mut(&mut self) -> &mut C; fn corpus_mut(&mut self) -> &mut Self::Corpus;
} }
/// Interact with the maximum size /// Interact with the maximum size
@ -52,26 +50,23 @@ pub trait HasMaxSize {
} }
/// Trait for elements offering a corpus of solutions /// Trait for elements offering a corpus of solutions
pub trait HasSolutions<C, I> pub trait HasSolutions<I: Input> {
where /// The associated type implementing [`Corpus`] for solutions
C: Corpus<I>, type Solutions: Corpus<I>;
I: Input,
{
/// The solutions corpus /// The solutions corpus
fn solutions(&self) -> &C; fn solutions(&self) -> &Self::Solutions;
/// The solutions corpus (mut) /// The solutions corpus (mut)
fn solutions_mut(&mut self) -> &mut C; fn solutions_mut(&mut self) -> &mut Self::Solutions;
} }
/// Trait for elements offering a rand /// Trait for elements offering a rand
pub trait HasRand<R> pub trait HasRand {
where /// The associated type implementing [`Rand`]
R: Rand, type Rand: Rand;
{
/// The rand instance /// The rand instance
fn rand(&self) -> &R; fn rand(&self) -> &Self::Rand;
/// The rand instance (mut) /// The rand instance (mut)
fn rand_mut(&mut self) -> &mut R; fn rand_mut(&mut self) -> &mut Self::Rand;
} }
/// Trait for offering a [`ClientPerfMonitor`] /// Trait for offering a [`ClientPerfMonitor`]
@ -116,15 +111,14 @@ pub trait HasMetadata {
} }
/// Trait for elements offering a feedback /// Trait for elements offering a feedback
pub trait HasFeedbackStates<FT> pub trait HasFeedbackStates {
where /// The associated feedback type implementing [`FeedbackStatesTuple`].
FT: FeedbackStatesTuple, type FeedbackStates: FeedbackStatesTuple;
{
/// The feedback states /// The feedback states
fn feedback_states(&self) -> &FT; fn feedback_states(&self) -> &Self::FeedbackStates;
/// The feedback states (mut) /// The feedback states (mut)
fn feedback_states_mut(&mut self) -> &mut FT; fn feedback_states_mut(&mut self) -> &mut Self::FeedbackStates;
} }
/// Trait for the execution counter /// Trait for the execution counter
@ -192,7 +186,7 @@ where
{ {
} }
impl<C, FT, I, R, SC> HasRand<R> for StdState<C, FT, I, R, SC> impl<C, FT, I, R, SC> HasRand for StdState<C, FT, I, R, SC>
where where
C: Corpus<I>, C: Corpus<I>,
I: Input, I: Input,
@ -200,20 +194,22 @@ where
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
SC: Corpus<I>, SC: Corpus<I>,
{ {
type Rand = R;
/// The rand instance /// The rand instance
#[inline] #[inline]
fn rand(&self) -> &R { fn rand(&self) -> &Self::Rand {
&self.rand &self.rand
} }
/// The rand instance (mut) /// The rand instance (mut)
#[inline] #[inline]
fn rand_mut(&mut self) -> &mut R { fn rand_mut(&mut self) -> &mut Self::Rand {
&mut self.rand &mut self.rand
} }
} }
impl<C, FT, I, R, SC> HasCorpus<C, I> for StdState<C, FT, I, R, SC> impl<C, FT, I, R, SC> HasCorpus<I> for StdState<C, FT, I, R, SC>
where where
C: Corpus<I>, C: Corpus<I>,
I: Input, I: Input,
@ -221,6 +217,8 @@ where
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
SC: Corpus<I>, SC: Corpus<I>,
{ {
type Corpus = C;
/// Returns the corpus /// Returns the corpus
#[inline] #[inline]
fn corpus(&self) -> &C { fn corpus(&self) -> &C {
@ -234,7 +232,7 @@ where
} }
} }
impl<C, FT, I, R, SC> HasSolutions<SC, I> for StdState<C, FT, I, R, SC> impl<C, FT, I, R, SC> HasSolutions<I> for StdState<C, FT, I, R, SC>
where where
C: Corpus<I>, C: Corpus<I>,
I: Input, I: Input,
@ -242,6 +240,8 @@ where
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
SC: Corpus<I>, SC: Corpus<I>,
{ {
type Solutions = SC;
/// Returns the solutions corpus /// Returns the solutions corpus
#[inline] #[inline]
fn solutions(&self) -> &SC { fn solutions(&self) -> &SC {
@ -276,7 +276,7 @@ where
} }
} }
impl<C, FT, I, R, SC> HasFeedbackStates<FT> for StdState<C, FT, I, R, SC> impl<C, FT, I, R, SC> HasFeedbackStates for StdState<C, FT, I, R, SC>
where where
C: Corpus<I>, C: Corpus<I>,
I: Input, I: Input,
@ -284,6 +284,8 @@ where
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
SC: Corpus<I>, SC: Corpus<I>,
{ {
type FeedbackStates = FT;
/// The feedback states /// The feedback states
#[inline] #[inline]
fn feedback_states(&self) -> &FT { fn feedback_states(&self) -> &FT {

View File

@ -7,7 +7,6 @@ use core::{
}; };
use libafl::{ use libafl::{
corpus::Corpus,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
inprocess::inprocess_get_state, Executor, ExitKind, HasObservers, InProcessExecutor, inprocess::inprocess_get_state, Executor, ExitKind, HasObservers, InProcessExecutor,
@ -474,7 +473,7 @@ where
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
QT: QemuHelperTuple<I, S>, QT: QemuHelperTuple<I, S>,
{ {
pub fn new<EM, OC, OF, Z>( pub fn new<EM, OF, Z>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
emulator: &'a Emulator, emulator: &'a Emulator,
helpers: QT, helpers: QT,
@ -485,9 +484,8 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I> + EventRestarter<S>, EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>, OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor, S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>, Z: HasObjective<I, OF, S>,
{ {
let slf = Self { let slf = Self {