diff --git a/src/corpus/mod.rs b/src/corpus/mod.rs index e6db9fb483..9a1b18681a 100644 --- a/src/corpus/mod.rs +++ b/src/corpus/mod.rs @@ -304,13 +304,10 @@ mod tests { #[test] fn test_queuecorpus() { - let rand = Xoshiro256StarRand::new_rc(); + let rand = Xoshiro256StarRand::new_rr(); let mut q = QueueCorpus::new(OnDiskCorpus::new(&rand, PathBuf::from("fancy/path"))); let i = BytesInput::new(vec![0; 4]); - let t = Rc::new(RefCell::new(Testcase::new_with_filename( - i, - PathBuf::from("fancyfile"), - ))); + let t = Testcase::with_filename_rr(i, PathBuf::from("fancyfile")); q.add(t); let filename = q .get() diff --git a/src/corpus/testcase.rs b/src/corpus/testcase.rs index 52550e135b..9ba2dce787 100644 --- a/src/corpus/testcase.rs +++ b/src/corpus/testcase.rs @@ -2,34 +2,14 @@ use crate::inputs::Input; use crate::AflError; use hashbrown::HashMap; +use std::cell::RefCell; use std::path::PathBuf; +use std::rc::Rc; pub trait TestcaseMetadata { fn name(&self) -> &'static str; } -/* -pub trait TestcaseTrait { - /// Make sure to return a valid input instance loading it from disk if not in memory - fn load_input(&mut self) -> Result<&I, AflError>; - - /// Get the input, if any - fn input(&self) -> &Option; - - /// Get the input, if any (mutable) - fn input_mut(&mut self) -> &mut Option; - - /// Get the filename, if any - fn filename(&self) -> &Option; - - /// Get the filename, if any (mutable) - fn filename_mut(&mut self, filename: PathBuf) -> &mut &Option; - - /// Get all the metadatas into an HashMap - fn metadatas(&mut self) -> &mut HashMap>; -} -*/ - #[derive(Default)] pub struct Testcase where @@ -40,6 +20,8 @@ where metadatas: HashMap<&'static str, Box>, } +pub type TestcaseRef = Rc>>; + impl Testcase where I: Input, @@ -89,7 +71,7 @@ where self.metadatas.insert(meta.name(), meta); } - /// Create a new DefaultTestcase instace given an input + /// Create a new Testcase instace given an input pub fn new(input: I) -> Self { Testcase { input: Some(input), @@ -98,12 +80,22 @@ where } } - /// Create a new DefaultTestcase instace given an input and a filename - pub fn new_with_filename(input: I, filename: PathBuf) -> Self { + /// Create a new Testcase instace given an input and a filename + pub fn with_filename(input: I, filename: PathBuf) -> Self { Testcase { input: Some(input), filename: Some(filename), metadatas: HashMap::default(), } } + + /// Create a new Testcase instace given an input behind a Rc RefCell + pub fn new_rr(input: I) -> Rc> { + Rc::new(RefCell::new(Self::new(input))) + } + + /// Create a new Testcase instace given an input and a filename behind a Rc RefCell + pub fn with_filename_rr(input: I, filename: PathBuf) -> Rc> { + Rc::new(RefCell::new(Self::with_filename(input, filename))) + } } diff --git a/src/engines/mod.rs b/src/engines/mod.rs index 19ce6b7fac..85f1e38edf 100644 --- a/src/engines/mod.rs +++ b/src/engines/mod.rs @@ -20,7 +20,7 @@ where ) -> Result; } -pub trait Engine<'a, I, C, E>: Evaluator +pub trait Engine: Evaluator where I: Input, C: Corpus, @@ -34,11 +34,11 @@ where self.feedbacks_mut().push(feedback); } - fn stages(&self) -> &Vec>>; + fn stages(&self) -> &Vec>>; - fn stages_mut(&mut self) -> &mut Vec>>; + fn stages_mut(&mut self) -> &mut Vec>>; - fn add_stage(&mut self, stage: Box>) { + fn add_stage(&mut self, stage: Box>) { self.stages_mut().push(stage); } @@ -91,19 +91,19 @@ where } } -pub struct DefaultEngine<'a, I, C, E> +pub struct DefaultEngine where I: Input, C: Corpus, E: Executor, { feedbacks: Vec>>, - stages: Vec>>, - executor: &'a mut E, - corpus: &'a mut C, + stages: Vec>>, + executor: E, + corpus: C, } -impl<'a, I, C, E> Evaluator for DefaultEngine<'a, I, C, E> +impl Evaluator for DefaultEngine where I: Input, C: Corpus, @@ -118,7 +118,7 @@ where } } -impl<'a, I, C, E> Engine<'a, I, C, E> for DefaultEngine<'a, I, C, E> +impl Engine for DefaultEngine where I: Input, C: Corpus, @@ -132,38 +132,38 @@ where &mut self.feedbacks } - fn stages(&self) -> &Vec>> { + fn stages(&self) -> &Vec>> { &self.stages } - fn stages_mut(&mut self) -> &mut Vec>> { + fn stages_mut(&mut self) -> &mut Vec>> { &mut self.stages } fn corpus(&self) -> &C { - self.corpus + &self.corpus } fn corpus_mut(&mut self) -> &mut C { - self.corpus + &mut self.corpus } fn executor(&self) -> &E { - self.executor + &self.executor } fn executor_mut(&mut self) -> &mut E { - self.executor + &mut self.executor } } -impl<'a, I, C, E> DefaultEngine<'a, I, C, E> +impl DefaultEngine where I: Input, C: Corpus, E: Executor, { - pub fn new(corpus: &'a mut C, executor: &'a mut E) -> Self { + pub fn new(corpus: C, executor: E) -> Self { DefaultEngine { feedbacks: vec![], stages: vec![], @@ -171,11 +171,15 @@ where executor: executor, } } + + pub fn new_rr(corpus: C, executor: E) -> Rc> { + Rc::new(RefCell::new(Self::new(corpus, executor))) + } } #[cfg(test)] mod tests { - use crate::corpus::InMemoryCorpus; + use crate::corpus::{Corpus, InMemoryCorpus}; use crate::engines::{DefaultEngine, Engine}; use crate::executors::inmemory::InMemoryExecutor; use crate::executors::{Executor, ExitKind}; @@ -192,14 +196,12 @@ mod tests { #[test] fn test_engine() { - let rand = Rc::new(RefCell::new(Xoshiro256StarRand::new())); + let rand = Xoshiro256StarRand::new_rr(); let mut corpus = InMemoryCorpus::::new(&rand); let mut executor = InMemoryExecutor::new(harness); - let mut engine = DefaultEngine::new(&mut corpus, &mut executor); - let stage = Box::new(DefaultMutationalStage::new(&rand, &mut engine)); - engine.add_stage(stage); - engine.fuzz_one().unwrap(); - let stage1 = Box::new(DefaultMutationalStage::new(&rand, &mut engine)); - engine.fuzz_one().unwrap(); + let mut engine = DefaultEngine::new_rr(corpus, executor); + let stage = Box::new(DefaultMutationalStage::new(&rand, &engine)); + engine.borrow_mut().add_stage(stage); + engine.borrow_mut().fuzz_one().unwrap(); } } diff --git a/src/stages/mod.rs b/src/stages/mod.rs index 4b6a71f0ca..43676df6d2 100644 --- a/src/stages/mod.rs +++ b/src/stages/mod.rs @@ -14,12 +14,10 @@ where { type E: Evaluator; - fn eval(&self) -> &Self::E; - - fn eval_mut(&mut self) -> &mut Self::E; + fn eval(&self) -> &Rc>; } -pub trait Stage<'a, I>: HasEvaluator +pub trait Stage: HasEvaluator where I: Input, { diff --git a/src/stages/mutational.rs b/src/stages/mutational.rs index 8bd263f525..ac10b014b3 100644 --- a/src/stages/mutational.rs +++ b/src/stages/mutational.rs @@ -11,7 +11,7 @@ use std::rc::Rc; // TODO create HasMutatorsVec trait -pub trait MutationalStage<'a, I>: Stage<'a, I> + HasRand +pub trait MutationalStage: Stage + HasRand where I: Input, { @@ -36,7 +36,10 @@ where m.mutate(&mut input, i as i32)?; } - let interesting = self.eval_mut().evaluate_input(&mut input, entry.clone())?; + let interesting = self + .eval() + .borrow_mut() + .evaluate_input(&mut input, entry.clone())?; for m in self.mutators_mut() { m.post_exec(interesting, i as i32)?; @@ -48,18 +51,18 @@ where } } -pub struct DefaultMutationalStage<'a, I, R, E> +pub struct DefaultMutationalStage where I: Input, R: Rand, E: Evaluator, { rand: Rc>, - eval: &'a mut E, + eval: Rc>, mutators: Vec>>, } -impl<'a, I, R, E> HasRand for DefaultMutationalStage<'a, I, R, E> +impl HasRand for DefaultMutationalStage where I: Input, R: Rand, @@ -72,7 +75,7 @@ where } } -impl<'a, I, R, E> HasEvaluator for DefaultMutationalStage<'a, I, R, E> +impl HasEvaluator for DefaultMutationalStage where I: Input, R: Rand, @@ -80,16 +83,12 @@ where { type E = E; - fn eval(&self) -> &Self::E { - self.eval - } - - fn eval_mut(&mut self) -> &mut Self::E { - self.eval + fn eval(&self) -> &Rc> { + &self.eval } } -impl<'a, I, R, E> MutationalStage<'a, I> for DefaultMutationalStage<'a, I, R, E> +impl MutationalStage for DefaultMutationalStage where I: Input, R: Rand, @@ -104,7 +103,7 @@ where } } -impl<'a, I, R, E> Stage<'a, I> for DefaultMutationalStage<'a, I, R, E> +impl Stage for DefaultMutationalStage where I: Input, R: Rand, @@ -115,16 +114,16 @@ where } } -impl<'a, I, R, E> DefaultMutationalStage<'a, I, R, E> +impl DefaultMutationalStage where I: Input, R: Rand, E: Evaluator, { - pub fn new(rand: &Rc>, eval: &'a mut E) -> Self { + pub fn new(rand: &Rc>, eval: &Rc>) -> Self { DefaultMutationalStage { rand: Rc::clone(rand), - eval: eval, + eval: Rc::clone(eval), mutators: vec![], } } diff --git a/src/utils.rs b/src/utils.rs index fbfdea27a8..dcfc1891a6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -41,7 +41,7 @@ pub trait Rand: Debug { } } -/// Has a Rand box field +/// Has a Rand Rc RefCell field pub trait HasRand { type R: Rand; @@ -106,13 +106,13 @@ impl Rand for Xoshiro256StarRand { } impl Xoshiro256StarRand { - pub fn new() -> Xoshiro256StarRand { + pub fn new() -> Self { let mut ret: Xoshiro256StarRand = Default::default(); ret.set_seed(0); // TODO: Proper random seed? ret } - pub fn new_rc() -> Rc> { + pub fn new_rr() -> Rc> { Rc::new(RefCell::new(Xoshiro256StarRand::new())) } } @@ -163,7 +163,7 @@ mod tests { } fn test_has_rand() { - let rand = Xoshiro256StarRand::new_rc(); + let rand = Xoshiro256StarRand::new_rr(); let has_rand = HasRandTest { rand: Rc::clone(&rand), };