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);
// 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
let objective = CrashFeedback::new();

View File

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

View File

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

View File

@ -81,29 +81,26 @@ where
/// corpus that exercise all the requested features (e.g. all the coverage seen so far)
/// prioritizing [`Testcase`]`s` using [`FavFactor`]
#[derive(Debug, Clone)]
pub struct MinimizerCorpusScheduler<C, CS, F, I, M, R, S>
pub struct MinimizerCorpusScheduler<CS, F, I, M, S>
where
CS: CorpusScheduler<I, S>,
F: FavFactor<I>,
I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
S: HasCorpus<I> + HasMetadata,
{
base: CS,
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
CS: CorpusScheduler<I, S>,
F: FavFactor<I>,
I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata + HasRand<R>,
C: Corpus<I>,
R: Rand,
S: HasCorpus<I> + HasMetadata + HasRand,
{
/// Add an entry to the corpus and return its index
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
CS: CorpusScheduler<I, S>,
F: FavFactor<I>,
I: Input,
M: AsSlice<usize> + SerdeAny + HasRefCnt,
S: HasCorpus<C, I> + HasMetadata + HasRand<R>,
C: Corpus<I>,
R: Rand,
S: HasCorpus<I> + HasMetadata + HasRand,
{
/// Update the `Corpus` score using the `MinimizerCorpusScheduler`
#[allow(clippy::unused_self)]
@ -284,10 +279,10 @@ where
}
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`.
pub type LenTimeMinimizerCorpusScheduler<C, CS, I, M, R, S> =
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, M, R, S>;
pub type LenTimeMinimizerCorpusScheduler<CS, I, M, S> =
MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, M, S>;
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`
/// that exercise all the entries registered in the [`MapIndexesMetadata`].
pub type IndexesLenTimeMinimizerCorpusScheduler<C, CS, I, R, S> =
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, R, S>;
pub type IndexesLenTimeMinimizerCorpusScheduler<CS, I, S> =
MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, S>;

View File

@ -30,7 +30,7 @@ pub mod powersched;
pub use powersched::PowerQueueCorpusScheduler;
use alloc::borrow::ToOwned;
use core::{cell::RefCell, marker::PhantomData};
use core::cell::RefCell;
use crate::{
bolts::rands::Rand,
@ -108,22 +108,12 @@ where
/// Feed the fuzzer simpply with a random testcase on request
#[derive(Debug, Clone)]
pub struct RandCorpusScheduler<C, I, R, S>
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
phantom: PhantomData<(C, I, R, S)>,
}
pub struct RandCorpusScheduler;
impl<C, I, R, S> CorpusScheduler<I, S> for RandCorpusScheduler<C, I, R, S>
impl<I, S> CorpusScheduler<I, S> for RandCorpusScheduler
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
S: HasCorpus<I> + HasRand,
I: Input,
R: Rand,
{
/// Gets the next entry at random
fn next(&self, state: &mut S) -> Result<usize, Error> {
@ -138,29 +128,15 @@ where
}
}
impl<C, I, R, S> RandCorpusScheduler<C, I, R, S>
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
impl RandCorpusScheduler {
/// Create a new [`RandCorpusScheduler`] that just schedules randomly.
#[must_use]
pub fn new() -> Self {
Self {
phantom: PhantomData,
}
Self
}
}
impl<C, I, R, S> Default for RandCorpusScheduler<C, I, R, S>
where
S: HasCorpus<C, I> + HasRand<R>,
C: Corpus<I>,
I: Input,
R: Rand,
{
impl Default for RandCorpusScheduler {
fn default() -> Self {
Self::new()
}
@ -168,4 +144,4 @@ where
/// 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.
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.
use alloc::string::{String, ToString};
use core::marker::PhantomData;
use crate::{
corpus::{Corpus, CorpusScheduler, PowerScheduleTestcaseMetaData},
@ -13,30 +12,17 @@ use crate::{
/// A corpus scheduler using power schedules
#[derive(Clone, Debug)]
pub struct PowerQueueCorpusScheduler<C, I, S>
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
phantom: PhantomData<(C, I, S)>,
}
pub struct PowerQueueCorpusScheduler;
impl<C, I, S> Default for PowerQueueCorpusScheduler<C, I, S>
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
impl Default for PowerQueueCorpusScheduler {
fn default() -> Self {
Self::new()
}
}
impl<C, I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler<C, I, S>
impl<I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
S: HasCorpus<I> + HasMetadata,
I: Input,
{
/// Add an entry to the corpus and return its index
@ -92,17 +78,10 @@ where
}
}
impl<C, I, S> PowerQueueCorpusScheduler<C, I, S>
where
S: HasCorpus<C, I> + HasMetadata,
C: Corpus<I>,
I: Input,
{
impl PowerQueueCorpusScheduler {
/// Create a new [`PowerQueueCorpusScheduler`]
#[must_use]
pub fn new() -> Self {
Self {
phantom: PhantomData,
}
Self
}
}

View File

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

View File

@ -11,10 +11,7 @@ use crate::{
};
use alloc::{string::ToString, vec::Vec};
#[cfg(feature = "std")]
use core::{
marker::PhantomData,
sync::atomic::{compiler_fence, Ordering},
};
use core::sync::atomic::{compiler_fence, Ordering};
#[cfg(feature = "std")]
use serde::{de::DeserializeOwned, Serialize};
@ -232,11 +229,9 @@ where
#[cfg(feature = "std")]
#[allow(clippy::default_trait_access)]
#[derive(Debug, Clone)]
pub struct SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
pub struct SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>,
{
@ -244,17 +239,12 @@ where
simple_event_mgr: SimpleEventManager<I, MT>,
/// [`StateRestorer`] for restarts
staterestorer: StateRestorer<SP>,
/// Phantom data
_phantom: PhantomData<&'a (C, I, S, SC)>,
}
#[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> EventFirer<I>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<I, MT, SP> EventFirer<I> for SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>,
{
@ -264,10 +254,8 @@ where
}
#[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> EventRestarter<S>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
@ -282,10 +270,8 @@ where
}
#[cfg(feature = "std")]
impl<'a, C, E, I, MT, S, SC, SP, Z> EventProcessor<E, I, S, Z>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<E, I, S, SP, MT, Z> EventProcessor<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
@ -297,10 +283,8 @@ where
}
#[cfg(feature = "std")]
impl<'a, C, E, I, MT, S, SC, SP, Z> EventManager<E, I, S, Z>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<E, I, S, SP, MT, Z> EventManager<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
@ -309,24 +293,18 @@ where
}
#[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> ProgressReporter<I>
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<I, MT, SP> ProgressReporter<I> for SimpleRestartingEventManager<I, MT, SP>
where
I: Input,
C: Corpus<I>,
S: Serialize,
SP: ShMemProvider,
MT: Monitor, //CE: CustomEvent<I, OT>,
{
}
#[cfg(feature = "std")]
impl<'a, C, I, MT, S, SC, SP> HasEventManagerId
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
impl<I, MT, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, SP>
where
C: Corpus<I>,
I: Input,
S: Serialize,
SP: ShMemProvider,
MT: Monitor,
{
@ -337,12 +315,9 @@ where
#[cfg(feature = "std")]
#[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
C: Corpus<I>,
I: Input,
S: DeserializeOwned + Serialize + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
SP: ShMemProvider,
MT: Monitor, //TODO CE: CustomEvent,
{
@ -351,7 +326,6 @@ where
Self {
staterestorer,
simple_event_mgr: SimpleEventManager::new(monitor),
_phantom: PhantomData {},
}
}
@ -359,7 +333,10 @@ where
/// This [`EventManager`] is simple and single threaded,
/// but can still used shared maps to recover from crashes and timeouts.
#[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
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
// 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 crate::{
corpus::Corpus,
events::{EventFirer, EventRestarter},
executors::{Executor, ExitKind, HasObservers},
feedbacks::Feedback,
@ -127,7 +126,7 @@ where
/// * `harness_fn` - the harness, executiong the function
/// * `observers` - the observers observing the target during execution
/// 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,
observers: OT,
_fuzzer: &mut Z,
@ -136,12 +135,11 @@ where
) -> Result<Self, Error>
where
EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
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)]
unsafe {
/*
@ -267,15 +265,14 @@ impl 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
I: Input,
E: HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>,
{
#[cfg(unix)]
@ -285,18 +282,10 @@ impl InProcessHandlers {
compiler_fence(Ordering::SeqCst);
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 _,
timeout_handler: unix_signal_handler::inproc_timeout_handler::<
E,
EM,
I,
OC,
OF,
OT,
S,
Z,
> as *const _,
})
}
#[cfg(all(windows, feature = "std"))]
@ -310,7 +299,6 @@ impl InProcessHandlers {
E,
EM,
I,
OC,
OF,
OT,
S,
@ -320,7 +308,6 @@ impl InProcessHandlers {
E,
EM,
I,
OC,
OF,
OT,
S,
@ -493,7 +480,7 @@ mod unix_signal_handler {
}
#[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,
_info: siginfo_t,
_context: &mut ucontext_t,
@ -502,9 +489,8 @@ mod unix_signal_handler {
E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
I: Input,
Z: HasObjective<I, OF, S>,
{
@ -571,7 +557,7 @@ mod unix_signal_handler {
/// Will be used for signal handling.
/// It will store the current State to shmem, then exit.
#[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,
_info: siginfo_t,
_context: &mut ucontext_t,
@ -580,9 +566,8 @@ mod unix_signal_handler {
E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
I: Input,
Z: HasObjective<I, OF, S>,
{
@ -748,7 +733,7 @@ mod windows_exception_handler {
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,
global_state: *mut c_void,
_p1: *mut u8,
@ -756,9 +741,8 @@ mod windows_exception_handler {
E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
I: Input,
Z: HasObjective<I, OF, S>,
{
@ -847,16 +831,15 @@ mod windows_exception_handler {
// 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,
data: &mut InProcessExecutorHandlerData,
) where
E: HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S>,
OT: ObserversTuple<I, S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
I: Input,
Z: HasObjective<I, OF, S>,
{
@ -1085,7 +1068,7 @@ where
SP: ShMemProvider,
{
/// Creates a new [`InProcessForkExecutor`]
pub fn new<EM, OC, OF, Z>(
pub fn new<EM, OF, Z>(
harness_fn: &'a mut H,
observers: OT,
_fuzzer: &mut Z,
@ -1095,9 +1078,8 @@ where
) -> Result<Self, Error>
where
EM: EventFirer<I> + EventRestarter<S>,
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I> + HasClientPerfMonitor,
S: HasSolutions<I> + HasClientPerfMonitor,
Z: HasObjective<I, OF, S>,
{
Ok(Self {

View File

@ -9,11 +9,14 @@ use num_traits::PrimInt;
use serde::{Deserialize, Serialize};
use crate::{
bolts::{tuples::Named, AsSlice, HasRefCnt},
bolts::{
tuples::{MatchName, Named},
AsSlice, HasRefCnt,
},
corpus::Testcase,
events::{Event, EventFirer},
executors::ExitKind,
feedbacks::{Feedback, FeedbackState, FeedbackStatesTuple},
feedbacks::{Feedback, FeedbackState},
inputs::Input,
monitors::UserStats,
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``.
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.
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.
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,
/// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapPow2Feedback<FT, I, O, S, T> =
MapFeedback<FT, I, NextPow2IsNovel, O, MaxReducer, S, T>;
pub type MaxMapPow2Feedback<I, O, S, T> = MapFeedback<I, NextPow2IsNovel, O, MaxReducer, S, T>;
/// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapOneOrFilledFeedback<FT, I, O, S, T> =
MapFeedback<FT, I, OneOrFilledIsNovel, O, MaxReducer, S, T>;
pub type MaxMapOneOrFilledFeedback<I, O, S, T> =
MapFeedback<I, OneOrFilledIsNovel, O, MaxReducer, S, T>;
/// A `Reducer` function is used to aggregate values for the novelty search
pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static + Debug
@ -329,14 +331,13 @@ where
/// The most common AFL-like feedback type
#[derive(Serialize, Deserialize, Clone, Debug)]
#[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
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>,
O: MapObserver<T>,
N: IsNovel<T>,
S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple,
S: HasFeedbackStates,
{
/// Indexes used in the last observation
indexes: Option<Vec<usize>>,
@ -347,18 +348,17 @@ where
/// Name identifier of the observer
observer_name: String,
/// 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
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>,
O: MapObserver<T>,
N: IsNovel<T>,
I: Input,
S: HasFeedbackStates<FT> + HasClientPerfMonitor + Debug,
FT: FeedbackStatesTuple,
S: HasFeedbackStates + HasClientPerfMonitor + Debug,
{
fn is_interesting<EM, OT>(
&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
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
R: Reducer<T>,
N: IsNovel<T>,
O: MapObserver<T>,
S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple,
S: HasFeedbackStates,
{
#[inline]
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
T: PrimInt
+ Default
@ -487,8 +486,7 @@ where
R: Reducer<T>,
N: IsNovel<T>,
O: MapObserver<T>,
S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple,
S: HasFeedbackStates,
{
/// Create new `MapFeedback`
#[must_use]

View File

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

View File

@ -33,19 +33,17 @@ pub struct Automaton {
#[derive(Clone, Debug)]
/// Generates random inputs from a grammar automatron
pub struct GramatronGenerator<'a, R, S>
pub struct GramatronGenerator<'a, S>
where
R: Rand,
S: HasRand<R>,
S: HasRand,
{
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
fn generate(&mut self, state: &mut S) -> Result<GramatronInput, Error> {
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Returns a new [`GramatronGenerator`]
#[must_use]

View File

@ -35,19 +35,17 @@ where
#[derive(Clone, Debug)]
/// Generates random bytes
pub struct RandBytesGenerator<R, S>
pub struct RandBytesGenerator<S>
where
R: Rand,
S: HasRand<R>,
S: HasRand,
{
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
#[must_use]
@ -84,19 +81,17 @@ where
#[derive(Clone, Debug)]
/// Generates random printable characters
pub struct RandPrintablesGenerator<R, S>
pub struct RandPrintablesGenerator<S>
where
R: Rand,
S: HasRand<R>,
S: HasRand,
{
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
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
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters.
#[must_use]

View File

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

View File

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

View File

@ -360,29 +360,23 @@ pub enum MOptMode {
/// This is the main struct of `MOpt`, an `AFL` mutator.
/// 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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
mode: MOptMode,
finds_before: usize,
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
#[inline]
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
/// Create a new [`StdMOptMutator`].
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
/// Get the mutations
#[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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
SC: Corpus<I>,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
/// Compute the number of iterations used to apply stacked mutations
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::{
bolts::tuples::Named,
corpus::Corpus,
feedbacks::NautilusChunksMetadata,
generators::nautilus::NautilusContext,
inputs::nautilus::NautilusInput,
@ -11,7 +10,7 @@ use crate::{
Error,
};
use core::{fmt::Debug, marker::PhantomData};
use core::fmt::Debug;
use grammartec::mutator::Mutator as BackingMutator;
use grammartec::{
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(
&mut self,
_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 {
"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(
&mut self,
_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 {
"NautilusRecursionMutator"
}
@ -143,22 +142,20 @@ impl<'a> NautilusRecursionMutator<'a> {
}
/// The splicing mutator for `Nautilus` that can splice inputs together
pub struct NautilusSpliceMutator<'a, C> {
pub struct NautilusSpliceMutator<'a> {
ctx: &'a Context,
mutator: BackingMutator,
phantom: PhantomData<C>,
}
impl Debug for NautilusSpliceMutator<'_, ()> {
impl Debug for NautilusSpliceMutator<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NautilusSpliceMutator {{}}")
}
}
impl<'a, S, C> Mutator<NautilusInput, S> for NautilusSpliceMutator<'a, C>
impl<S> Mutator<NautilusInput, S> for NautilusSpliceMutator<'_>
where
C: Corpus<NautilusInput>,
S: HasCorpus<C, NautilusInput> + HasMetadata,
S: HasCorpus<NautilusInput> + HasMetadata,
{
fn mutate(
&mut self,
@ -194,13 +191,13 @@ where
}
}
impl<'a, C> Named for NautilusSpliceMutator<'a, C> {
impl Named for NautilusSpliceMutator<'_> {
fn name(&self) -> &str {
"NautilusSpliceMutator"
}
}
impl<'a, C> NautilusSpliceMutator<'a, C> {
impl<'a> NautilusSpliceMutator<'a> {
/// Creates a new [`NautilusSpliceMutator`].
#[must_use]
pub fn new(context: &'a NautilusContext) -> Self {
@ -208,7 +205,6 @@ impl<'a, C> NautilusSpliceMutator<'a, C> {
Self {
ctx: &context.ctx,
mutator,
phantom: PhantomData,
}
}
}

View File

@ -14,9 +14,9 @@ use crate::{
AsSlice,
},
corpus::Corpus,
inputs::{HasBytesVec, Input},
inputs::Input,
mutators::{MutationResult, Mutator, MutatorsTuple},
state::{HasCorpus, HasMaxSize, HasMetadata, HasRand},
state::{HasCorpus, HasMetadata, HasRand},
Error,
};
@ -95,24 +95,22 @@ where
}
/// 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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
mutations: MT,
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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
#[inline]
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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Get the mutations
#[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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Compute the number of iterations used to apply stacked mutations
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
I: Input,
MT: MutatorsTuple<I, S>,
R: Rand,
S: HasRand<R>,
S: HasRand,
{
/// Create a new [`StdScheduledMutator`] instance specifying mutations
pub fn new(mutations: MT) -> Self {
@ -209,41 +203,35 @@ where
/// Get the mutations that compose the Havoc mutator
#[must_use]
pub fn havoc_mutations<C, I, R, S>() -> tuple_list_type!(
BitFlipMutator<I, R, S>,
ByteFlipMutator<I, R, S>,
ByteIncMutator<I, R, S>,
ByteDecMutator<I, R, S>,
ByteNegMutator<I, R, S>,
ByteRandMutator<I, R, S>,
ByteAddMutator<I, R, S>,
WordAddMutator<I, R, S>,
DwordAddMutator<I, R, S>,
QwordAddMutator<I, R, S>,
ByteInterestingMutator<I, R, S>,
WordInterestingMutator<I, R, S>,
DwordInterestingMutator<I, R, S>,
BytesDeleteMutator<I, R, S>,
BytesDeleteMutator<I, R, S>,
BytesDeleteMutator<I, R, S>,
BytesDeleteMutator<I, R, S>,
BytesExpandMutator<I, R, S>,
BytesInsertMutator<I, R, S>,
BytesRandInsertMutator<I, R, S>,
BytesSetMutator<I, R, S>,
BytesRandSetMutator<I, R, S>,
BytesCopyMutator<I, R, S>,
BytesInsertCopyMutator<I, R, S>,
BytesSwapMutator<I, R, S>,
CrossoverInsertMutator<C, I, R, S>,
CrossoverReplaceMutator<C, I, R, S>,
)
where
I: Input + HasBytesVec,
S: HasRand<R> + HasCorpus<C, I> + HasMetadata + HasMaxSize,
C: Corpus<I>,
R: Rand,
{
pub fn havoc_mutations() -> tuple_list_type!(
BitFlipMutator,
ByteFlipMutator,
ByteIncMutator,
ByteDecMutator,
ByteNegMutator,
ByteRandMutator,
ByteAddMutator,
WordAddMutator,
DwordAddMutator,
QwordAddMutator,
ByteInterestingMutator,
WordInterestingMutator,
DwordInterestingMutator,
BytesDeleteMutator,
BytesDeleteMutator,
BytesDeleteMutator,
BytesDeleteMutator,
BytesExpandMutator,
BytesInsertMutator,
BytesRandInsertMutator,
BytesSetMutator,
BytesRandSetMutator,
BytesCopyMutator,
BytesInsertCopyMutator,
BytesSwapMutator,
CrossoverInsertMutator,
CrossoverReplaceMutator,
) {
tuple_list!(
BitFlipMutator::new(),
ByteFlipMutator::new(),
@ -277,39 +265,28 @@ where
/// Get the mutations that uses the Tokens metadata
#[must_use]
pub fn tokens_mutations<C, I, R, S>(
) -> 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,
{
pub fn tokens_mutations() -> tuple_list_type!(TokenInsert, TokenReplace) {
tuple_list!(TokenInsert::new(), TokenReplace::new(),)
}
/// 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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
scheduled: SM,
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
fn mutate(
@ -362,14 +337,11 @@ where
}
}
impl<C, I, MT, R, S, SM> ComposedByMutations<I, MT, S>
for LoggerScheduledMutator<C, I, MT, R, S, SM>
impl<I, MT, S, SM> ComposedByMutations<I, MT, S> for LoggerScheduledMutator<I, MT, S, SM>
where
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
#[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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
/// 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
C: Corpus<I>,
I: Input,
MT: MutatorsTuple<I, S> + NamedTuple,
R: Rand,
S: HasRand<R> + HasCorpus<C, I>,
S: HasRand + HasCorpus<I>,
SM: ScheduledMutator<I, MT, S>,
{
/// Create a new [`StdScheduledMutator`] instance without mutations and corpus

View File

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

View File

@ -2,10 +2,11 @@
use crate::{
bolts::current_time,
bolts::tuples::MatchName,
corpus::{Corpus, PowerScheduleTestcaseMetaData},
events::{EventFirer, LogSeverity},
executors::{Executor, ExitKind, HasObservers},
feedbacks::{FeedbackStatesTuple, MapFeedbackState},
feedbacks::MapFeedbackState,
fuzzer::Evaluator,
inputs::Input,
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.
#[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
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,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
S: HasCorpus<I> + HasMetadata,
{
map_observer_name: String,
stage_max: usize,
#[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, FT, I, O, OT, S, T, Z)>,
phantom: PhantomData<(I, O, OT, S, T)>,
}
const CAL_STAGE_START: usize = 4;
const CAL_STAGE_MAX: usize = 16;
impl<C, E, EM, FT, I, O, OT, S, T, Z> Stage<E, EM, S, Z>
for CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z>
impl<E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z> for CalibrationStage<I, O, OT, S, T>
where
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,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata + HasFeedbackStates<FT> + HasClientPerfMonitor,
S: HasCorpus<I> + HasMetadata + HasFeedbackStates + HasClientPerfMonitor,
Z: Evaluator<E, EM, I, S>,
{
#[inline]
@ -314,18 +306,13 @@ impl 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
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,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasCorpus<C, I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
S: HasCorpus<I> + HasMetadata,
{
/// Create a new [`CalibrationStage`].
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.
#[derive(Clone, Debug)]
pub struct ConcolicTracingStage<C, EM, I, OT, S, TE, Z>
pub struct ConcolicTracingStage<EM, I, OT, S, TE, Z>
where
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, 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,
}
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
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
#[inline]
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
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, 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.
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 {
inner,
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`].
#[derive(Clone, Debug)]
pub struct SimpleConcolicMutationalStage<C, EM, I, S, Z>
pub struct SimpleConcolicMutationalStage<EM, I, S, Z>
where
I: Input,
C: Corpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
_phantom: PhantomData<(C, EM, I, S, Z)>,
_phantom: PhantomData<(EM, I, S, Z)>,
}
#[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
I: Input + HasBytesVec,
C: Corpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
Z: Evaluator<E, EM, I, S>,
{
#[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
I: Input,
C: Corpus<I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
fn default() -> Self {
Self {

View File

@ -32,8 +32,7 @@ pub mod sync;
pub use sync::*;
use crate::{
bolts::rands::Rand,
corpus::{Corpus, CorpusScheduler},
corpus::CorpusScheduler,
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
executors::{Executor, HasObservers},
inputs::Input,
@ -164,32 +163,28 @@ where
/// Allows us to use a [`push::PushStage`] as a normal [`Stage`]
#[allow(clippy::type_complexity)]
#[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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
PS: PushStage<CS, EM, I, OT, S, Z>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
PS: PushStage<CS, EM, I, OT, S, Z>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// 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>
for PushStageAdapter<C, CS, EM, I, OT, PS, R, 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>
where
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
OT: ObserversTuple<I, S>,
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
PS: PushStage<CS, EM, I, OT, S, Z>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutesInput<I, OT, S, Z>
+ ExecutionProcessor<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.
/// Mutational stages will usually have a range of mutations that are
/// 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
C: Corpus<I>,
M: Mutator<I, S>,
I: Input,
S: HasClientPerfMonitor + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasCorpus<I>,
Z: Evaluator<E, EM, I, S>,
{
/// The mutator registered for this stage
@ -84,28 +83,23 @@ pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
/// The default mutational stage
#[derive(Clone, Debug)]
pub struct StdMutationalStage<C, E, EM, I, M, R, S, Z>
pub struct StdMutationalStage<E, EM, I, M, S, Z>
where
C: Corpus<I>,
M: Mutator<I, S>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: Evaluator<E, EM, I, S>,
{
mutator: M,
#[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>
for StdMutationalStage<C, E, EM, I, M, R, S, Z>
impl<E, EM, I, M, S, Z> MutationalStage<E, EM, I, M, S, Z> for StdMutationalStage<E, EM, I, M, S, Z>
where
C: Corpus<I>,
M: Mutator<I, S>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: Evaluator<E, EM, I, S>,
{
/// 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
C: Corpus<I>,
M: Mutator<I, S>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: Evaluator<E, EM, I, S>,
{
#[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
C: Corpus<I>,
M: Mutator<I, S>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: Evaluator<E, EM, I, S>,
{
/// 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
#[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
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input,
M: Mutator<I, S>,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
map_observer_name: String,
@ -51,20 +50,19 @@ where
/// The employed power schedule strategy
strat: PowerSchedule,
#[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>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
impl<E, EM, I, M, O, OT, S, T, Z> MutationalStage<E, EM, I, M, S, Z>
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input,
M: Mutator<I, S>,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
/// 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>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
impl<E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input,
M: Mutator<I, S>,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
#[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
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input,
M: Mutator<I, S>,
O: MapObserver<T>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
/// Creates a new [`PowerMutationalStage`]

View File

@ -16,8 +16,8 @@ use core::{
};
use crate::{
bolts::{current_time, rands::Rand},
corpus::{Corpus, CorpusScheduler},
bolts::current_time,
corpus::CorpusScheduler,
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
executors::ExitKind,
inputs::Input,
@ -32,15 +32,13 @@ const STATS_TIMEOUT_DEFAULT: Duration = Duration::from_secs(15);
// The shared state for all [`PushStage`]s
/// Should be stored inside a `[Rc<RefCell<_>>`]
#[derive(Clone, Debug)]
pub struct PushStageSharedState<C, CS, EM, I, OT, R, S, Z>
pub struct PushStageSharedState<CS, EM, I, OT, S, Z>
where
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// The [`crate::state::State`]
@ -51,18 +49,16 @@ where
pub event_mgr: EM,
/// The [`crate::observers::ObserversTuple`]
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
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
@ -80,15 +76,13 @@ where
/// Helper class for the [`PushStage`] trait, taking care of borrowing the shared state
#[derive(Clone, Debug)]
pub struct PushStageHelper<C, CS, EM, I, OT, R, S, Z>
pub struct PushStageHelper<CS, EM, I, OT, S, Z>
where
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// If this stage has already been initalized.
@ -98,7 +92,7 @@ where
pub last_monitor_time: Duration,
/// The shared state, keeping track of the corpus and the fuzzer
#[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
pub errored: bool,
@ -109,26 +103,24 @@ where
pub current_input: Option<I>, // Todo: Get rid of copy
#[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>>>,
}
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// Create a new [`PushStageHelper`]
#[must_use]
#[allow(clippy::type_complexity)]
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>>>,
) -> Self {
Self {
@ -145,17 +137,14 @@ where
/// Sets the shared state for this helper (and all other helpers owning the same [`RefCell`])
#[inline]
pub fn set_shared_state(
&mut self,
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>,
) {
pub fn set_shared_state(&mut self, shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>) {
(&mut *self.shared_state.borrow_mut()).replace(shared_state);
}
/// Takes the shared state from this helper, replacing it with `None`
#[inline]
#[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();
shared_state_ref.take()
}
@ -176,7 +165,7 @@ where
/// Resets this state after a full stage iter.
fn end_of_iter(
&mut self,
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>,
shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>,
errored: bool,
) {
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.
/// It's an iterator so we can chain it.
/// 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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// 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
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
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
#[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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
M: Mutator<I, S>,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
current_corpus_idx: Option<usize>,
@ -55,19 +53,17 @@ where
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
M: Mutator<I, S>,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// 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>
for StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
impl<CS, EM, I, M, OT, S, Z> PushStage<CS, EM, I, OT, S, Z>
for StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
where
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
M: Mutator<I, S>,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// Creates a new default mutational stage
@ -186,26 +180,24 @@ where
}
#[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
}
#[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
}
}
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
I: Input,
M: Mutator<I, S>,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
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
C: Corpus<I>,
CS: CorpusScheduler<I, S>,
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
I: Input,
M: Mutator<I, S>,
OT: ObserversTuple<I, S>,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
{
/// Creates a new default mutational stage
@ -232,7 +222,7 @@ where
#[allow(clippy::type_complexity)]
pub fn new(
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>>>,
stage_idx: i32,
) -> Self {

View File

@ -10,8 +10,6 @@ use std::{
};
use crate::{
bolts::rands::Rand,
corpus::Corpus,
fuzzer::Evaluator,
inputs::Input,
stages::Stage,
@ -38,28 +36,24 @@ impl SyncFromDiskMetadata {
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
#[derive(Debug)]
pub struct SyncFromDiskStage<C, CB, E, EM, I, R, S, Z>
pub struct SyncFromDiskStage<CB, E, EM, I, S, Z>
where
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
sync_dir: PathBuf,
load_callback: CB,
#[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
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
#[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
C: Corpus<I>,
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
/// Creates a new [`SyncFromDiskStage`]
@ -163,13 +155,11 @@ where
}
}
impl<C, E, EM, I, R, S, Z>
SyncFromDiskStage<C, fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, R, S, Z>
impl<E, EM, I, S, Z>
SyncFromDiskStage<fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, S, Z>
where
C: Corpus<I>,
I: Input,
R: Rand,
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
Z: Evaluator<E, EM, I, S>,
{
/// 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
#[derive(Clone, Debug)]
pub struct TracingStage<C, EM, I, OT, S, TE, Z>
pub struct TracingStage<EM, I, OT, S, TE, Z>
where
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
tracer_executor: TE,
#[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
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
#[inline]
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
I: Input,
C: Corpus<I>,
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
/// Creates a new default stage
pub fn new(tracer_executor: TE) -> Self {
@ -106,20 +103,19 @@ where
/// A stage that runs the shadow executor using also the shadow observers
#[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)]
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>
for ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z>
impl<E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
for ShadowTracingStage<E, EM, I, OT, S, SOT, Z>
where
I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
SOT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I> + Debug,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I> + Debug,
{
#[inline]
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
I: Input,
C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
OT: ObserversTuple<I, S>,
SOT: ObserversTuple<I, S>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
{
/// Creates a new default stage
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 {}
/// Trait for elements offering a corpus
pub trait HasCorpus<C, I>
where
C: Corpus<I>,
I: Input,
{
pub trait HasCorpus<I: Input> {
/// The associated type implementing [`Corpus`].
type Corpus: Corpus<I>;
/// The testcase corpus
fn corpus(&self) -> &C;
fn corpus(&self) -> &Self::Corpus;
/// The testcase corpus (mut)
fn corpus_mut(&mut self) -> &mut C;
fn corpus_mut(&mut self) -> &mut Self::Corpus;
}
/// Interact with the maximum size
@ -52,26 +50,23 @@ pub trait HasMaxSize {
}
/// Trait for elements offering a corpus of solutions
pub trait HasSolutions<C, I>
where
C: Corpus<I>,
I: Input,
{
pub trait HasSolutions<I: Input> {
/// The associated type implementing [`Corpus`] for solutions
type Solutions: Corpus<I>;
/// The solutions corpus
fn solutions(&self) -> &C;
fn solutions(&self) -> &Self::Solutions;
/// 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
pub trait HasRand<R>
where
R: Rand,
{
pub trait HasRand {
/// The associated type implementing [`Rand`]
type Rand: Rand;
/// The rand instance
fn rand(&self) -> &R;
fn rand(&self) -> &Self::Rand;
/// The rand instance (mut)
fn rand_mut(&mut self) -> &mut R;
fn rand_mut(&mut self) -> &mut Self::Rand;
}
/// Trait for offering a [`ClientPerfMonitor`]
@ -116,15 +111,14 @@ pub trait HasMetadata {
}
/// Trait for elements offering a feedback
pub trait HasFeedbackStates<FT>
where
FT: FeedbackStatesTuple,
{
pub trait HasFeedbackStates {
/// The associated feedback type implementing [`FeedbackStatesTuple`].
type FeedbackStates: FeedbackStatesTuple;
/// The feedback states
fn feedback_states(&self) -> &FT;
fn feedback_states(&self) -> &Self::FeedbackStates;
/// 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
@ -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
C: Corpus<I>,
I: Input,
@ -200,20 +194,22 @@ where
FT: FeedbackStatesTuple,
SC: Corpus<I>,
{
type Rand = R;
/// The rand instance
#[inline]
fn rand(&self) -> &R {
fn rand(&self) -> &Self::Rand {
&self.rand
}
/// The rand instance (mut)
#[inline]
fn rand_mut(&mut self) -> &mut R {
fn rand_mut(&mut self) -> &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
C: Corpus<I>,
I: Input,
@ -221,6 +217,8 @@ where
FT: FeedbackStatesTuple,
SC: Corpus<I>,
{
type Corpus = C;
/// Returns the corpus
#[inline]
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
C: Corpus<I>,
I: Input,
@ -242,6 +240,8 @@ where
FT: FeedbackStatesTuple,
SC: Corpus<I>,
{
type Solutions = SC;
/// Returns the solutions corpus
#[inline]
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
C: Corpus<I>,
I: Input,
@ -284,6 +284,8 @@ where
FT: FeedbackStatesTuple,
SC: Corpus<I>,
{
type FeedbackStates = FT;
/// The feedback states
#[inline]
fn feedback_states(&self) -> &FT {

View File

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