From e5aaf85d3cc0e0000b76022446ef9a36f0803476 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 12 Nov 2022 03:02:54 +0100 Subject: [PATCH] Tuneable Stage, Scheduler, ScheduledMutator (#874) * Tuneable Stage, Scheduler, and Mutators * rename * fix build * get rid of prelude * fmt * Reworked tunable, fixed stuff, add testcase * clippy * further fixes * fix typo, fmt --- libafl/examples/llmp_test/main.rs | 20 +- libafl/src/executors/command.rs | 4 +- libafl/src/mutators/mod.rs | 2 + libafl/src/mutators/mopt_mutator.rs | 1 + libafl/src/mutators/tuneable.rs | 240 ++++++++++++++++++++ libafl/src/schedulers/mod.rs | 3 + libafl/src/schedulers/tuneable.rs | 108 +++++++++ libafl/src/stages/mod.rs | 3 + libafl/src/stages/mutational.rs | 6 +- libafl/src/stages/power.rs | 4 +- libafl/src/stages/tuneable.rs | 148 ++++++++++++ libafl/src/state/mod.rs | 24 +- scripts/autofix.sh | 4 +- scripts/clippy.ps1 | 2 +- scripts/clippy.sh | 2 +- scripts/find_unused_rs_files.sh | 2 +- utils/libafl_benches/benches/hash_speeds.rs | 10 +- 17 files changed, 555 insertions(+), 28 deletions(-) create mode 100644 libafl/src/mutators/tuneable.rs create mode 100644 libafl/src/schedulers/tuneable.rs create mode 100644 libafl/src/stages/tuneable.rs diff --git a/libafl/examples/llmp_test/main.rs b/libafl/examples/llmp_test/main.rs index a605bab15c..3506231159 100644 --- a/libafl/examples/llmp_test/main.rs +++ b/libafl/examples/llmp_test/main.rs @@ -18,9 +18,9 @@ use libafl::{ Error, }; -const _TAG_SIMPLE_U32_V1: Tag = 0x51300321; -const _TAG_MATH_RESULT_V1: Tag = 0x77474331; -const _TAG_1MEG_V1: Tag = 0xB1111161; +const _TAG_SIMPLE_U32_V1: Tag = 0x5130_0321; +const _TAG_MATH_RESULT_V1: Tag = 0x7747_4331; +const _TAG_1MEG_V1: Tag = 0xB111_1161; #[cfg(all(unix, feature = "std"))] fn adder_loop(port: u16) -> ! { @@ -71,15 +71,17 @@ fn large_msg_loop(port: u16) -> ! { let mut client = llmp::LlmpClient::create_attach_to_tcp(StdShMemProvider::new().unwrap(), port).unwrap(); + #[allow(clippy::large_stack_arrays)] let meg_buf = [1u8; 1 << 20]; loop { client.send_buf(_TAG_1MEG_V1, &meg_buf).unwrap(); println!("Sending the next megabyte"); - thread::sleep(time::Duration::from_millis(100)) + thread::sleep(time::Duration::from_millis(100)); } } +#[allow(clippy::unnecessary_wraps)] #[cfg(all(unix, feature = "std"))] fn broker_message_hook( client_id: u32, @@ -133,20 +135,20 @@ fn main() { .unwrap_or_else(|| "4242".into()) .parse::() .unwrap(); - println!("Launching in mode {} on port {}", mode, port); + println!("Launching in mode {mode} on port {port}"); match mode.as_str() { "broker" => { let mut broker = llmp::LlmpBroker::new(StdShMemProvider::new().unwrap()).unwrap(); broker.launch_tcp_listener_on(port).unwrap(); - broker.loop_forever(&mut broker_message_hook, Some(Duration::from_millis(5))) + broker.loop_forever(&mut broker_message_hook, Some(Duration::from_millis(5))); } "b2b" => { let mut broker = llmp::LlmpBroker::new(StdShMemProvider::new().unwrap()).unwrap(); broker.launch_tcp_listener_on(b2b_port).unwrap(); // connect back to the main broker. broker.connect_b2b(("127.0.0.1", port)).unwrap(); - broker.loop_forever(&mut broker_message_hook, Some(Duration::from_millis(5))) + broker.loop_forever(&mut broker_message_hook, Some(Duration::from_millis(5))); } "ctr" => { let mut client = @@ -158,8 +160,8 @@ fn main() { client .send_buf(_TAG_SIMPLE_U32_V1, &counter.to_le_bytes()) .unwrap(); - println!("CTR Client writing {}", counter); - thread::sleep(Duration::from_secs(1)) + println!("CTR Client writing {counter}"); + thread::sleep(Duration::from_secs(1)); } } "adder" => { diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 85640876bd..bc5ff0cbe8 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -35,10 +35,10 @@ use crate::{ use crate::{inputs::Input, Error}; /// How to deliver input to an external program -/// `StdIn`: The traget reads from stdin +/// `StdIn`: The target reads from stdin /// `File`: The target reads from the specified [`InputFile`] #[derive(Debug, Clone, PartialEq, Eq)] -enum InputLocation { +pub enum InputLocation { /// Mutate a commandline argument to deliver an input Arg { /// The offset of the argument to mutate diff --git a/libafl/src/mutators/mod.rs b/libafl/src/mutators/mod.rs index f04163a1f7..6c71bad390 100644 --- a/libafl/src/mutators/mod.rs +++ b/libafl/src/mutators/mod.rs @@ -14,6 +14,8 @@ pub mod gramatron; pub use gramatron::*; pub mod grimoire; pub use grimoire::*; +pub mod tuneable; +pub use tuneable::*; #[cfg(feature = "nautilus")] pub mod nautilus; diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index 2f943a5504..6fdd4b0fe2 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -644,6 +644,7 @@ where } /// Get the next mutation to apply + #[inline] fn schedule(&self, state: &mut S, _: &S::Input) -> usize { state .metadata_mut() diff --git a/libafl/src/mutators/tuneable.rs b/libafl/src/mutators/tuneable.rs new file mode 100644 index 0000000000..d678220fdb --- /dev/null +++ b/libafl/src/mutators/tuneable.rs @@ -0,0 +1,240 @@ +//! An extension to the `ScheduledMutator` which schedules multiple mutations internally. +//! Instead of a random mutator for a random amount of iterations, we can run +//! a specific mutator for a specified amount of iterations + +use alloc::vec::Vec; +use core::{ + fmt::{self, Debug}, + marker::PhantomData, +}; + +use serde::{Deserialize, Serialize}; + +pub use crate::mutators::{mutations::*, token_mutations::*}; +use crate::{ + bolts::rands::Rand, + impl_serdeany, + mutators::{ComposedByMutations, MutationResult, Mutator, MutatorsTuple, ScheduledMutator}, + state::{HasMetadata, HasRand, State}, + Error, +}; + +/// Metadata in the state, that controls the behavior of the [`TuneableScheduledMutator`] at runtime +#[derive(Default, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] +pub struct TuneableScheduledMutatorMetadata { + /// The offsets of mutators to run, in order. Clear to fall back to random. + pub next: Vec, + /// The next index to read from in the `next` vec + pub next_idx: usize, + /// The count of total mutations to perform. + /// If `next` is of length `10`, and this number is `20`, + /// the mutations will be iterated through twice. + pub iters: Option, +} + +impl TuneableScheduledMutatorMetadata { + /// Gets the stored metadata, used to alter the [`TuneableScheduledMutator`] behavior + pub fn get(state: &S) -> Result<&Self, Error> { + state + .metadata() + .get::() + .ok_or_else(|| Error::illegal_state("TuneableScheduledMutator not in use")) + } + + /// Gets the stored metadata, used to alter the [`TuneableScheduledMutator`] behavior, mut + pub fn get_mut(state: &mut S) -> Result<&mut Self, Error> { + state + .metadata_mut() + .get_mut::() + .ok_or_else(|| Error::illegal_state("TuneableScheduledMutator not in use")) + } +} + +impl_serdeany!(TuneableScheduledMutatorMetadata); + +/// A [`Mutator`] that schedules one of the embedded mutations on each call. +/// The index of the next mutation can be set. +pub struct TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand, +{ + mutations: MT, + max_stack_pow: u64, + phantom: PhantomData, +} + +impl Debug for TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "TuneableScheduledMutator with {} mutations for Input type {}", + self.mutations.len(), + core::any::type_name::() + ) + } +} + +impl Mutator for TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand + HasMetadata, +{ + #[inline] + fn mutate( + &mut self, + state: &mut S, + input: &mut S::Input, + stage_idx: i32, + ) -> Result { + self.scheduled_mutate(state, input, stage_idx) + } +} + +impl ComposedByMutations for TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand, +{ + /// Get the mutations + #[inline] + fn mutations(&self) -> &MT { + &self.mutations + } + + // Get the mutations (mutable) + #[inline] + fn mutations_mut(&mut self) -> &mut MT { + &mut self.mutations + } +} + +impl ScheduledMutator for TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand + HasMetadata, +{ + /// Compute the number of iterations used to apply stacked mutations + fn iterations(&self, state: &mut S, _: &S::Input) -> u64 { + if let Some(iters) = Self::get_iters(state) { + iters + } else { + // fall back to random + 1 << (1 + state.rand_mut().below(self.max_stack_pow)) + } + } + + /// Get the next mutation to apply + fn schedule(&self, state: &mut S, _: &S::Input) -> usize { + debug_assert!(!self.mutations().is_empty()); + // Assumption: we can not reach this code path without previously adding this metadatum. + let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap(); + #[allow(clippy::cast_possible_truncation)] + if metadata.next.is_empty() { + // fall back to random if no entries in the vec + state.rand_mut().below(self.mutations().len() as u64) as usize + } else { + let ret = metadata.next[metadata.next_idx]; + metadata.next_idx += 1_usize; + if metadata.next_idx >= metadata.next.len() { + metadata.next_idx = 0; + } + debug_assert!( + self.mutations().len() > ret, + "TuneableScheduler: next vec may not contain idx larger than number of mutations!" + ); + ret + } + } +} + +impl TuneableScheduledMutator +where + MT: MutatorsTuple, + S: State + HasRand + HasMetadata, +{ + /// Create a new [`TuneableScheduledMutator`] instance specifying mutations + pub fn new(state: &mut S, mutations: MT) -> Self { + if !state.has_metadata::() { + state.add_metadata(TuneableScheduledMutatorMetadata::default()); + } + TuneableScheduledMutator { + mutations, + max_stack_pow: 7, + phantom: PhantomData, + } + } + + fn metadata_mut(state: &mut S) -> &mut TuneableScheduledMutatorMetadata { + state + .metadata_mut() + .get_mut::() + .unwrap() + } + + fn metadata(state: &S) -> &TuneableScheduledMutatorMetadata { + state + .metadata() + .get::() + .unwrap() + } + + /// Sets the next iterations count, i.e., how many times to mutate the input + /// + /// Using `set_next_and_iter` to set multiple values at the same time + /// will be faster than setting them individually + /// as it internally only needs a single metadata lookup + pub fn set_iters(state: &mut S, iters: u64) { + let metadata = Self::metadata_mut(state); + metadata.iters = Some(iters); + } + + /// Gets the set iterations + pub fn get_iters(state: &S) -> Option { + let metadata = Self::metadata(state); + metadata.iters + } + + /// Resets this to a randomic mutational stage + pub fn reset(state: &mut S) { + let metadata = Self::metadata_mut(state); + metadata.next.clear(); + metadata.next_idx = 0; + metadata.iters = None; + } +} + +#[cfg(test)] +mod test { + use super::{ + BitFlipMutator, ByteDecMutator, TuneableScheduledMutator, TuneableScheduledMutatorMetadata, + }; + use crate::{ + bolts::tuples::tuple_list, + inputs::BytesInput, + mutators::{ByteRandMutator, ScheduledMutator}, + state::NopState, + }; + + #[test] + fn test_tuning() { + let mut state = NopState::new(); + let mutators = tuple_list!( + BitFlipMutator::new(), + ByteDecMutator::new(), + ByteRandMutator::new() + ); + let tuneable = TuneableScheduledMutator::new(&mut state, mutators); + let input = BytesInput::new(vec![42]); + let metadata = TuneableScheduledMutatorMetadata::get_mut(&mut state).unwrap(); + metadata.next.push(1); + metadata.next.push(2); + assert_eq!(tuneable.schedule(&mut state, &input), 1); + assert_eq!(tuneable.schedule(&mut state, &input), 2); + assert_eq!(tuneable.schedule(&mut state, &input), 1); + } +} diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 238bd03d09..9d3cdfd8f3 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -27,6 +27,9 @@ use alloc::borrow::ToOwned; pub use powersched::PowerQueueScheduler; +pub mod tuneable; +pub use tuneable::*; + use crate::{ bolts::rands::Rand, corpus::{Corpus, Testcase}, diff --git a/libafl/src/schedulers/tuneable.rs b/libafl/src/schedulers/tuneable.rs new file mode 100644 index 0000000000..e2cd11b35e --- /dev/null +++ b/libafl/src/schedulers/tuneable.rs @@ -0,0 +1,108 @@ +//! The queue corpus scheduler implements an AFL-like queue mechanism +//! The [`TuneableScheduler`] extends the queue scheduler with a method to +//! chose the next corpus entry manually + +use alloc::borrow::ToOwned; +use core::marker::PhantomData; + +use serde::{Deserialize, Serialize}; + +use crate::{ + corpus::Corpus, + impl_serdeany, + inputs::UsesInput, + schedulers::Scheduler, + state::{HasCorpus, HasMetadata, UsesState}, + Error, +}; + +#[derive(Default, Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)] +struct TuneableSchedulerMetadata { + next: Option, +} + +impl_serdeany!(TuneableSchedulerMetadata); + +/// Walk the corpus in a queue-like fashion +/// With the specific `set_next` method, we can chose the next corpus entry manually +#[derive(Debug, Clone)] +pub struct TuneableScheduler { + phantom: PhantomData, +} + +impl TuneableScheduler +where + S: HasMetadata + HasCorpus, +{ + /// Creates a new `TuneableScheduler` + #[must_use] + pub fn new(state: &mut S) -> Self { + if !state.has_metadata::() { + state.add_metadata(TuneableSchedulerMetadata::default()); + } + Self { + phantom: PhantomData, + } + } + + fn metadata_mut(state: &mut S) -> &mut TuneableSchedulerMetadata { + state + .metadata_mut() + .get_mut::() + .unwrap() + } + + fn metadata(state: &S) -> &TuneableSchedulerMetadata { + state.metadata().get::().unwrap() + } + + /// Sets the next corpus id to be used + pub fn set_next(state: &mut S, next: usize) { + Self::metadata_mut(state).next = Some(next); + } + + /// Gets the next set corpus id + pub fn get_next(state: &S) -> Option { + Self::metadata(state).next + } + + /// Resets this to a queue scheduler + pub fn reset(state: &mut S) { + let metadata = Self::metadata_mut(state); + metadata.next = None; + } + + /// Gets the current corpus entry id + pub fn get_current(state: &S) -> usize { + state.corpus().current().unwrap_or_default() + } +} + +impl UsesState for TuneableScheduler +where + S: UsesInput, +{ + type State = S; +} + +impl Scheduler for TuneableScheduler +where + S: HasCorpus + HasMetadata, +{ + /// Gets the next entry in the queue + fn next(&self, state: &mut Self::State) -> Result { + if state.corpus().count() == 0 { + return Err(Error::empty("No entries in corpus".to_owned())); + } + let id = if let Some(next) = Self::get_next(state) { + // next was set + next + } else if Self::get_current(state) + 1 >= state.corpus().count() { + 0 + } else { + Self::get_current(state) + 1 + }; + *state.corpus_mut().current_mut() = Some(id); + Ok(id) + } +} diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 848c0d9cc7..ab50cef54f 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -30,6 +30,9 @@ pub use generalization::GeneralizationStage; pub mod owned; pub use owned::StagesOwnedList; +pub mod tuneable; +pub use tuneable::*; + #[cfg(feature = "std")] pub mod concolic; #[cfg(feature = "std")] diff --git a/libafl/src/stages/mutational.rs b/libafl/src/stages/mutational.rs index 578baed5a8..57a2ae6e7f 100644 --- a/libafl/src/stages/mutational.rs +++ b/libafl/src/stages/mutational.rs @@ -37,7 +37,7 @@ where fn mutator_mut(&mut self) -> &mut M; /// Gets the number of iterations this mutator should run for. - fn iterations(&self, state: &mut Z::State, corpus_idx: usize) -> Result; + fn iterations(&self, state: &mut Z::State, corpus_idx: usize) -> Result; /// Runs this (mutational) stage for the given testcase #[allow(clippy::cast_possible_wrap)] // more than i32 stages on 32 bit system - highly unlikely... @@ -109,8 +109,8 @@ where } /// Gets the number of iterations as a random number - fn iterations(&self, state: &mut Z::State, _corpus_idx: usize) -> Result { - Ok(1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) as usize) + fn iterations(&self, state: &mut Z::State, _corpus_idx: usize) -> Result { + Ok(1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS)) } } diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index b8e00fcf71..e94bb208e5 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -58,10 +58,10 @@ where /// Gets the number of iterations as a random number #[allow(clippy::cast_sign_loss)] - fn iterations(&self, state: &mut E::State, corpus_idx: usize) -> Result { + fn iterations(&self, state: &mut E::State, corpus_idx: usize) -> Result { // Update handicap let mut testcase = state.corpus().get(corpus_idx)?.borrow_mut(); - let score = F::compute(&mut *testcase, state)? as usize; + let score = F::compute(&mut *testcase, state)? as u64; Ok(score) } diff --git a/libafl/src/stages/tuneable.rs b/libafl/src/stages/tuneable.rs new file mode 100644 index 0000000000..ff68fea670 --- /dev/null +++ b/libafl/src/stages/tuneable.rs @@ -0,0 +1,148 @@ +//! A [`crate::stages::MutationalStage`] where the mutator iteration can be tuned at runtime + +use core::marker::PhantomData; + +use serde::{Deserialize, Serialize}; + +use crate::{ + bolts::rands::Rand, + impl_serdeany, + mutators::Mutator, + stages::{mutational::DEFAULT_MUTATIONAL_MAX_ITERATIONS, MutationalStage, Stage}, + state::{HasClientPerfMonitor, HasCorpus, HasMetadata, HasRand, UsesState}, + Error, Evaluator, +}; + +#[derive(Default, Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)] +struct TuneableMutationalStageMetadata { + iters: Option, +} + +impl_serdeany!(TuneableMutationalStageMetadata); + +/// Set the number of iterations to be used by this mutational stage +pub fn set_iters(state: &mut S, iters: u64) -> Result<(), Error> { + let metadata = state + .metadata_mut() + .get_mut::() + .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")); + metadata.map(|metadata| { + metadata.iters = Some(iters); + }) +} + +/// Get the set iterations +pub fn get_iters(state: &S) -> Result, Error> { + state + .metadata() + .get::() + .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")) + .map(|metadata| metadata.iters) +} + +/// Reset this to a normal, randomized, stage +pub fn reset(state: &mut S) -> Result<(), Error> { + state + .metadata_mut() + .get_mut::() + .ok_or_else(|| Error::illegal_state("TuneableMutationslStage not in use")) + .map(|metadata| metadata.iters = None) +} + +/// A [`crate::stages::MutationalStage`] where the mutator iteration can be tuned at runtime +#[derive(Clone, Debug)] +pub struct TuneableMutationalStage { + mutator: M, + phantom: PhantomData<(E, EM, Z)>, +} + +impl MutationalStage for TuneableMutationalStage +where + E: UsesState, + EM: UsesState, + M: Mutator, + Z: Evaluator, + Z::State: HasClientPerfMonitor + HasCorpus + HasRand + HasMetadata, +{ + /// The mutator, added to this stage + #[inline] + fn mutator(&self) -> &M { + &self.mutator + } + + /// The list of mutators, added to this stage (as mutable ref) + #[inline] + fn mutator_mut(&mut self) -> &mut M { + &mut self.mutator + } + + /// Gets the number of iterations as a random number + #[allow(clippy::cast_possible_truncation)] + fn iterations(&self, state: &mut Z::State, _corpus_idx: usize) -> Result { + Ok(if let Some(iters) = get_iters(state)? { + iters + } else { + // fall back to random + 1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) + }) + } +} + +impl UsesState for TuneableMutationalStage +where + E: UsesState, + EM: UsesState, + M: Mutator, + Z: Evaluator, + Z::State: HasClientPerfMonitor + HasCorpus + HasRand, +{ + type State = Z::State; +} + +impl Stage for TuneableMutationalStage +where + E: UsesState, + EM: UsesState, + M: Mutator, + Z: Evaluator, + Z::State: HasClientPerfMonitor + HasCorpus + HasRand + HasMetadata, +{ + #[inline] + #[allow(clippy::let_and_return)] + fn perform( + &mut self, + fuzzer: &mut Z, + executor: &mut E, + state: &mut Z::State, + manager: &mut EM, + corpus_idx: usize, + ) -> Result<(), Error> { + let ret = self.perform_mutational(fuzzer, executor, state, manager, corpus_idx); + + #[cfg(feature = "introspection")] + state.introspection_monitor_mut().finish_stage(); + + ret + } +} + +impl TuneableMutationalStage +where + E: UsesState, + EM: UsesState, + M: Mutator, + Z: Evaluator, + Z::State: HasClientPerfMonitor + HasCorpus + HasRand + HasMetadata, +{ + /// Creates a new default mutational stage + #[must_use] + pub fn new(state: &mut Z::State, mutator: M) -> Self { + if !state.has_metadata::() { + state.add_metadata(TuneableMutationalStageMetadata::default()); + } + Self { + mutator, + phantom: PhantomData, + } + } +} diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index 240620c5a6..1a91e1c5ab 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -9,6 +9,8 @@ use std::{ use serde::{de::DeserializeOwned, Deserialize, Serialize}; +#[cfg(test)] +use crate::bolts::rands::StdRand; use crate::{ bolts::{ rands::Rand, @@ -599,8 +601,11 @@ impl HasClientPerfMonitor for StdState { } #[cfg(test)] +/// A very simple state without any bells or whistles, for testing. #[derive(Debug, Serialize, Deserialize, Default)] pub struct NopState { + metadata: SerdeAnyMap, + rand: StdRand, phantom: PhantomData, } @@ -610,6 +615,8 @@ impl NopState { #[must_use] pub fn new() -> Self { NopState { + metadata: SerdeAnyMap::new(), + rand: StdRand::default(), phantom: PhantomData, } } @@ -637,11 +644,24 @@ impl HasExecutions for NopState { #[cfg(test)] impl HasMetadata for NopState { fn metadata(&self) -> &SerdeAnyMap { - unimplemented!() + &self.metadata } fn metadata_mut(&mut self) -> &mut SerdeAnyMap { - unimplemented!() + &mut self.metadata + } +} + +#[cfg(test)] +impl HasRand for NopState { + type Rand = StdRand; + + fn rand(&self) -> &Self::Rand { + &self.rand + } + + fn rand_mut(&mut self) -> &mut Self::Rand { + &mut self.rand } } diff --git a/scripts/autofix.sh b/scripts/autofix.sh index 5a622802f3..705b210fff 100755 --- a/scripts/autofix.sh +++ b/scripts/autofix.sh @@ -17,7 +17,7 @@ echo "[+] Done fixing build" echo echo 'Fixing clippy (might need a "git commit" and a rerun, if "cargo fix" changed the source)' -RUST_BACKTRACE=full cargo +nightly clippy --fix --release --all --all-features --tests -- -Z macro-backtrace \ +RUST_BACKTRACE=full cargo +nightly clippy --fix --release --all --all-features --tests --examples --benches -- -Z macro-backtrace \ -D clippy::all \ -D clippy::pedantic \ -W clippy::similar_names \ @@ -32,7 +32,7 @@ RUST_BACKTRACE=full cargo +nightly clippy --fix --release --all --all-features - -A clippy::module-name-repetitions \ -A clippy::unreadable-literal \ -cargo +nightly clippy --fix --tests --all-features --allow-dirty --allow-staged +cargo +nightly clippy --fix --tests --examples --benches --all-features --allow-dirty --allow-staged echo "[+] Done fixing clippy" echo diff --git a/scripts/clippy.ps1 b/scripts/clippy.ps1 index 2f832d67d6..33415c9cfc 100644 --- a/scripts/clippy.ps1 +++ b/scripts/clippy.ps1 @@ -1,4 +1,4 @@ -cargo clippy --all --all-features --tests -- ` +cargo clippy --all --all-features --tests --benches --examples -- ` -D clippy::all ` -D clippy::pedantic ` -W clippy::similar_names ` diff --git a/scripts/clippy.sh b/scripts/clippy.sh index e3da4a6c5c..5c0b56eb39 100755 --- a/scripts/clippy.sh +++ b/scripts/clippy.sh @@ -2,7 +2,7 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" cd "$SCRIPT_DIR/.." || exit 1 -RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --release --tests -- -Z macro-backtrace \ +RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --release --tests --examples --benches -- -Z macro-backtrace \ -D clippy::all \ -D clippy::pedantic \ -W clippy::similar_names \ diff --git a/scripts/find_unused_rs_files.sh b/scripts/find_unused_rs_files.sh index 2059b62a28..c442121065 100755 --- a/scripts/find_unused_rs_files.sh +++ b/scripts/find_unused_rs_files.sh @@ -2,7 +2,7 @@ # Script to find .rs files that don't get built. -cargo +nightly build --examples --all-features --tests +cargo +nightly build --examples --all-features --tests --examples --benches # Find all files in deps, then compare to all actual .d files. Ignore a range of files. grep --no-filename '^[^/].*\.rs:$' target/debug/deps/*.d | sed 's/:$//' | sort -u | diff - <(find . -name '*.rs' | sed 's/\.\///' | sort -u) | grep -Ev '(target/|scripts/|symcc_runtime/|build.rs|fuzzers/)' \ No newline at end of file diff --git a/utils/libafl_benches/benches/hash_speeds.rs b/utils/libafl_benches/benches/hash_speeds.rs index 04b73a0dc4..cd04d0f698 100644 --- a/utils/libafl_benches/benches/hash_speeds.rs +++ b/utils/libafl_benches/benches/hash_speeds.rs @@ -15,7 +15,7 @@ fn criterion_benchmark(c: &mut Criterion) { } c.bench_function("xxh3", |b| { - b.iter(|| xxh3::xxh3_64_with_seed(black_box(&bench_vec), 0)) + b.iter(|| xxh3::xxh3_64_with_seed(black_box(&bench_vec), 0)); }); /*c.bench_function("const_xxh3", |b| { b.iter(|| const_xxh3::xxh3_64_with_seed(black_box(&bench_vec), 0)) @@ -24,15 +24,15 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter(|| { let mut hasher = ahash::AHasher::new_with_keys(123, 456); hasher.write(black_box(&bench_vec)); - hasher.finish() - }) + hasher.finish(); + }); }); c.bench_function("fxhash", |b| { b.iter(|| { let mut hasher = rustc_hash::FxHasher::default(); hasher.write(black_box(&bench_vec)); - hasher.finish() - }) + hasher.finish(); + }); }); }