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:
parent
30eb1508de
commit
250ec8d1e0
@ -41,7 +41,7 @@ pub fn main() {
|
|||||||
let feedback_state = MapFeedbackState::with_observer(&observer);
|
let feedback_state = MapFeedbackState::with_observer(&observer);
|
||||||
|
|
||||||
// Feedback to rate the interestingness of an input
|
// Feedback to rate the interestingness of an input
|
||||||
let feedback = MaxMapFeedback::<_, BytesInput, _, _, _>::new(&feedback_state, &observer);
|
let feedback = MaxMapFeedback::<BytesInput, _, _, _>::new(&feedback_state, &observer);
|
||||||
|
|
||||||
// A feedback to choose if an input is a solution or not
|
// A feedback to choose if an input is a solution or not
|
||||||
let objective = CrashFeedback::new();
|
let objective = CrashFeedback::new();
|
||||||
|
@ -29,8 +29,8 @@ impl FavFactor<PacketData> for PacketLenFavFactor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PacketLenMinimizerCorpusScheduler<C, CS, R, S> =
|
pub type PacketLenMinimizerCorpusScheduler<CS, S> =
|
||||||
MinimizerCorpusScheduler<C, CS, PacketLenFavFactor, PacketData, MapIndexesMetadata, R, S>;
|
MinimizerCorpusScheduler<CS, PacketLenFavFactor, PacketData, MapIndexesMetadata, S>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
||||||
pub struct PacketLenFeedback {
|
pub struct PacketLenFeedback {
|
||||||
|
@ -10,23 +10,13 @@ use libafl::{
|
|||||||
|
|
||||||
use crate::input::PacketData;
|
use crate::input::PacketData;
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
use lain::traits::Mutatable;
|
use lain::traits::Mutatable;
|
||||||
|
|
||||||
pub struct LainMutator<R, S>
|
pub struct LainMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
inner: lain::mutator::Mutator<StdRand>,
|
inner: lain::mutator::Mutator<StdRand>,
|
||||||
phantom: PhantomData<*const (R, S)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Mutator<PacketData, S> for LainMutator<R, S>
|
impl<S: HasRand> Mutator<PacketData, S> for LainMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -40,35 +30,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for LainMutator<R, S>
|
impl Named for LainMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"LainMutator"
|
"LainMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> LainMutator<R, S>
|
impl LainMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: lain::mutator::Mutator::new(StdRand::with_seed(0)),
|
inner: lain::mutator::Mutator::new(StdRand::with_seed(0)),
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Default for LainMutator<R, S>
|
impl Default for LainMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
|
@ -81,29 +81,26 @@ where
|
|||||||
/// corpus that exercise all the requested features (e.g. all the coverage seen so far)
|
/// corpus that exercise all the requested features (e.g. all the coverage seen so far)
|
||||||
/// prioritizing [`Testcase`]`s` using [`FavFactor`]
|
/// prioritizing [`Testcase`]`s` using [`FavFactor`]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MinimizerCorpusScheduler<C, CS, F, I, M, R, S>
|
pub struct MinimizerCorpusScheduler<CS, F, I, M, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: FavFactor<I>,
|
F: FavFactor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
base: CS,
|
base: CS,
|
||||||
skip_non_favored_prob: u64,
|
skip_non_favored_prob: u64,
|
||||||
phantom: PhantomData<(C, F, I, M, R, S)>,
|
phantom: PhantomData<(F, I, M, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, M, R, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<C, CS, F, I, M, R, S>
|
impl<CS, F, I, M, S> CorpusScheduler<I, S> for MinimizerCorpusScheduler<CS, F, I, M, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: FavFactor<I>,
|
F: FavFactor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
||||||
S: HasCorpus<C, I> + HasMetadata + HasRand<R>,
|
S: HasCorpus<I> + HasMetadata + HasRand,
|
||||||
C: Corpus<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
fn on_add(&self, state: &mut S, idx: usize) -> Result<(), Error> {
|
||||||
@ -145,15 +142,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, M, R, S> MinimizerCorpusScheduler<C, CS, F, I, M, R, S>
|
impl<CS, F, I, M, S> MinimizerCorpusScheduler<CS, F, I, M, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: FavFactor<I>,
|
F: FavFactor<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
M: AsSlice<usize> + SerdeAny + HasRefCnt,
|
||||||
S: HasCorpus<C, I> + HasMetadata + HasRand<R>,
|
S: HasCorpus<I> + HasMetadata + HasRand,
|
||||||
C: Corpus<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
/// Update the `Corpus` score using the `MinimizerCorpusScheduler`
|
/// Update the `Corpus` score using the `MinimizerCorpusScheduler`
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
@ -284,10 +279,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`.
|
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`.
|
||||||
pub type LenTimeMinimizerCorpusScheduler<C, CS, I, M, R, S> =
|
pub type LenTimeMinimizerCorpusScheduler<CS, I, M, S> =
|
||||||
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, M, R, S>;
|
MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, M, S>;
|
||||||
|
|
||||||
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`
|
/// A [`MinimizerCorpusScheduler`] with [`LenTimeMulFavFactor`] to prioritize quick and small [`Testcase`]`s`
|
||||||
/// that exercise all the entries registered in the [`MapIndexesMetadata`].
|
/// that exercise all the entries registered in the [`MapIndexesMetadata`].
|
||||||
pub type IndexesLenTimeMinimizerCorpusScheduler<C, CS, I, R, S> =
|
pub type IndexesLenTimeMinimizerCorpusScheduler<CS, I, S> =
|
||||||
MinimizerCorpusScheduler<C, CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, R, S>;
|
MinimizerCorpusScheduler<CS, LenTimeMulFavFactor<I>, I, MapIndexesMetadata, S>;
|
||||||
|
@ -30,7 +30,7 @@ pub mod powersched;
|
|||||||
pub use powersched::PowerQueueCorpusScheduler;
|
pub use powersched::PowerQueueCorpusScheduler;
|
||||||
|
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use core::{cell::RefCell, marker::PhantomData};
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
bolts::rands::Rand,
|
||||||
@ -108,22 +108,12 @@ where
|
|||||||
|
|
||||||
/// Feed the fuzzer simpply with a random testcase on request
|
/// Feed the fuzzer simpply with a random testcase on request
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RandCorpusScheduler<C, I, R, S>
|
pub struct RandCorpusScheduler;
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, I, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, I, R, S> CorpusScheduler<I, S> for RandCorpusScheduler<C, I, R, S>
|
impl<I, S> CorpusScheduler<I, S> for RandCorpusScheduler
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
S: HasCorpus<I> + HasRand,
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
/// Gets the next entry at random
|
/// Gets the next entry at random
|
||||||
fn next(&self, state: &mut S) -> Result<usize, Error> {
|
fn next(&self, state: &mut S) -> Result<usize, Error> {
|
||||||
@ -138,29 +128,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S> RandCorpusScheduler<C, I, R, S>
|
impl RandCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Create a new [`RandCorpusScheduler`] that just schedules randomly.
|
/// Create a new [`RandCorpusScheduler`] that just schedules randomly.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, R, S> Default for RandCorpusScheduler<C, I, R, S>
|
impl Default for RandCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasRand<R>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
@ -168,4 +144,4 @@ where
|
|||||||
|
|
||||||
/// A [`StdCorpusScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s
|
/// A [`StdCorpusScheduler`] uses the default scheduler in `LibAFL` to schedule [`Testcase`]s
|
||||||
/// The current `Std` is a [`RandCorpusScheduler`], although this may change in the future, if another [`CorpusScheduler`] delivers better results.
|
/// The current `Std` is a [`RandCorpusScheduler`], although this may change in the future, if another [`CorpusScheduler`] delivers better results.
|
||||||
pub type StdCorpusScheduler<C, I, R, S> = RandCorpusScheduler<C, I, R, S>;
|
pub type StdCorpusScheduler = RandCorpusScheduler;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! The queue corpus scheduler for power schedules.
|
//! The queue corpus scheduler for power schedules.
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusScheduler, PowerScheduleTestcaseMetaData},
|
corpus::{Corpus, CorpusScheduler, PowerScheduleTestcaseMetaData},
|
||||||
@ -13,30 +12,17 @@ use crate::{
|
|||||||
|
|
||||||
/// A corpus scheduler using power schedules
|
/// A corpus scheduler using power schedules
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PowerQueueCorpusScheduler<C, I, S>
|
pub struct PowerQueueCorpusScheduler;
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, I, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, I, S> Default for PowerQueueCorpusScheduler<C, I, S>
|
impl Default for PowerQueueCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler<C, I, S>
|
impl<I, S> CorpusScheduler<I, S> for PowerQueueCorpusScheduler
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
@ -92,17 +78,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, S> PowerQueueCorpusScheduler<C, I, S>
|
impl PowerQueueCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// Create a new [`PowerQueueCorpusScheduler`]
|
/// Create a new [`PowerQueueCorpusScheduler`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! The queue corpus scheduler implements an AFL-like queue mechanism
|
//! The queue corpus scheduler implements an AFL-like queue mechanism
|
||||||
|
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, CorpusScheduler},
|
corpus::{Corpus, CorpusScheduler},
|
||||||
@ -12,19 +11,11 @@ use crate::{
|
|||||||
|
|
||||||
/// Walk the corpus in a queue-like fashion
|
/// Walk the corpus in a queue-like fashion
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct QueueCorpusScheduler<C, I, S>
|
pub struct QueueCorpusScheduler;
|
||||||
where
|
|
||||||
S: HasCorpus<C, I>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, I, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, I, S> CorpusScheduler<I, S> for QueueCorpusScheduler<C, I, S>
|
impl<I, S> CorpusScheduler<I, S> for QueueCorpusScheduler
|
||||||
where
|
where
|
||||||
S: HasCorpus<C, I>,
|
S: HasCorpus<I>,
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Gets the next entry in the queue
|
/// Gets the next entry in the queue
|
||||||
@ -48,27 +39,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, S> QueueCorpusScheduler<C, I, S>
|
impl QueueCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// Creates a new `QueueCorpusScheduler`
|
/// Creates a new `QueueCorpusScheduler`
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, S> Default for QueueCorpusScheduler<C, I, S>
|
impl Default for QueueCorpusScheduler {
|
||||||
where
|
|
||||||
S: HasCorpus<C, I>,
|
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::{
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
marker::PhantomData,
|
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
|
||||||
};
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
@ -232,11 +229,9 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(clippy::default_trait_access)]
|
#[allow(clippy::default_trait_access)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
pub struct SimpleRestartingEventManager<I, MT, SP>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
@ -244,17 +239,12 @@ where
|
|||||||
simple_event_mgr: SimpleEventManager<I, MT>,
|
simple_event_mgr: SimpleEventManager<I, MT>,
|
||||||
/// [`StateRestorer`] for restarts
|
/// [`StateRestorer`] for restarts
|
||||||
staterestorer: StateRestorer<SP>,
|
staterestorer: StateRestorer<SP>,
|
||||||
/// Phantom data
|
|
||||||
_phantom: PhantomData<&'a (C, I, S, SC)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, I, MT, S, SC, SP> EventFirer<I>
|
impl<I, MT, SP> EventFirer<I> for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
@ -264,10 +254,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, I, MT, S, SC, SP> EventRestarter<S>
|
impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -282,10 +270,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, E, I, MT, S, SC, SP, Z> EventProcessor<E, I, S, Z>
|
impl<E, I, S, SP, MT, Z> EventProcessor<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -297,10 +283,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, E, I, MT, S, SC, SP, Z> EventManager<E, I, S, Z>
|
impl<E, I, S, SP, MT, Z> EventManager<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -309,24 +293,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, I, MT, S, SC, SP> ProgressReporter<I>
|
impl<I, MT, SP> ProgressReporter<I> for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
S: Serialize,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'a, C, I, MT, S, SC, SP> HasEventManagerId
|
impl<I, MT, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, SP>
|
||||||
for SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor,
|
MT: Monitor,
|
||||||
{
|
{
|
||||||
@ -337,12 +315,9 @@ where
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(clippy::type_complexity, clippy::too_many_lines)]
|
#[allow(clippy::type_complexity, clippy::too_many_lines)]
|
||||||
impl<'a, C, I, MT, S, SC, SP> SimpleRestartingEventManager<'a, C, I, MT, S, SC, SP>
|
impl<'a, I, MT, SP> SimpleRestartingEventManager<I, MT, SP>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
S: DeserializeOwned + Serialize + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //TODO CE: CustomEvent,
|
MT: Monitor, //TODO CE: CustomEvent,
|
||||||
{
|
{
|
||||||
@ -351,7 +326,6 @@ where
|
|||||||
Self {
|
Self {
|
||||||
staterestorer,
|
staterestorer,
|
||||||
simple_event_mgr: SimpleEventManager::new(monitor),
|
simple_event_mgr: SimpleEventManager::new(monitor),
|
||||||
_phantom: PhantomData {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +333,10 @@ where
|
|||||||
/// This [`EventManager`] is simple and single threaded,
|
/// This [`EventManager`] is simple and single threaded,
|
||||||
/// but can still used shared maps to recover from crashes and timeouts.
|
/// but can still used shared maps to recover from crashes and timeouts.
|
||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
pub fn launch(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error> {
|
pub fn launch<S>(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
|
||||||
|
where
|
||||||
|
S: DeserializeOwned + Serialize + HasCorpus<I> + HasSolutions<I>,
|
||||||
|
{
|
||||||
// We start ourself as child process to actually fuzz
|
// We start ourself as child process to actually fuzz
|
||||||
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
||||||
// First, create a place to store state in, for restarts.
|
// First, create a place to store state in, for restarts.
|
||||||
|
@ -34,7 +34,6 @@ use crate::bolts::os::windows_exceptions::setup_exception_handler;
|
|||||||
use windows::Win32::System::Threading::SetThreadStackGuarantee;
|
use windows::Win32::System::Threading::SetThreadStackGuarantee;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::Corpus,
|
|
||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
feedbacks::Feedback,
|
feedbacks::Feedback,
|
||||||
@ -127,7 +126,7 @@ where
|
|||||||
/// * `harness_fn` - the harness, executiong the function
|
/// * `harness_fn` - the harness, executiong the function
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn new<EM, OC, OF, Z>(
|
pub fn new<EM, OF, Z>(
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
@ -136,12 +135,11 @@ where
|
|||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
let handlers = InProcessHandlers::new::<Self, EM, I, OC, OF, OT, S, Z>()?;
|
let handlers = InProcessHandlers::new::<Self, EM, I, OF, OT, S, Z>()?;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
unsafe {
|
unsafe {
|
||||||
/*
|
/*
|
||||||
@ -267,15 +265,14 @@ impl InProcessHandlers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create new [`InProcessHandlers`].
|
/// Create new [`InProcessHandlers`].
|
||||||
pub fn new<E, EM, I, OC, OF, OT, S, Z>() -> Result<Self, Error>
|
pub fn new<E, EM, I, OF, OT, S, Z>() -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
E: HasObservers<I, OT, S>,
|
E: HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -285,18 +282,10 @@ impl InProcessHandlers {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OC, OF, OT, S, Z>
|
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, OT, S, Z>
|
||||||
|
as *const _,
|
||||||
|
timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, OT, S, Z>
|
||||||
as *const _,
|
as *const _,
|
||||||
timeout_handler: unix_signal_handler::inproc_timeout_handler::<
|
|
||||||
E,
|
|
||||||
EM,
|
|
||||||
I,
|
|
||||||
OC,
|
|
||||||
OF,
|
|
||||||
OT,
|
|
||||||
S,
|
|
||||||
Z,
|
|
||||||
> as *const _,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[cfg(all(windows, feature = "std"))]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
@ -310,7 +299,6 @@ impl InProcessHandlers {
|
|||||||
E,
|
E,
|
||||||
EM,
|
EM,
|
||||||
I,
|
I,
|
||||||
OC,
|
|
||||||
OF,
|
OF,
|
||||||
OT,
|
OT,
|
||||||
S,
|
S,
|
||||||
@ -320,7 +308,6 @@ impl InProcessHandlers {
|
|||||||
E,
|
E,
|
||||||
EM,
|
EM,
|
||||||
I,
|
I,
|
||||||
OC,
|
|
||||||
OF,
|
OF,
|
||||||
OT,
|
OT,
|
||||||
S,
|
S,
|
||||||
@ -493,7 +480,7 @@ mod unix_signal_handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub unsafe fn inproc_timeout_handler<E, EM, I, OC, OF, OT, S, Z>(
|
pub unsafe fn inproc_timeout_handler<E, EM, I, OF, OT, S, Z>(
|
||||||
_signal: Signal,
|
_signal: Signal,
|
||||||
_info: siginfo_t,
|
_info: siginfo_t,
|
||||||
_context: &mut ucontext_t,
|
_context: &mut ucontext_t,
|
||||||
@ -502,9 +489,8 @@ mod unix_signal_handler {
|
|||||||
E: HasObservers<I, OT, S>,
|
E: HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
I: Input,
|
I: Input,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
@ -571,7 +557,7 @@ mod unix_signal_handler {
|
|||||||
/// Will be used for signal handling.
|
/// Will be used for signal handling.
|
||||||
/// It will store the current State to shmem, then exit.
|
/// It will store the current State to shmem, then exit.
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub unsafe fn inproc_crash_handler<E, EM, I, OC, OF, OT, S, Z>(
|
pub unsafe fn inproc_crash_handler<E, EM, I, OF, OT, S, Z>(
|
||||||
signal: Signal,
|
signal: Signal,
|
||||||
_info: siginfo_t,
|
_info: siginfo_t,
|
||||||
_context: &mut ucontext_t,
|
_context: &mut ucontext_t,
|
||||||
@ -580,9 +566,8 @@ mod unix_signal_handler {
|
|||||||
E: HasObservers<I, OT, S>,
|
E: HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
I: Input,
|
I: Input,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
@ -748,7 +733,7 @@ mod windows_exception_handler {
|
|||||||
EnterCriticalSection, LeaveCriticalSection, RTL_CRITICAL_SECTION,
|
EnterCriticalSection, LeaveCriticalSection, RTL_CRITICAL_SECTION,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub unsafe extern "system" fn inproc_timeout_handler<E, EM, I, OC, OF, OT, S, Z>(
|
pub unsafe extern "system" fn inproc_timeout_handler<E, EM, I, OF, OT, S, Z>(
|
||||||
_p0: *mut u8,
|
_p0: *mut u8,
|
||||||
global_state: *mut c_void,
|
global_state: *mut c_void,
|
||||||
_p1: *mut u8,
|
_p1: *mut u8,
|
||||||
@ -756,9 +741,8 @@ mod windows_exception_handler {
|
|||||||
E: HasObservers<I, OT, S>,
|
E: HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
I: Input,
|
I: Input,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
@ -847,16 +831,15 @@ mod windows_exception_handler {
|
|||||||
// println!("TIMER INVOKED!");
|
// println!("TIMER INVOKED!");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn inproc_crash_handler<E, EM, I, OC, OF, OT, S, Z>(
|
pub unsafe fn inproc_crash_handler<E, EM, I, OF, OT, S, Z>(
|
||||||
exception_pointers: *mut EXCEPTION_POINTERS,
|
exception_pointers: *mut EXCEPTION_POINTERS,
|
||||||
data: &mut InProcessExecutorHandlerData,
|
data: &mut InProcessExecutorHandlerData,
|
||||||
) where
|
) where
|
||||||
E: HasObservers<I, OT, S>,
|
E: HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
I: Input,
|
I: Input,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
@ -1085,7 +1068,7 @@ where
|
|||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
{
|
{
|
||||||
/// Creates a new [`InProcessForkExecutor`]
|
/// Creates a new [`InProcessForkExecutor`]
|
||||||
pub fn new<EM, OC, OF, Z>(
|
pub fn new<EM, OF, Z>(
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
observers: OT,
|
observers: OT,
|
||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
@ -1095,9 +1078,8 @@ where
|
|||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -9,11 +9,14 @@ use num_traits::PrimInt;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{tuples::Named, AsSlice, HasRefCnt},
|
bolts::{
|
||||||
|
tuples::{MatchName, Named},
|
||||||
|
AsSlice, HasRefCnt,
|
||||||
|
},
|
||||||
corpus::Testcase,
|
corpus::Testcase,
|
||||||
events::{Event, EventFirer},
|
events::{Event, EventFirer},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
feedbacks::{Feedback, FeedbackState, FeedbackStatesTuple},
|
feedbacks::{Feedback, FeedbackState},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
monitors::UserStats,
|
monitors::UserStats,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
@ -22,21 +25,20 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
|
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
|
||||||
pub type AflMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, OrReducer, S, T>;
|
pub type AflMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, OrReducer, S, T>;
|
||||||
|
|
||||||
/// A [`MapFeedback`] that strives to maximize the map contents.
|
/// A [`MapFeedback`] that strives to maximize the map contents.
|
||||||
pub type MaxMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, MaxReducer, S, T>;
|
pub type MaxMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, MaxReducer, S, T>;
|
||||||
/// A [`MapFeedback`] that strives to minimize the map contents.
|
/// A [`MapFeedback`] that strives to minimize the map contents.
|
||||||
pub type MinMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, DifferentIsNovel, O, MinReducer, S, T>;
|
pub type MinMapFeedback<I, O, S, T> = MapFeedback<I, DifferentIsNovel, O, MinReducer, S, T>;
|
||||||
|
|
||||||
/// A [`MapFeedback`] that strives to maximize the map contents,
|
/// A [`MapFeedback`] that strives to maximize the map contents,
|
||||||
/// but only, if a value is larger than `pow2` of the previous.
|
/// but only, if a value is larger than `pow2` of the previous.
|
||||||
pub type MaxMapPow2Feedback<FT, I, O, S, T> =
|
pub type MaxMapPow2Feedback<I, O, S, T> = MapFeedback<I, NextPow2IsNovel, O, MaxReducer, S, T>;
|
||||||
MapFeedback<FT, I, NextPow2IsNovel, O, MaxReducer, S, T>;
|
|
||||||
/// A [`MapFeedback`] that strives to maximize the map contents,
|
/// A [`MapFeedback`] that strives to maximize the map contents,
|
||||||
/// but only, if a value is larger than `pow2` of the previous.
|
/// but only, if a value is larger than `pow2` of the previous.
|
||||||
pub type MaxMapOneOrFilledFeedback<FT, I, O, S, T> =
|
pub type MaxMapOneOrFilledFeedback<I, O, S, T> =
|
||||||
MapFeedback<FT, I, OneOrFilledIsNovel, O, MaxReducer, S, T>;
|
MapFeedback<I, OneOrFilledIsNovel, O, MaxReducer, S, T>;
|
||||||
|
|
||||||
/// A `Reducer` function is used to aggregate values for the novelty search
|
/// A `Reducer` function is used to aggregate values for the novelty search
|
||||||
pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static + Debug
|
pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static + Debug
|
||||||
@ -329,14 +331,13 @@ where
|
|||||||
/// The most common AFL-like feedback type
|
/// The most common AFL-like feedback type
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||||
pub struct MapFeedback<FT, I, N, O, R, S, T>
|
pub struct MapFeedback<I, N, O, R, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
S: HasFeedbackStates<FT>,
|
S: HasFeedbackStates,
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
{
|
{
|
||||||
/// Indexes used in the last observation
|
/// Indexes used in the last observation
|
||||||
indexes: Option<Vec<usize>>,
|
indexes: Option<Vec<usize>>,
|
||||||
@ -347,18 +348,17 @@ where
|
|||||||
/// Name identifier of the observer
|
/// Name identifier of the observer
|
||||||
observer_name: String,
|
observer_name: String,
|
||||||
/// Phantom Data of Reducer
|
/// Phantom Data of Reducer
|
||||||
phantom: PhantomData<(FT, I, N, S, R, O, T)>,
|
phantom: PhantomData<(I, N, S, R, O, T)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FT, I, N, O, R, S, T> Feedback<I, S> for MapFeedback<FT, I, N, O, R, S, T>
|
impl<I, N, O, R, S, T> Feedback<I, S> for MapFeedback<I, N, O, R, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
I: Input,
|
I: Input,
|
||||||
S: HasFeedbackStates<FT> + HasClientPerfMonitor + Debug,
|
S: HasFeedbackStates + HasClientPerfMonitor + Debug,
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
{
|
{
|
||||||
fn is_interesting<EM, OT>(
|
fn is_interesting<EM, OT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -459,14 +459,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FT, I, N, O, R, S, T> Named for MapFeedback<FT, I, N, O, R, S, T>
|
impl<I, N, O, R, S, T> Named for MapFeedback<I, N, O, R, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
S: HasFeedbackStates<FT>,
|
S: HasFeedbackStates,
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
@ -474,7 +473,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FT, I, N, O, R, S, T> MapFeedback<FT, I, N, O, R, S, T>
|
impl<I, N, O, R, S, T> MapFeedback<I, N, O, R, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt
|
T: PrimInt
|
||||||
+ Default
|
+ Default
|
||||||
@ -487,8 +486,7 @@ where
|
|||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
S: HasFeedbackStates<FT>,
|
S: HasFeedbackStates,
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
{
|
{
|
||||||
/// Create new `MapFeedback`
|
/// Create new `MapFeedback`
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -233,7 +233,7 @@ pub enum ExecuteInputResult {
|
|||||||
|
|
||||||
/// Your default fuzzer instance, for everyday use.
|
/// Your default fuzzer instance, for everyday use.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
pub struct StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
@ -244,11 +244,10 @@ where
|
|||||||
scheduler: CS,
|
scheduler: CS,
|
||||||
feedback: F,
|
feedback: F,
|
||||||
objective: OF,
|
objective: OF,
|
||||||
phantom: PhantomData<(C, I, OT, S, SC)>,
|
phantom: PhantomData<(I, OT, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> HasCorpusScheduler<CS, I, S>
|
impl<CS, F, I, OF, OT, S> HasCorpusScheduler<CS, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
@ -265,7 +264,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> HasFeedback<F, I, S> for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
impl<CS, F, I, OF, OT, S> HasFeedback<F, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
@ -282,7 +281,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> HasObjective<I, OF, S> for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
impl<CS, F, I, OF, OT, S> HasObjective<I, OF, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
@ -299,17 +298,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> ExecutionProcessor<I, OT, S>
|
impl<CS, F, I, OF, OT, S> ExecutionProcessor<I, OT, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
||||||
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions,
|
S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
|
||||||
{
|
{
|
||||||
/// Evaluate if a set of observation channels has an interesting state
|
/// Evaluate if a set of observation channels has an interesting state
|
||||||
fn process_execution<EM>(
|
fn process_execution<EM>(
|
||||||
@ -416,17 +412,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> EvaluatorObservers<I, OT, S>
|
impl<CS, F, I, OF, OT, S> EvaluatorObservers<I, OT, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions,
|
S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
/// Process one input, adding to the respective corpuses if needed and firing the right events
|
/// Process one input, adding to the respective corpuses if needed and firing the right events
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -448,10 +441,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, E, EM, F, I, OF, OT, S, SC> Evaluator<E, EM, I, S>
|
impl<CS, E, EM, F, I, OF, OT, S> Evaluator<E, EM, I, S> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
E: Executor<EM, I, S, Self> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Self> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
OT: ObserversTuple<I, S> + serde::Serialize + serde::de::DeserializeOwned,
|
||||||
@ -459,8 +450,7 @@ where
|
|||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasCorpus<C, I> + HasSolutions<SC, I> + HasClientPerfMonitor + HasExecutions,
|
S: HasCorpus<I> + HasSolutions<I> + HasClientPerfMonitor + HasExecutions,
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
/// Process one input, adding to the respective corpuses if needed and firing the right events
|
/// Process one input, adding to the respective corpuses if needed and firing the right events
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -517,8 +507,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, E, EM, F, I, OF, OT, S, ST, SC> Fuzzer<E, EM, I, S, ST>
|
impl<CS, E, EM, F, I, OF, OT, S, ST> Fuzzer<E, EM, I, S, ST> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventManager<E, I, S, Self>,
|
EM: EventManager<E, I, S, Self>,
|
||||||
@ -568,7 +557,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
impl<CS, F, I, OF, OT, S> StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
@ -635,8 +624,7 @@ where
|
|||||||
OT: ObserversTuple<I, S>;
|
OT: ObserversTuple<I, S>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, F, I, OF, OT, S, SC> ExecutesInput<I, OT, S, Self>
|
impl<CS, F, I, OF, OT, S> ExecutesInput<I, OT, S, Self> for StdFuzzer<CS, F, I, OF, OT, S>
|
||||||
for StdFuzzer<C, CS, F, I, OF, OT, S, SC>
|
|
||||||
where
|
where
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
F: Feedback<I, S>,
|
F: Feedback<I, S>,
|
||||||
|
@ -33,19 +33,17 @@ pub struct Automaton {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Generates random inputs from a grammar automatron
|
/// Generates random inputs from a grammar automatron
|
||||||
pub struct GramatronGenerator<'a, R, S>
|
pub struct GramatronGenerator<'a, S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
automaton: &'a Automaton,
|
automaton: &'a Automaton,
|
||||||
phantom: PhantomData<(R, S)>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R, S> Generator<GramatronInput, S> for GramatronGenerator<'a, R, S>
|
impl<'a, S> Generator<GramatronInput, S> for GramatronGenerator<'a, S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn generate(&mut self, state: &mut S) -> Result<GramatronInput, Error> {
|
fn generate(&mut self, state: &mut S) -> Result<GramatronInput, Error> {
|
||||||
let mut input = GramatronInput::new(vec![]);
|
let mut input = GramatronInput::new(vec![]);
|
||||||
@ -58,10 +56,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R, S> GramatronGenerator<'a, R, S>
|
impl<'a, S> GramatronGenerator<'a, S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Returns a new [`GramatronGenerator`]
|
/// Returns a new [`GramatronGenerator`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -35,19 +35,17 @@ where
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Generates random bytes
|
/// Generates random bytes
|
||||||
pub struct RandBytesGenerator<R, S>
|
pub struct RandBytesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
phantom: PhantomData<(R, S)>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Generator<BytesInput, S> for RandBytesGenerator<R, S>
|
impl<S> Generator<BytesInput, S> for RandBytesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||||
let mut size = state.rand_mut().below(self.max_size as u64);
|
let mut size = state.rand_mut().below(self.max_size as u64);
|
||||||
@ -67,10 +65,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> RandBytesGenerator<R, S>
|
impl<S> RandBytesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -84,19 +81,17 @@ where
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Generates random printable characters
|
/// Generates random printable characters
|
||||||
pub struct RandPrintablesGenerator<R, S>
|
pub struct RandPrintablesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
phantom: PhantomData<(R, S)>,
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Generator<BytesInput, S> for RandPrintablesGenerator<R, S>
|
impl<S> Generator<BytesInput, S> for RandPrintablesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||||
let mut size = state.rand_mut().below(self.max_size as u64);
|
let mut size = state.rand_mut().below(self.max_size as u64);
|
||||||
@ -117,10 +112,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> RandPrintablesGenerator<R, S>
|
impl<S> RandPrintablesGenerator<S>
|
||||||
where
|
where
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters.
|
/// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
//! Mutations for [`EncodedInput`]s
|
//! Mutations for [`EncodedInput`]s
|
||||||
//!
|
//!
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{
|
use core::cmp::{max, min};
|
||||||
cmp::{max, min},
|
|
||||||
marker::PhantomData,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{
|
bolts::{
|
||||||
@ -23,19 +20,9 @@ use crate::{
|
|||||||
|
|
||||||
/// Set a code in the input as a random value
|
/// Set a code in the input as a random value
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedRandMutator<R, S>
|
pub struct EncodedRandMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedRandMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedRandMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -52,45 +39,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedRandMutator<R, S>
|
impl Named for EncodedRandMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedRandMutator"
|
"EncodedRandMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedRandMutator<R, S>
|
impl EncodedRandMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedRandMutator`].
|
/// Creates a new [`EncodedRandMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increment a random code in the input
|
/// Increment a random code in the input
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedIncMutator<R, S>
|
pub struct EncodedIncMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedIncMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedIncMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -107,45 +74,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedIncMutator<R, S>
|
impl Named for EncodedIncMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedIncMutator"
|
"EncodedIncMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedIncMutator<R, S>
|
impl EncodedIncMutator {
|
||||||
where
|
/// Creates a new [`EncodedIncMutator`].
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedRandMutator`].
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrement a random code in the input
|
/// Decrement a random code in the input
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedDecMutator<R, S>
|
pub struct EncodedDecMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedDecMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDecMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -162,45 +109,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedDecMutator<R, S>
|
impl Named for EncodedDecMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedDecMutator"
|
"EncodedDecMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedDecMutator<R, S>
|
impl EncodedDecMutator {
|
||||||
where
|
/// Creates a new [`EncodedDecMutator`].
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedRandMutator`].
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds or subtracts a random value up to `ARITH_MAX` to a random place in the codes [`Vec`].
|
/// Adds or subtracts a random value up to `ARITH_MAX` to a random place in the codes [`Vec`].
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedAddMutator<R, S>
|
pub struct EncodedAddMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedAddMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedAddMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -221,45 +148,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedAddMutator<R, S>
|
impl Named for EncodedAddMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedAddMutator"
|
"EncodedAddMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedAddMutator<R, S>
|
impl EncodedAddMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedAddMutator`].
|
/// Creates a new [`EncodedAddMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Codes delete mutation for encoded inputs
|
/// Codes delete mutation for encoded inputs
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedDeleteMutator<R, S>
|
pub struct EncodedDeleteMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedDeleteMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDeleteMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -279,45 +186,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedDeleteMutator<R, S>
|
impl Named for EncodedDeleteMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedDeleteMutator"
|
"EncodedDeleteMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedDeleteMutator<R, S>
|
impl EncodedDeleteMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedDeleteMutator`].
|
/// Creates a new [`EncodedDeleteMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert mutation for encoded inputs
|
/// Insert mutation for encoded inputs
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedInsertCopyMutator<R, S>
|
pub struct EncodedInsertCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
tmp_buf: Vec<u32>,
|
tmp_buf: Vec<u32>,
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedInsertCopyMutator<R, S>
|
impl<S> Mutator<EncodedInput, S> for EncodedInsertCopyMutator
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMaxSize,
|
S: HasRand + HasMaxSize,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -358,46 +249,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedInsertCopyMutator<R, S>
|
impl Named for EncodedInsertCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedInsertCopyMutator"
|
"EncodedInsertCopyMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedInsertCopyMutator<R, S>
|
impl EncodedInsertCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedInsertCopyMutator`].
|
/// Creates a new [`EncodedInsertCopyMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
tmp_buf: vec![],
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Codes copy mutation for encoded inputs
|
/// Codes copy mutation for encoded inputs
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedCopyMutator<R, S>
|
pub struct EncodedCopyMutator;
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, S> Mutator<EncodedInput, S> for EncodedCopyMutator<R, S>
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
@ -419,46 +289,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for EncodedCopyMutator<R, S>
|
impl Named for EncodedCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedCopyMutator"
|
"EncodedCopyMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> EncodedCopyMutator<R, S>
|
impl EncodedCopyMutator {
|
||||||
where
|
|
||||||
S: HasRand<R>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedCopyMutator`].
|
/// Creates a new [`EncodedCopyMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crossover insert mutation for encoded inputs
|
/// Crossover insert mutation for encoded inputs
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedCrossoverInsertMutator<C, R, S>
|
pub struct EncodedCrossoverInsertMutator;
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, R, S> Mutator<EncodedInput, S> for EncodedCrossoverInsertMutator<C, R, S>
|
impl<S> Mutator<EncodedInput, S> for EncodedCrossoverInsertMutator
|
||||||
where
|
where
|
||||||
C: Corpus<EncodedInput>,
|
S: HasRand + HasCorpus<EncodedInput> + HasMaxSize,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -512,48 +363,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, R, S> Named for EncodedCrossoverInsertMutator<C, R, S>
|
impl Named for EncodedCrossoverInsertMutator {
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedCrossoverInsertMutator"
|
"EncodedCrossoverInsertMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, R, S> EncodedCrossoverInsertMutator<C, R, S>
|
impl EncodedCrossoverInsertMutator {
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedCrossoverInsertMutator`].
|
/// Creates a new [`EncodedCrossoverInsertMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crossover replace mutation for encoded inputs
|
/// Crossover replace mutation for encoded inputs
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct EncodedCrossoverReplaceMutator<C, R, S>
|
pub struct EncodedCrossoverReplaceMutator;
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput>,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, R, S> Mutator<EncodedInput, S> for EncodedCrossoverReplaceMutator<C, R, S>
|
impl<S> Mutator<EncodedInput, S> for EncodedCrossoverReplaceMutator
|
||||||
where
|
where
|
||||||
C: Corpus<EncodedInput>,
|
S: HasRand + HasCorpus<EncodedInput>,
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput>,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -599,50 +429,33 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, R, S> Named for EncodedCrossoverReplaceMutator<C, R, S>
|
impl Named for EncodedCrossoverReplaceMutator {
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput>,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"EncodedCrossoverReplaceMutator"
|
"EncodedCrossoverReplaceMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, R, S> EncodedCrossoverReplaceMutator<C, R, S>
|
impl EncodedCrossoverReplaceMutator {
|
||||||
where
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput>,
|
|
||||||
{
|
|
||||||
/// Creates a new [`EncodedCrossoverReplaceMutator`].
|
/// Creates a new [`EncodedCrossoverReplaceMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the mutations that compose the encoded mutator
|
/// Get the mutations that compose the encoded mutator
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn encoded_mutations<C, R, S>() -> tuple_list_type!(
|
pub fn encoded_mutations() -> tuple_list_type!(
|
||||||
EncodedRandMutator<R, S>,
|
EncodedRandMutator,
|
||||||
EncodedIncMutator<R, S>,
|
EncodedIncMutator,
|
||||||
EncodedDecMutator<R, S>,
|
EncodedDecMutator,
|
||||||
EncodedAddMutator<R, S>,
|
EncodedAddMutator,
|
||||||
EncodedDeleteMutator<R, S>,
|
EncodedDeleteMutator,
|
||||||
EncodedInsertCopyMutator<R, S>,
|
EncodedInsertCopyMutator,
|
||||||
EncodedCopyMutator<R, S>,
|
EncodedCopyMutator,
|
||||||
EncodedCrossoverInsertMutator<C, R, S>,
|
EncodedCrossoverInsertMutator,
|
||||||
EncodedCrossoverReplaceMutator<C, R, S>,
|
EncodedCrossoverReplaceMutator,
|
||||||
)
|
) {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasCorpus<C, EncodedInput> + HasMaxSize,
|
|
||||||
C: Corpus<EncodedInput>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
EncodedRandMutator::new(),
|
EncodedRandMutator::new(),
|
||||||
EncodedIncMutator::new(),
|
EncodedIncMutator::new(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Gramatron is the rewritten gramatron fuzzer in rust.
|
//! Gramatron is the rewritten gramatron fuzzer in rust.
|
||||||
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
|
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{cmp::max, marker::PhantomData};
|
use core::cmp::max;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -17,18 +17,16 @@ use crate::{
|
|||||||
|
|
||||||
/// A random mutator for grammar fuzzing
|
/// A random mutator for grammar fuzzing
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GramatronRandomMutator<'a, R, S>
|
pub struct GramatronRandomMutator<'a, S>
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMetadata,
|
S: HasRand + HasMetadata,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
generator: &'a GramatronGenerator<'a, R, S>,
|
generator: &'a GramatronGenerator<'a, S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R, S> Mutator<GramatronInput, S> for GramatronRandomMutator<'a, R, S>
|
impl<'a, S> Mutator<GramatronInput, S> for GramatronRandomMutator<'a, S>
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMetadata,
|
S: HasRand + HasMetadata,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -48,24 +46,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R, S> Named for GramatronRandomMutator<'a, R, S>
|
impl<'a, S> Named for GramatronRandomMutator<'a, S>
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMetadata,
|
S: HasRand + HasMetadata,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"GramatronRandomMutator"
|
"GramatronRandomMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R, S> GramatronRandomMutator<'a, R, S>
|
impl<'a, S> GramatronRandomMutator<'a, S>
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMetadata,
|
S: HasRand + HasMetadata,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
/// Creates a new [`GramatronRandomMutator`].
|
/// Creates a new [`GramatronRandomMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(generator: &'a GramatronGenerator<'a, R, S>) -> Self {
|
pub fn new(generator: &'a GramatronGenerator<'a, S>) -> Self {
|
||||||
Self { generator }
|
Self { generator }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,20 +90,11 @@ impl GramatronIdxMapMetadata {
|
|||||||
|
|
||||||
/// A [`Mutator`] that mutates a [`GramatronInput`] by splicing inputs together.
|
/// A [`Mutator`] that mutates a [`GramatronInput`] by splicing inputs together.
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct GramatronSpliceMutator<C, R, S>
|
pub struct GramatronSpliceMutator;
|
||||||
where
|
|
||||||
C: Corpus<GramatronInput>,
|
|
||||||
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(C, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, R, S> Mutator<GramatronInput, S> for GramatronSpliceMutator<C, R, S>
|
impl<S> Mutator<GramatronInput, S> for GramatronSpliceMutator
|
||||||
where
|
where
|
||||||
C: Corpus<GramatronInput>,
|
S: HasRand + HasCorpus<GramatronInput> + HasMetadata,
|
||||||
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -155,49 +142,31 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, R, S> Named for GramatronSpliceMutator<C, R, S>
|
impl Named for GramatronSpliceMutator {
|
||||||
where
|
|
||||||
C: Corpus<GramatronInput>,
|
|
||||||
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"GramatronSpliceMutator"
|
"GramatronSpliceMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C, R, S> GramatronSpliceMutator<C, R, S>
|
impl GramatronSpliceMutator {
|
||||||
where
|
|
||||||
C: Corpus<GramatronInput>,
|
|
||||||
S: HasRand<R> + HasCorpus<C, GramatronInput> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`GramatronSpliceMutator`].
|
/// Creates a new [`GramatronSpliceMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutator that uses Gramatron for grammar fuzzing and mutation.
|
/// A mutator that uses Gramatron for grammar fuzzing and mutation.
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct GramatronRecursionMutator<R, S>
|
pub struct GramatronRecursionMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
counters: HashMap<usize, (usize, usize, usize)>,
|
counters: HashMap<usize, (usize, usize, usize)>,
|
||||||
states: Vec<usize>,
|
states: Vec<usize>,
|
||||||
temp: Vec<Terminal>,
|
temp: Vec<Terminal>,
|
||||||
phantom: PhantomData<(R, S)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Mutator<GramatronInput, S> for GramatronRecursionMutator<R, S>
|
impl<S> Mutator<GramatronInput, S> for GramatronRecursionMutator
|
||||||
where
|
where
|
||||||
S: HasRand<R> + HasMetadata,
|
S: HasRand + HasMetadata,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -266,29 +235,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> Named for GramatronRecursionMutator<R, S>
|
impl Named for GramatronRecursionMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"GramatronRecursionMutator"
|
"GramatronRecursionMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, S> GramatronRecursionMutator<R, S>
|
impl GramatronRecursionMutator {
|
||||||
where
|
|
||||||
S: HasRand<R> + HasMetadata,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`GramatronRecursionMutator`].
|
/// Creates a new [`GramatronRecursionMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
counters: HashMap::default(),
|
|
||||||
states: vec![],
|
|
||||||
temp: vec![],
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,29 +360,23 @@ pub enum MOptMode {
|
|||||||
|
|
||||||
/// This is the main struct of `MOpt`, an `AFL` mutator.
|
/// This is the main struct of `MOpt`, an `AFL` mutator.
|
||||||
/// See the original `MOpt` implementation in <https://github.com/puppet-meteor/MOpt-AFL>
|
/// See the original `MOpt` implementation in <https://github.com/puppet-meteor/MOpt-AFL>
|
||||||
pub struct StdMOptMutator<C, I, MT, R, S, SC>
|
pub struct StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
mode: MOptMode,
|
mode: MOptMode,
|
||||||
finds_before: usize,
|
finds_before: usize,
|
||||||
mutations: MT,
|
mutations: MT,
|
||||||
phantom: PhantomData<(C, I, R, S, SC)>,
|
phantom: PhantomData<(I, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SC> Debug for StdMOptMutator<C, I, MT, R, S, SC>
|
impl<I, MT, S> Debug for StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
@ -394,14 +388,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SC> Mutator<I, S> for StdMOptMutator<C, I, MT, R, S, SC>
|
impl<I, MT, S> Mutator<I, S> for StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutate(
|
fn mutate(
|
||||||
@ -532,14 +523,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SC> StdMOptMutator<C, I, MT, R, S, SC>
|
impl<I, MT, S> StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
/// Create a new [`StdMOptMutator`].
|
/// Create a new [`StdMOptMutator`].
|
||||||
pub fn new(state: &mut S, mutations: MT, swarm_num: usize) -> Result<Self, Error> {
|
pub fn new(state: &mut S, mutations: MT, swarm_num: usize) -> Result<Self, Error> {
|
||||||
@ -619,14 +607,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SC> ComposedByMutations<I, MT, S> for StdMOptMutator<C, I, MT, R, S, SC>
|
impl<I, MT, S> ComposedByMutations<I, MT, S> for StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
/// Get the mutations
|
/// Get the mutations
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -641,14 +626,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SC> ScheduledMutator<I, MT, S> for StdMOptMutator<C, I, MT, R, S, SC>
|
impl<I, MT, S> ScheduledMutator<I, MT, S> for StdMOptMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||||
S: HasRand<R> + HasMetadata + HasCorpus<C, I> + HasSolutions<SC, I>,
|
|
||||||
SC: Corpus<I>,
|
|
||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::tuples::Named,
|
bolts::tuples::Named,
|
||||||
corpus::Corpus,
|
|
||||||
feedbacks::NautilusChunksMetadata,
|
feedbacks::NautilusChunksMetadata,
|
||||||
generators::nautilus::NautilusContext,
|
generators::nautilus::NautilusContext,
|
||||||
inputs::nautilus::NautilusInput,
|
inputs::nautilus::NautilusInput,
|
||||||
@ -11,7 +10,7 @@ use crate::{
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
use core::{fmt::Debug, marker::PhantomData};
|
use core::fmt::Debug;
|
||||||
use grammartec::mutator::Mutator as BackingMutator;
|
use grammartec::mutator::Mutator as BackingMutator;
|
||||||
use grammartec::{
|
use grammartec::{
|
||||||
context::Context,
|
context::Context,
|
||||||
@ -30,7 +29,7 @@ impl Debug for NautilusRandomMutator<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S> Mutator<NautilusInput, S> for NautilusRandomMutator<'a> {
|
impl<S> Mutator<NautilusInput, S> for NautilusRandomMutator<'_> {
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
@ -60,7 +59,7 @@ impl<'a, S> Mutator<NautilusInput, S> for NautilusRandomMutator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Named for NautilusRandomMutator<'a> {
|
impl Named for NautilusRandomMutator<'_> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"NautilusRandomMutator"
|
"NautilusRandomMutator"
|
||||||
}
|
}
|
||||||
@ -91,7 +90,7 @@ impl Debug for NautilusRecursionMutator<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'a> {
|
impl<S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'_> {
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
@ -124,7 +123,7 @@ impl<'a, S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Named for NautilusRecursionMutator<'a> {
|
impl Named for NautilusRecursionMutator<'_> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"NautilusRecursionMutator"
|
"NautilusRecursionMutator"
|
||||||
}
|
}
|
||||||
@ -143,22 +142,20 @@ impl<'a> NautilusRecursionMutator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The splicing mutator for `Nautilus` that can splice inputs together
|
/// The splicing mutator for `Nautilus` that can splice inputs together
|
||||||
pub struct NautilusSpliceMutator<'a, C> {
|
pub struct NautilusSpliceMutator<'a> {
|
||||||
ctx: &'a Context,
|
ctx: &'a Context,
|
||||||
mutator: BackingMutator,
|
mutator: BackingMutator,
|
||||||
phantom: PhantomData<C>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusSpliceMutator<'_, ()> {
|
impl Debug for NautilusSpliceMutator<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "NautilusSpliceMutator {{}}")
|
write!(f, "NautilusSpliceMutator {{}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S, C> Mutator<NautilusInput, S> for NautilusSpliceMutator<'a, C>
|
impl<S> Mutator<NautilusInput, S> for NautilusSpliceMutator<'_>
|
||||||
where
|
where
|
||||||
C: Corpus<NautilusInput>,
|
S: HasCorpus<NautilusInput> + HasMetadata,
|
||||||
S: HasCorpus<C, NautilusInput> + HasMetadata,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -194,13 +191,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C> Named for NautilusSpliceMutator<'a, C> {
|
impl Named for NautilusSpliceMutator<'_> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"NautilusSpliceMutator"
|
"NautilusSpliceMutator"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C> NautilusSpliceMutator<'a, C> {
|
impl<'a> NautilusSpliceMutator<'a> {
|
||||||
/// Creates a new [`NautilusSpliceMutator`].
|
/// Creates a new [`NautilusSpliceMutator`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(context: &'a NautilusContext) -> Self {
|
pub fn new(context: &'a NautilusContext) -> Self {
|
||||||
@ -208,7 +205,6 @@ impl<'a, C> NautilusSpliceMutator<'a, C> {
|
|||||||
Self {
|
Self {
|
||||||
ctx: &context.ctx,
|
ctx: &context.ctx,
|
||||||
mutator,
|
mutator,
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ use crate::{
|
|||||||
AsSlice,
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
inputs::{HasBytesVec, Input},
|
inputs::Input,
|
||||||
mutators::{MutationResult, Mutator, MutatorsTuple},
|
mutators::{MutationResult, Mutator, MutatorsTuple},
|
||||||
state::{HasCorpus, HasMaxSize, HasMetadata, HasRand},
|
state::{HasCorpus, HasMetadata, HasRand},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,24 +95,22 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`Mutator`] that schedules one of the embedded mutations on each call.
|
/// A [`Mutator`] that schedules one of the embedded mutations on each call.
|
||||||
pub struct StdScheduledMutator<I, MT, R, S>
|
pub struct StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
mutations: MT,
|
mutations: MT,
|
||||||
max_iterations: u64,
|
max_iterations: u64,
|
||||||
phantom: PhantomData<(I, R, S)>,
|
phantom: PhantomData<(I, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, R, S> Debug for StdScheduledMutator<I, MT, R, S>
|
impl<I, MT, S> Debug for StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
@ -124,12 +122,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, R, S> Mutator<I, S> for StdScheduledMutator<I, MT, R, S>
|
impl<I, MT, S> Mutator<I, S> for StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutate(
|
fn mutate(
|
||||||
@ -142,12 +139,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, R, S> ComposedByMutations<I, MT, S> for StdScheduledMutator<I, MT, R, S>
|
impl<I, MT, S> ComposedByMutations<I, MT, S> for StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Get the mutations
|
/// Get the mutations
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -162,12 +158,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, R, S> ScheduledMutator<I, MT, S> for StdScheduledMutator<I, MT, R, S>
|
impl<I, MT, S> ScheduledMutator<I, MT, S> for StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
||||||
@ -181,12 +176,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, R, S> StdScheduledMutator<I, MT, R, S>
|
impl<I, MT, S> StdScheduledMutator<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S>,
|
MT: MutatorsTuple<I, S>,
|
||||||
R: Rand,
|
S: HasRand,
|
||||||
S: HasRand<R>,
|
|
||||||
{
|
{
|
||||||
/// Create a new [`StdScheduledMutator`] instance specifying mutations
|
/// Create a new [`StdScheduledMutator`] instance specifying mutations
|
||||||
pub fn new(mutations: MT) -> Self {
|
pub fn new(mutations: MT) -> Self {
|
||||||
@ -209,41 +203,35 @@ where
|
|||||||
|
|
||||||
/// Get the mutations that compose the Havoc mutator
|
/// Get the mutations that compose the Havoc mutator
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn havoc_mutations<C, I, R, S>() -> tuple_list_type!(
|
pub fn havoc_mutations() -> tuple_list_type!(
|
||||||
BitFlipMutator<I, R, S>,
|
BitFlipMutator,
|
||||||
ByteFlipMutator<I, R, S>,
|
ByteFlipMutator,
|
||||||
ByteIncMutator<I, R, S>,
|
ByteIncMutator,
|
||||||
ByteDecMutator<I, R, S>,
|
ByteDecMutator,
|
||||||
ByteNegMutator<I, R, S>,
|
ByteNegMutator,
|
||||||
ByteRandMutator<I, R, S>,
|
ByteRandMutator,
|
||||||
ByteAddMutator<I, R, S>,
|
ByteAddMutator,
|
||||||
WordAddMutator<I, R, S>,
|
WordAddMutator,
|
||||||
DwordAddMutator<I, R, S>,
|
DwordAddMutator,
|
||||||
QwordAddMutator<I, R, S>,
|
QwordAddMutator,
|
||||||
ByteInterestingMutator<I, R, S>,
|
ByteInterestingMutator,
|
||||||
WordInterestingMutator<I, R, S>,
|
WordInterestingMutator,
|
||||||
DwordInterestingMutator<I, R, S>,
|
DwordInterestingMutator,
|
||||||
BytesDeleteMutator<I, R, S>,
|
BytesDeleteMutator,
|
||||||
BytesDeleteMutator<I, R, S>,
|
BytesDeleteMutator,
|
||||||
BytesDeleteMutator<I, R, S>,
|
BytesDeleteMutator,
|
||||||
BytesDeleteMutator<I, R, S>,
|
BytesDeleteMutator,
|
||||||
BytesExpandMutator<I, R, S>,
|
BytesExpandMutator,
|
||||||
BytesInsertMutator<I, R, S>,
|
BytesInsertMutator,
|
||||||
BytesRandInsertMutator<I, R, S>,
|
BytesRandInsertMutator,
|
||||||
BytesSetMutator<I, R, S>,
|
BytesSetMutator,
|
||||||
BytesRandSetMutator<I, R, S>,
|
BytesRandSetMutator,
|
||||||
BytesCopyMutator<I, R, S>,
|
BytesCopyMutator,
|
||||||
BytesInsertCopyMutator<I, R, S>,
|
BytesInsertCopyMutator,
|
||||||
BytesSwapMutator<I, R, S>,
|
BytesSwapMutator,
|
||||||
CrossoverInsertMutator<C, I, R, S>,
|
CrossoverInsertMutator,
|
||||||
CrossoverReplaceMutator<C, I, R, S>,
|
CrossoverReplaceMutator,
|
||||||
)
|
) {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata + HasMaxSize,
|
|
||||||
C: Corpus<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
BitFlipMutator::new(),
|
BitFlipMutator::new(),
|
||||||
ByteFlipMutator::new(),
|
ByteFlipMutator::new(),
|
||||||
@ -277,39 +265,28 @@ where
|
|||||||
|
|
||||||
/// Get the mutations that uses the Tokens metadata
|
/// Get the mutations that uses the Tokens metadata
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn tokens_mutations<C, I, R, S>(
|
pub fn tokens_mutations() -> tuple_list_type!(TokenInsert, TokenReplace) {
|
||||||
) -> tuple_list_type!(TokenInsert<I, R, S>, TokenReplace<I, R, S>)
|
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasRand<R> + HasCorpus<C, I> + HasMetadata + HasMaxSize,
|
|
||||||
C: Corpus<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
tuple_list!(TokenInsert::new(), TokenReplace::new(),)
|
tuple_list!(TokenInsert::new(), TokenReplace::new(),)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A logging [`Mutator`] that wraps around a [`StdScheduledMutator`].
|
/// A logging [`Mutator`] that wraps around a [`StdScheduledMutator`].
|
||||||
pub struct LoggerScheduledMutator<C, I, MT, R, S, SM>
|
pub struct LoggerScheduledMutator<I, MT, S, SM>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
scheduled: SM,
|
scheduled: SM,
|
||||||
mutation_log: Vec<usize>,
|
mutation_log: Vec<usize>,
|
||||||
phantom: PhantomData<(C, I, MT, R, S)>,
|
phantom: PhantomData<(I, MT, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SM> Debug for LoggerScheduledMutator<C, I, MT, R, S, SM>
|
impl<I, MT, S, SM> Debug for LoggerScheduledMutator<I, MT, S, SM>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
@ -322,13 +299,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SM> Mutator<I, S> for LoggerScheduledMutator<C, I, MT, R, S, SM>
|
impl<I, MT, S, SM> Mutator<I, S> for LoggerScheduledMutator<I, MT, S, SM>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
@ -362,14 +337,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SM> ComposedByMutations<I, MT, S>
|
impl<I, MT, S, SM> ComposedByMutations<I, MT, S> for LoggerScheduledMutator<I, MT, S, SM>
|
||||||
for LoggerScheduledMutator<C, I, MT, R, S, SM>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -383,13 +355,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SM> ScheduledMutator<I, MT, S> for LoggerScheduledMutator<C, I, MT, R, S, SM>
|
impl<I, MT, S, SM> ScheduledMutator<I, MT, S> for LoggerScheduledMutator<I, MT, S, SM>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
@ -428,13 +398,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, I, MT, R, S, SM> LoggerScheduledMutator<C, I, MT, R, S, SM>
|
impl<I, MT, S, SM> LoggerScheduledMutator<I, MT, S, SM>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: MutatorsTuple<I, S> + NamedTuple,
|
MT: MutatorsTuple<I, S> + NamedTuple,
|
||||||
R: Rand,
|
S: HasRand + HasCorpus<I>,
|
||||||
S: HasRand<R> + HasCorpus<C, I>,
|
|
||||||
SM: ScheduledMutator<I, MT, S>,
|
SM: ScheduledMutator<I, MT, S>,
|
||||||
{
|
{
|
||||||
/// Create a new [`StdScheduledMutator`] instance without mutations and corpus
|
/// Create a new [`StdScheduledMutator`] instance without mutations and corpus
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Tokens are what afl calls extras or dictionaries.
|
//! Tokens are what afl calls extras or dictionaries.
|
||||||
//! They may be inserted as part of mutations during fuzzing.
|
//! They may be inserted as part of mutations during fuzzing.
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{marker::PhantomData, mem::size_of};
|
use core::mem::size_of;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -127,20 +127,12 @@ impl Tokens {
|
|||||||
|
|
||||||
/// Inserts a random token at a random position in the `Input`.
|
/// Inserts a random token at a random position in the `Input`.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TokenInsert<I, R, S>
|
pub struct TokenInsert;
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(I, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, R, S> Mutator<I, S> for TokenInsert<I, R, S>
|
impl<I, S> Mutator<I, S> for TokenInsert
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
S: HasMetadata + HasRand + HasMaxSize,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -184,49 +176,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> Named for TokenInsert<I, R, S>
|
impl Named for TokenInsert {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"TokenInsert"
|
"TokenInsert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> TokenInsert<I, R, S>
|
impl TokenInsert {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Create a `TokenInsert` `Mutation`.
|
/// Create a `TokenInsert` `Mutation`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `TokenReplace` [`Mutator`] replaces a random part of the input with one of a range of tokens.
|
/// A `TokenReplace` [`Mutator`] replaces a random part of the input with one of a range of tokens.
|
||||||
/// From AFL terms, this is called as `Dictionary` mutation (which doesn't really make sense ;) ).
|
/// From AFL terms, this is called as `Dictionary` mutation (which doesn't really make sense ;) ).
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TokenReplace<I, R, S>
|
pub struct TokenReplace;
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(I, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, R, S> Mutator<I, S> for TokenReplace<I, R, S>
|
impl<I, S> Mutator<I, S> for TokenReplace
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
S: HasMetadata + HasRand + HasMaxSize,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
fn mutate(
|
fn mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -266,49 +238,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> Named for TokenReplace<I, R, S>
|
impl Named for TokenReplace {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"TokenReplace"
|
"TokenReplace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> TokenReplace<I, R, S>
|
impl TokenReplace {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new `TokenReplace` struct.
|
/// Creates a new `TokenReplace` struct.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `I2SRandReplace` [`Mutator`] replaces a random matching input-2-state comparison operand with the other.
|
/// A `I2SRandReplace` [`Mutator`] replaces a random matching input-2-state comparison operand with the other.
|
||||||
/// it needs a valid [`CmpValuesMetadata`] in the state.
|
/// it needs a valid [`CmpValuesMetadata`] in the state.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct I2SRandReplace<I, R, S>
|
pub struct I2SRandReplace;
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
phantom: PhantomData<(I, R, S)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I, R, S> Mutator<I, S> for I2SRandReplace<I, R, S>
|
impl<I, S> Mutator<I, S> for I2SRandReplace
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
S: HasMetadata + HasRand + HasMaxSize,
|
||||||
R: Rand,
|
|
||||||
{
|
{
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn mutate(
|
fn mutate(
|
||||||
@ -471,29 +423,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> Named for I2SRandReplace<I, R, S>
|
impl Named for I2SRandReplace {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"I2SRandReplace"
|
"I2SRandReplace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, R, S> I2SRandReplace<I, R, S>
|
impl I2SRandReplace {
|
||||||
where
|
|
||||||
I: Input + HasBytesVec,
|
|
||||||
S: HasMetadata + HasRand<R> + HasMaxSize,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
/// Creates a new `I2SRandReplace` struct.
|
/// Creates a new `I2SRandReplace` struct.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::current_time,
|
bolts::current_time,
|
||||||
|
bolts::tuples::MatchName,
|
||||||
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
corpus::{Corpus, PowerScheduleTestcaseMetaData},
|
||||||
events::{EventFirer, LogSeverity},
|
events::{EventFirer, LogSeverity},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
feedbacks::{FeedbackStatesTuple, MapFeedbackState},
|
feedbacks::MapFeedbackState,
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
@ -23,40 +24,31 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
/// The calibration stage will measure the average exec time and the target's stability for this input.
|
/// The calibration stage will measure the average exec time and the target's stability for this input.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z>
|
pub struct CalibrationStage<I, O, OT, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
|
||||||
EM: EventFirer<I>,
|
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
|
||||||
{
|
{
|
||||||
map_observer_name: String,
|
map_observer_name: String,
|
||||||
stage_max: usize,
|
stage_max: usize,
|
||||||
#[allow(clippy::type_complexity)]
|
phantom: PhantomData<(I, O, OT, S, T)>,
|
||||||
phantom: PhantomData<(C, E, EM, FT, I, O, OT, S, T, Z)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAL_STAGE_START: usize = 4;
|
const CAL_STAGE_START: usize = 4;
|
||||||
const CAL_STAGE_MAX: usize = 16;
|
const CAL_STAGE_MAX: usize = 16;
|
||||||
|
|
||||||
impl<C, E, EM, FT, I, O, OT, S, T, Z> Stage<E, EM, S, Z>
|
impl<E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z> for CalibrationStage<I, O, OT, S, T>
|
||||||
for CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z>
|
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I>,
|
EM: EventFirer<I>,
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<C, I> + HasMetadata + HasFeedbackStates<FT> + HasClientPerfMonitor,
|
S: HasCorpus<I> + HasMetadata + HasFeedbackStates + HasClientPerfMonitor,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -314,18 +306,13 @@ impl PowerScheduleMetadata {
|
|||||||
|
|
||||||
crate::impl_serdeany!(PowerScheduleMetadata);
|
crate::impl_serdeany!(PowerScheduleMetadata);
|
||||||
|
|
||||||
impl<C, E, EM, FT, I, O, OT, S, T, Z> CalibrationStage<C, E, EM, FT, I, O, OT, S, T, Z>
|
impl<I, O, OT, S, T> CalibrationStage<I, O, OT, S, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
|
||||||
EM: EventFirer<I>,
|
|
||||||
FT: FeedbackStatesTuple,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<C, I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
|
||||||
{
|
{
|
||||||
/// Create a new [`CalibrationStage`].
|
/// Create a new [`CalibrationStage`].
|
||||||
pub fn new(state: &mut S, map_observer_name: &O) -> Self {
|
pub fn new(state: &mut S, map_observer_name: &O) -> Self {
|
||||||
|
@ -17,25 +17,23 @@ use super::{Stage, TracingStage};
|
|||||||
|
|
||||||
/// Wraps a [`TracingStage`] to add concolic observing.
|
/// Wraps a [`TracingStage`] to add concolic observing.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ConcolicTracingStage<C, EM, I, OT, S, TE, Z>
|
pub struct ConcolicTracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
inner: TracingStage<C, EM, I, OT, S, TE, Z>,
|
inner: TracingStage<EM, I, OT, S, TE, Z>,
|
||||||
observer_name: String,
|
observer_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for ConcolicTracingStage<C, EM, I, OT, S, TE, Z>
|
impl<E, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for ConcolicTracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -67,16 +65,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, EM, I, OT, S, TE, Z> ConcolicTracingStage<C, EM, I, OT, S, TE, Z>
|
impl<EM, I, OT, S, TE, Z> ConcolicTracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
/// Creates a new default tracing stage using the given [`Executor`], observing traces from a [`ConcolicObserver`] with the given name.
|
/// Creates a new default tracing stage using the given [`Executor`], observing traces from a [`ConcolicObserver`] with the given name.
|
||||||
pub fn new(inner: TracingStage<C, EM, I, OT, S, TE, Z>, observer_name: String) -> Self {
|
pub fn new(inner: TracingStage<EM, I, OT, S, TE, Z>, observer_name: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner,
|
inner,
|
||||||
observer_name,
|
observer_name,
|
||||||
@ -345,21 +342,19 @@ fn generate_mutations(iter: impl Iterator<Item = (SymExprRef, SymExpr)>) -> Vec<
|
|||||||
|
|
||||||
/// A mutational stage that uses Z3 to solve concolic constraints attached to the [`crate::corpus::Testcase`] by the [`ConcolicTracingStage`].
|
/// A mutational stage that uses Z3 to solve concolic constraints attached to the [`crate::corpus::Testcase`] by the [`ConcolicTracingStage`].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SimpleConcolicMutationalStage<C, EM, I, S, Z>
|
pub struct SimpleConcolicMutationalStage<EM, I, S, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
|
||||||
{
|
{
|
||||||
_phantom: PhantomData<(C, EM, I, S, Z)>,
|
_phantom: PhantomData<(EM, I, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "concolic_mutation")]
|
#[cfg(feature = "concolic_mutation")]
|
||||||
impl<E, C, EM, I, S, Z> Stage<E, EM, S, Z> for SimpleConcolicMutationalStage<C, EM, I, S, Z>
|
impl<E, EM, I, S, Z> Stage<E, EM, S, Z> for SimpleConcolicMutationalStage<EM, I, S, Z>
|
||||||
where
|
where
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
C: Corpus<I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -399,11 +394,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, EM, I, S, Z> Default for SimpleConcolicMutationalStage<C, EM, I, S, Z>
|
impl<EM, I, S, Z> Default for SimpleConcolicMutationalStage<EM, I, S, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
|
||||||
{
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -32,8 +32,7 @@ pub mod sync;
|
|||||||
pub use sync::*;
|
pub use sync::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
corpus::CorpusScheduler,
|
||||||
corpus::{Corpus, CorpusScheduler},
|
|
||||||
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
@ -164,32 +163,28 @@ where
|
|||||||
/// Allows us to use a [`push::PushStage`] as a normal [`Stage`]
|
/// Allows us to use a [`push::PushStage`] as a normal [`Stage`]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z>
|
pub struct PushStageAdapter<CS, EM, I, OT, PS, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
|
PS: PushStage<CS, EM, I, OT, S, Z>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
push_stage: PS,
|
push_stage: PS,
|
||||||
phantom: PhantomData<(C, CS, EM, I, OT, R, S, Z)>,
|
phantom: PhantomData<(CS, EM, I, OT, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, OT, PS, R, S, Z> PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z>
|
impl<CS, EM, I, OT, PS, S, Z> PushStageAdapter<CS, EM, I, OT, PS, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
|
PS: PushStage<CS, EM, I, OT, S, Z>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Create a new [`PushStageAdapter`], warpping the given [`PushStage`]
|
/// Create a new [`PushStageAdapter`], warpping the given [`PushStage`]
|
||||||
@ -203,18 +198,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, E, EM, I, OT, PS, R, S, Z> Stage<E, EM, S, Z>
|
impl<CS, E, EM, I, OT, PS, S, Z> Stage<E, EM, S, Z> for PushStageAdapter<CS, EM, I, OT, PS, S, Z>
|
||||||
for PushStageAdapter<C, CS, EM, I, OT, PS, R, S, Z>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
PS: PushStage<C, CS, EM, I, OT, R, S, Z>,
|
PS: PushStage<CS, EM, I, OT, S, Z>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutesInput<I, OT, S, Z>
|
Z: ExecutesInput<I, OT, S, Z>
|
||||||
+ ExecutionProcessor<I, OT, S>
|
+ ExecutionProcessor<I, OT, S>
|
||||||
+ EvaluatorObservers<I, OT, S>
|
+ EvaluatorObservers<I, OT, S>
|
||||||
|
@ -24,12 +24,11 @@ use crate::monitors::PerfFeature;
|
|||||||
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
/// A Mutational stage is the stage in a fuzzing run that mutates inputs.
|
||||||
/// Mutational stages will usually have a range of mutations that are
|
/// Mutational stages will usually have a range of mutations that are
|
||||||
/// being applied to the input one by one, between executions.
|
/// being applied to the input one by one, between executions.
|
||||||
pub trait MutationalStage<C, E, EM, I, M, S, Z>: Stage<E, EM, S, Z>
|
pub trait MutationalStage<E, EM, I, M, S, Z>: Stage<E, EM, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasCorpus<I>,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// The mutator registered for this stage
|
/// The mutator registered for this stage
|
||||||
@ -84,28 +83,23 @@ pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
|
|||||||
|
|
||||||
/// The default mutational stage
|
/// The default mutational stage
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct StdMutationalStage<C, E, EM, I, M, R, S, Z>
|
pub struct StdMutationalStage<E, EM, I, M, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
mutator: M,
|
mutator: M,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, E, EM, I, R, S, Z)>,
|
phantom: PhantomData<(E, EM, I, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, R, S, Z> MutationalStage<C, E, EM, I, M, S, Z>
|
impl<E, EM, I, M, S, Z> MutationalStage<E, EM, I, M, S, Z> for StdMutationalStage<E, EM, I, M, S, Z>
|
||||||
for StdMutationalStage<C, E, EM, I, M, R, S, Z>
|
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// The mutator, added to this stage
|
/// The mutator, added to this stage
|
||||||
@ -126,13 +120,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, R, S, Z> Stage<E, EM, S, Z> for StdMutationalStage<C, E, EM, I, M, R, S, Z>
|
impl<E, EM, I, M, S, Z> Stage<E, EM, S, Z> for StdMutationalStage<E, EM, I, M, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -154,13 +146,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, R, S, Z> StdMutationalStage<C, E, EM, I, M, R, S, Z>
|
impl<E, EM, I, M, S, Z> StdMutationalStage<E, EM, I, M, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
|
@ -34,16 +34,15 @@ const HAVOC_MAX_MULT: f64 = 64.0;
|
|||||||
|
|
||||||
/// The mutational stage using power schedules
|
/// The mutational stage using power schedules
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
|
pub struct PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
map_observer_name: String,
|
map_observer_name: String,
|
||||||
@ -51,20 +50,19 @@ where
|
|||||||
/// The employed power schedule strategy
|
/// The employed power schedule strategy
|
||||||
strat: PowerSchedule,
|
strat: PowerSchedule,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, E, EM, I, O, OT, S, T, Z)>,
|
phantom: PhantomData<(E, EM, I, O, OT, S, T, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, O, OT, S, T, Z> MutationalStage<C, E, EM, I, M, S, Z>
|
impl<E, EM, I, M, O, OT, S, T, Z> MutationalStage<E, EM, I, M, S, Z>
|
||||||
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
|
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// The mutator, added to this stage
|
/// The mutator, added to this stage
|
||||||
@ -155,17 +153,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
|
impl<E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
|
||||||
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
|
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -183,16 +180,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
|
impl<E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new [`PowerMutationalStage`]
|
/// Creates a new [`PowerMutationalStage`]
|
||||||
|
@ -16,8 +16,8 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{current_time, rands::Rand},
|
bolts::current_time,
|
||||||
corpus::{Corpus, CorpusScheduler},
|
corpus::CorpusScheduler,
|
||||||
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
events::{EventFirer, EventRestarter, HasEventManagerId, ProgressReporter},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
@ -32,15 +32,13 @@ const STATS_TIMEOUT_DEFAULT: Duration = Duration::from_secs(15);
|
|||||||
// The shared state for all [`PushStage`]s
|
// The shared state for all [`PushStage`]s
|
||||||
/// Should be stored inside a `[Rc<RefCell<_>>`]
|
/// Should be stored inside a `[Rc<RefCell<_>>`]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PushStageSharedState<C, CS, EM, I, OT, R, S, Z>
|
pub struct PushStageSharedState<CS, EM, I, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// The [`crate::state::State`]
|
/// The [`crate::state::State`]
|
||||||
@ -51,18 +49,16 @@ where
|
|||||||
pub event_mgr: EM,
|
pub event_mgr: EM,
|
||||||
/// The [`crate::observers::ObserversTuple`]
|
/// The [`crate::observers::ObserversTuple`]
|
||||||
pub observers: OT,
|
pub observers: OT,
|
||||||
phantom: PhantomData<(C, CS, I, OT, R, S, Z)>,
|
phantom: PhantomData<(CS, I, OT, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, OT, R, S, Z> PushStageSharedState<C, CS, EM, I, OT, R, S, Z>
|
impl<CS, EM, I, OT, S, Z> PushStageSharedState<CS, EM, I, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s
|
/// Create a new `PushStageSharedState` that can be used by all [`PushStage`]s
|
||||||
@ -80,15 +76,13 @@ where
|
|||||||
|
|
||||||
/// Helper class for the [`PushStage`] trait, taking care of borrowing the shared state
|
/// Helper class for the [`PushStage`] trait, taking care of borrowing the shared state
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PushStageHelper<C, CS, EM, I, OT, R, S, Z>
|
pub struct PushStageHelper<CS, EM, I, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// If this stage has already been initalized.
|
/// If this stage has already been initalized.
|
||||||
@ -98,7 +92,7 @@ where
|
|||||||
pub last_monitor_time: Duration,
|
pub last_monitor_time: Duration,
|
||||||
/// The shared state, keeping track of the corpus and the fuzzer
|
/// The shared state, keeping track of the corpus and the fuzzer
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>,
|
pub shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
|
||||||
/// If the last iteraation failed
|
/// If the last iteraation failed
|
||||||
pub errored: bool,
|
pub errored: bool,
|
||||||
|
|
||||||
@ -109,26 +103,24 @@ where
|
|||||||
pub current_input: Option<I>, // Todo: Get rid of copy
|
pub current_input: Option<I>, // Todo: Get rid of copy
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, CS, (), EM, I, R, OT, S, Z)>,
|
phantom: PhantomData<(CS, (), EM, I, OT, S, Z)>,
|
||||||
exit_kind: Rc<Cell<Option<ExitKind>>>,
|
exit_kind: Rc<Cell<Option<ExitKind>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, OT, R, S, Z> PushStageHelper<C, CS, EM, I, OT, R, S, Z>
|
impl<CS, EM, I, OT, S, Z> PushStageHelper<CS, EM, I, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Create a new [`PushStageHelper`]
|
/// Create a new [`PushStageHelper`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>,
|
shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
|
||||||
exit_kind_ref: Rc<Cell<Option<ExitKind>>>,
|
exit_kind_ref: Rc<Cell<Option<ExitKind>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -145,17 +137,14 @@ where
|
|||||||
|
|
||||||
/// Sets the shared state for this helper (and all other helpers owning the same [`RefCell`])
|
/// Sets the shared state for this helper (and all other helpers owning the same [`RefCell`])
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_shared_state(
|
pub fn set_shared_state(&mut self, shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>) {
|
||||||
&mut self,
|
|
||||||
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>,
|
|
||||||
) {
|
|
||||||
(&mut *self.shared_state.borrow_mut()).replace(shared_state);
|
(&mut *self.shared_state.borrow_mut()).replace(shared_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the shared state from this helper, replacing it with `None`
|
/// Takes the shared state from this helper, replacing it with `None`
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn take_shared_state(&mut self) -> Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>> {
|
pub fn take_shared_state(&mut self) -> Option<PushStageSharedState<CS, EM, I, OT, S, Z>> {
|
||||||
let shared_state_ref = &mut (*self.shared_state).borrow_mut();
|
let shared_state_ref = &mut (*self.shared_state).borrow_mut();
|
||||||
shared_state_ref.take()
|
shared_state_ref.take()
|
||||||
}
|
}
|
||||||
@ -176,7 +165,7 @@ where
|
|||||||
/// Resets this state after a full stage iter.
|
/// Resets this state after a full stage iter.
|
||||||
fn end_of_iter(
|
fn end_of_iter(
|
||||||
&mut self,
|
&mut self,
|
||||||
shared_state: PushStageSharedState<C, CS, EM, I, OT, R, S, Z>,
|
shared_state: PushStageSharedState<CS, EM, I, OT, S, Z>,
|
||||||
errored: bool,
|
errored: bool,
|
||||||
) {
|
) {
|
||||||
self.set_shared_state(shared_state);
|
self.set_shared_state(shared_state);
|
||||||
@ -191,21 +180,19 @@ where
|
|||||||
/// A push stage is a generator that returns a single testcase for each call.
|
/// A push stage is a generator that returns a single testcase for each call.
|
||||||
/// It's an iterator so we can chain it.
|
/// It's an iterator so we can chain it.
|
||||||
/// After it has finished once, we will call it agan for the next fuzzer round.
|
/// After it has finished once, we will call it agan for the next fuzzer round.
|
||||||
pub trait PushStage<C, CS, EM, I, OT, R, S, Z>: Iterator
|
pub trait PushStage<CS, EM, I, OT, S, Z>: Iterator
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Gets the [`PushStageHelper`]
|
/// Gets the [`PushStageHelper`]
|
||||||
fn push_stage_helper(&self) -> &PushStageHelper<C, CS, EM, I, OT, R, S, Z>;
|
fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, I, OT, S, Z>;
|
||||||
/// Gets the [`PushStageHelper`], mut
|
/// Gets the [`PushStageHelper`], mut
|
||||||
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<C, CS, EM, I, OT, R, S, Z>;
|
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<CS, EM, I, OT, S, Z>;
|
||||||
|
|
||||||
/// Set the current corpus index this stagve works on
|
/// Set the current corpus index this stagve works on
|
||||||
fn set_current_corpus_idx(&mut self, corpus_idx: usize) {
|
fn set_current_corpus_idx(&mut self, corpus_idx: usize) {
|
||||||
|
@ -35,16 +35,14 @@ pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
|
|||||||
///
|
///
|
||||||
/// The default mutational push stage
|
/// The default mutational push stage
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
|
pub struct StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
current_corpus_idx: Option<usize>,
|
current_corpus_idx: Option<usize>,
|
||||||
@ -55,19 +53,17 @@ where
|
|||||||
|
|
||||||
mutator: M,
|
mutator: M,
|
||||||
|
|
||||||
psh: PushStageHelper<C, CS, EM, I, OT, R, S, Z>,
|
psh: PushStageHelper<CS, EM, I, OT, S, Z>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, M, OT, R, S, Z> StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
|
impl<CS, EM, I, M, OT, S, Z> StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Gets the number of iterations as a random number
|
/// Gets the number of iterations as a random number
|
||||||
@ -82,17 +78,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, M, OT, R, S, Z> PushStage<C, CS, EM, I, OT, R, S, Z>
|
impl<CS, EM, I, M, OT, S, Z> PushStage<CS, EM, I, OT, S, Z>
|
||||||
for StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
|
for StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
@ -186,26 +180,24 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push_stage_helper(&self) -> &PushStageHelper<C, CS, EM, I, OT, R, S, Z> {
|
fn push_stage_helper(&self) -> &PushStageHelper<CS, EM, I, OT, S, Z> {
|
||||||
&self.psh
|
&self.psh
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<C, CS, EM, I, OT, R, S, Z> {
|
fn push_stage_helper_mut(&mut self) -> &mut PushStageHelper<CS, EM, I, OT, S, Z> {
|
||||||
&mut self.psh
|
&mut self.psh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, M, OT, R, S, Z> Iterator for StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
|
impl<CS, EM, I, M, OT, S, Z> Iterator for StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId + ProgressReporter<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasExecutions,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasExecutions,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
type Item = Result<I, Error>;
|
type Item = Result<I, Error>;
|
||||||
@ -215,16 +207,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CS, EM, I, M, OT, R, S, Z> StdMutationalPushStage<C, CS, EM, I, M, OT, R, S, Z>
|
impl<CS, EM, I, M, OT, S, Z> StdMutationalPushStage<CS, EM, I, M, OT, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CS: CorpusScheduler<I, S>,
|
CS: CorpusScheduler<I, S>,
|
||||||
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
EM: EventFirer<I> + EventRestarter<S> + HasEventManagerId,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R>,
|
|
||||||
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
Z: ExecutionProcessor<I, OT, S> + EvaluatorObservers<I, OT, S> + HasCorpusScheduler<CS, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
@ -232,7 +222,7 @@ where
|
|||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mutator: M,
|
mutator: M,
|
||||||
shared_state: Rc<RefCell<Option<PushStageSharedState<C, CS, EM, I, OT, R, S, Z>>>>,
|
shared_state: Rc<RefCell<Option<PushStageSharedState<CS, EM, I, OT, S, Z>>>>,
|
||||||
exit_kind: Rc<Cell<Option<ExitKind>>>,
|
exit_kind: Rc<Cell<Option<ExitKind>>>,
|
||||||
stage_idx: i32,
|
stage_idx: i32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -10,8 +10,6 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::rands::Rand,
|
|
||||||
corpus::Corpus,
|
|
||||||
fuzzer::Evaluator,
|
fuzzer::Evaluator,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
stages::Stage,
|
stages::Stage,
|
||||||
@ -38,28 +36,24 @@ impl SyncFromDiskMetadata {
|
|||||||
|
|
||||||
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SyncFromDiskStage<C, CB, E, EM, I, R, S, Z>
|
pub struct SyncFromDiskStage<CB, E, EM, I, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
sync_dir: PathBuf,
|
sync_dir: PathBuf,
|
||||||
load_callback: CB,
|
load_callback: CB,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, E, EM, I, R, S, Z)>,
|
phantom: PhantomData<(E, EM, I, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CB, E, EM, I, R, S, Z> Stage<E, EM, S, Z> for SyncFromDiskStage<C, CB, E, EM, I, R, S, Z>
|
impl<CB, E, EM, I, S, Z> Stage<E, EM, S, Z> for SyncFromDiskStage<CB, E, EM, I, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -99,13 +93,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, CB, E, EM, I, R, S, Z> SyncFromDiskStage<C, CB, E, EM, I, R, S, Z>
|
impl<CB, E, EM, I, S, Z> SyncFromDiskStage<CB, E, EM, I, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
CB: FnMut(&mut Z, &mut S, &Path) -> Result<I, Error>,
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SyncFromDiskStage`]
|
/// Creates a new [`SyncFromDiskStage`]
|
||||||
@ -163,13 +155,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, R, S, Z>
|
impl<E, EM, I, S, Z>
|
||||||
SyncFromDiskStage<C, fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, R, S, Z>
|
SyncFromDiskStage<fn(&mut Z, &mut S, &Path) -> Result<I, Error>, E, EM, I, S, Z>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasRand + HasMetadata,
|
||||||
S: HasClientPerfMonitor + HasCorpus<C, I> + HasRand<R> + HasMetadata,
|
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SyncFromDiskStage`] invoking `Input::from_file` to load inputs
|
/// Creates a new [`SyncFromDiskStage`] invoking `Input::from_file` to load inputs
|
||||||
|
@ -19,26 +19,24 @@ use crate::monitors::PerfFeature;
|
|||||||
|
|
||||||
/// A stage that runs a tracer executor
|
/// A stage that runs a tracer executor
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TracingStage<C, EM, I, OT, S, TE, Z>
|
pub struct TracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
tracer_executor: TE,
|
tracer_executor: TE,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, EM, I, OT, S, TE, Z)>,
|
phantom: PhantomData<(EM, I, OT, S, TE, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, C, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<C, EM, I, OT, S, TE, Z>
|
impl<E, EM, I, OT, S, TE, Z> Stage<E, EM, S, Z> for TracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -82,13 +80,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, EM, I, OT, S, TE, Z> TracingStage<C, EM, I, OT, S, TE, Z>
|
impl<EM, I, OT, S, TE, Z> TracingStage<EM, I, OT, S, TE, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
TE: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
/// Creates a new default stage
|
/// Creates a new default stage
|
||||||
pub fn new(tracer_executor: TE) -> Self {
|
pub fn new(tracer_executor: TE) -> Self {
|
||||||
@ -106,20 +103,19 @@ where
|
|||||||
|
|
||||||
/// A stage that runs the shadow executor using also the shadow observers
|
/// A stage that runs the shadow executor using also the shadow observers
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z> {
|
pub struct ShadowTracingStage<E, EM, I, OT, S, SOT, Z> {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(C, E, EM, I, OT, S, SOT, Z)>,
|
phantom: PhantomData<(E, EM, I, OT, S, SOT, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
impl<E, EM, I, OT, S, SOT, Z> Stage<ShadowExecutor<E, I, S, SOT>, EM, S, Z>
|
||||||
for ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z>
|
for ShadowTracingStage<E, EM, I, OT, S, SOT, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
SOT: ObserversTuple<I, S>,
|
SOT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I> + Debug,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I> + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn perform(
|
fn perform(
|
||||||
@ -163,14 +159,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, E, EM, I, OT, S, SOT, Z> ShadowTracingStage<C, E, EM, I, OT, S, SOT, Z>
|
impl<E, EM, I, OT, S, SOT, Z> ShadowTracingStage<E, EM, I, OT, S, SOT, Z>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
SOT: ObserversTuple<I, S>,
|
SOT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasExecutions + HasCorpus<C, I>,
|
S: HasClientPerfMonitor + HasExecutions + HasCorpus<I>,
|
||||||
{
|
{
|
||||||
/// Creates a new default stage
|
/// Creates a new default stage
|
||||||
pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self {
|
pub fn new(_executor: &mut ShadowExecutor<E, I, S, SOT>) -> Self {
|
||||||
|
@ -32,15 +32,13 @@ pub const DEFAULT_MAX_SIZE: usize = 1_048_576;
|
|||||||
pub trait State: Serialize + DeserializeOwned {}
|
pub trait State: Serialize + DeserializeOwned {}
|
||||||
|
|
||||||
/// Trait for elements offering a corpus
|
/// Trait for elements offering a corpus
|
||||||
pub trait HasCorpus<C, I>
|
pub trait HasCorpus<I: Input> {
|
||||||
where
|
/// The associated type implementing [`Corpus`].
|
||||||
C: Corpus<I>,
|
type Corpus: Corpus<I>;
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// The testcase corpus
|
/// The testcase corpus
|
||||||
fn corpus(&self) -> &C;
|
fn corpus(&self) -> &Self::Corpus;
|
||||||
/// The testcase corpus (mut)
|
/// The testcase corpus (mut)
|
||||||
fn corpus_mut(&mut self) -> &mut C;
|
fn corpus_mut(&mut self) -> &mut Self::Corpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interact with the maximum size
|
/// Interact with the maximum size
|
||||||
@ -52,26 +50,23 @@ pub trait HasMaxSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for elements offering a corpus of solutions
|
/// Trait for elements offering a corpus of solutions
|
||||||
pub trait HasSolutions<C, I>
|
pub trait HasSolutions<I: Input> {
|
||||||
where
|
/// The associated type implementing [`Corpus`] for solutions
|
||||||
C: Corpus<I>,
|
type Solutions: Corpus<I>;
|
||||||
I: Input,
|
|
||||||
{
|
|
||||||
/// The solutions corpus
|
/// The solutions corpus
|
||||||
fn solutions(&self) -> &C;
|
fn solutions(&self) -> &Self::Solutions;
|
||||||
/// The solutions corpus (mut)
|
/// The solutions corpus (mut)
|
||||||
fn solutions_mut(&mut self) -> &mut C;
|
fn solutions_mut(&mut self) -> &mut Self::Solutions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for elements offering a rand
|
/// Trait for elements offering a rand
|
||||||
pub trait HasRand<R>
|
pub trait HasRand {
|
||||||
where
|
/// The associated type implementing [`Rand`]
|
||||||
R: Rand,
|
type Rand: Rand;
|
||||||
{
|
|
||||||
/// The rand instance
|
/// The rand instance
|
||||||
fn rand(&self) -> &R;
|
fn rand(&self) -> &Self::Rand;
|
||||||
/// The rand instance (mut)
|
/// The rand instance (mut)
|
||||||
fn rand_mut(&mut self) -> &mut R;
|
fn rand_mut(&mut self) -> &mut Self::Rand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for offering a [`ClientPerfMonitor`]
|
/// Trait for offering a [`ClientPerfMonitor`]
|
||||||
@ -116,15 +111,14 @@ pub trait HasMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for elements offering a feedback
|
/// Trait for elements offering a feedback
|
||||||
pub trait HasFeedbackStates<FT>
|
pub trait HasFeedbackStates {
|
||||||
where
|
/// The associated feedback type implementing [`FeedbackStatesTuple`].
|
||||||
FT: FeedbackStatesTuple,
|
type FeedbackStates: FeedbackStatesTuple;
|
||||||
{
|
|
||||||
/// The feedback states
|
/// The feedback states
|
||||||
fn feedback_states(&self) -> &FT;
|
fn feedback_states(&self) -> &Self::FeedbackStates;
|
||||||
|
|
||||||
/// The feedback states (mut)
|
/// The feedback states (mut)
|
||||||
fn feedback_states_mut(&mut self) -> &mut FT;
|
fn feedback_states_mut(&mut self) -> &mut Self::FeedbackStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for the execution counter
|
/// Trait for the execution counter
|
||||||
@ -192,7 +186,7 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, FT, I, R, SC> HasRand<R> for StdState<C, FT, I, R, SC>
|
impl<C, FT, I, R, SC> HasRand for StdState<C, FT, I, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -200,20 +194,22 @@ where
|
|||||||
FT: FeedbackStatesTuple,
|
FT: FeedbackStatesTuple,
|
||||||
SC: Corpus<I>,
|
SC: Corpus<I>,
|
||||||
{
|
{
|
||||||
|
type Rand = R;
|
||||||
|
|
||||||
/// The rand instance
|
/// The rand instance
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand(&self) -> &R {
|
fn rand(&self) -> &Self::Rand {
|
||||||
&self.rand
|
&self.rand
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rand instance (mut)
|
/// The rand instance (mut)
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand_mut(&mut self) -> &mut R {
|
fn rand_mut(&mut self) -> &mut Self::Rand {
|
||||||
&mut self.rand
|
&mut self.rand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, FT, I, R, SC> HasCorpus<C, I> for StdState<C, FT, I, R, SC>
|
impl<C, FT, I, R, SC> HasCorpus<I> for StdState<C, FT, I, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -221,6 +217,8 @@ where
|
|||||||
FT: FeedbackStatesTuple,
|
FT: FeedbackStatesTuple,
|
||||||
SC: Corpus<I>,
|
SC: Corpus<I>,
|
||||||
{
|
{
|
||||||
|
type Corpus = C;
|
||||||
|
|
||||||
/// Returns the corpus
|
/// Returns the corpus
|
||||||
#[inline]
|
#[inline]
|
||||||
fn corpus(&self) -> &C {
|
fn corpus(&self) -> &C {
|
||||||
@ -234,7 +232,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, FT, I, R, SC> HasSolutions<SC, I> for StdState<C, FT, I, R, SC>
|
impl<C, FT, I, R, SC> HasSolutions<I> for StdState<C, FT, I, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -242,6 +240,8 @@ where
|
|||||||
FT: FeedbackStatesTuple,
|
FT: FeedbackStatesTuple,
|
||||||
SC: Corpus<I>,
|
SC: Corpus<I>,
|
||||||
{
|
{
|
||||||
|
type Solutions = SC;
|
||||||
|
|
||||||
/// Returns the solutions corpus
|
/// Returns the solutions corpus
|
||||||
#[inline]
|
#[inline]
|
||||||
fn solutions(&self) -> &SC {
|
fn solutions(&self) -> &SC {
|
||||||
@ -276,7 +276,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, FT, I, R, SC> HasFeedbackStates<FT> for StdState<C, FT, I, R, SC>
|
impl<C, FT, I, R, SC> HasFeedbackStates for StdState<C, FT, I, R, SC>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -284,6 +284,8 @@ where
|
|||||||
FT: FeedbackStatesTuple,
|
FT: FeedbackStatesTuple,
|
||||||
SC: Corpus<I>,
|
SC: Corpus<I>,
|
||||||
{
|
{
|
||||||
|
type FeedbackStates = FT;
|
||||||
|
|
||||||
/// The feedback states
|
/// The feedback states
|
||||||
#[inline]
|
#[inline]
|
||||||
fn feedback_states(&self) -> &FT {
|
fn feedback_states(&self) -> &FT {
|
||||||
|
@ -7,7 +7,6 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::Corpus,
|
|
||||||
events::{EventFirer, EventRestarter},
|
events::{EventFirer, EventRestarter},
|
||||||
executors::{
|
executors::{
|
||||||
inprocess::inprocess_get_state, Executor, ExitKind, HasObservers, InProcessExecutor,
|
inprocess::inprocess_get_state, Executor, ExitKind, HasObservers, InProcessExecutor,
|
||||||
@ -474,7 +473,7 @@ where
|
|||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
QT: QemuHelperTuple<I, S>,
|
QT: QemuHelperTuple<I, S>,
|
||||||
{
|
{
|
||||||
pub fn new<EM, OC, OF, Z>(
|
pub fn new<EM, OF, Z>(
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
emulator: &'a Emulator,
|
emulator: &'a Emulator,
|
||||||
helpers: QT,
|
helpers: QT,
|
||||||
@ -485,9 +484,8 @@ where
|
|||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
EM: EventFirer<I> + EventRestarter<S>,
|
EM: EventFirer<I> + EventRestarter<S>,
|
||||||
OC: Corpus<I>,
|
|
||||||
OF: Feedback<I, S>,
|
OF: Feedback<I, S>,
|
||||||
S: HasSolutions<OC, I> + HasClientPerfMonitor,
|
S: HasSolutions<I> + HasClientPerfMonitor,
|
||||||
Z: HasObjective<I, OF, S>,
|
Z: HasObjective<I, OF, S>,
|
||||||
{
|
{
|
||||||
let slf = Self {
|
let slf = Self {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user