refcell stage
This commit is contained in:
parent
bf1c1f4057
commit
850c49258e
@ -304,13 +304,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
|
|
||||||
fn test_queuecorpus() {
|
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 mut q = QueueCorpus::new(OnDiskCorpus::new(&rand, PathBuf::from("fancy/path")));
|
||||||
let i = BytesInput::new(vec![0; 4]);
|
let i = BytesInput::new(vec![0; 4]);
|
||||||
let t = Rc::new(RefCell::new(Testcase::new_with_filename(
|
let t = Testcase::with_filename_rr(i, PathBuf::from("fancyfile"));
|
||||||
i,
|
|
||||||
PathBuf::from("fancyfile"),
|
|
||||||
)));
|
|
||||||
q.add(t);
|
q.add(t);
|
||||||
let filename = q
|
let filename = q
|
||||||
.get()
|
.get()
|
||||||
|
@ -2,34 +2,14 @@ use crate::inputs::Input;
|
|||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub trait TestcaseMetadata {
|
pub trait TestcaseMetadata {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub trait TestcaseTrait<I: Input> {
|
|
||||||
/// 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<I>;
|
|
||||||
|
|
||||||
/// Get the input, if any (mutable)
|
|
||||||
fn input_mut(&mut self) -> &mut Option<I>;
|
|
||||||
|
|
||||||
/// Get the filename, if any
|
|
||||||
fn filename(&self) -> &Option<PathBuf>;
|
|
||||||
|
|
||||||
/// Get the filename, if any (mutable)
|
|
||||||
fn filename_mut(&mut self, filename: PathBuf) -> &mut &Option<PathBuf>;
|
|
||||||
|
|
||||||
/// Get all the metadatas into an HashMap
|
|
||||||
fn metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>>;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Testcase<I>
|
pub struct Testcase<I>
|
||||||
where
|
where
|
||||||
@ -40,6 +20,8 @@ where
|
|||||||
metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type TestcaseRef<I> = Rc<RefCell<Testcase<I>>>;
|
||||||
|
|
||||||
impl<I> Testcase<I>
|
impl<I> Testcase<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -89,7 +71,7 @@ where
|
|||||||
self.metadatas.insert(meta.name(), meta);
|
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 {
|
pub fn new(input: I) -> Self {
|
||||||
Testcase {
|
Testcase {
|
||||||
input: Some(input),
|
input: Some(input),
|
||||||
@ -98,12 +80,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new DefaultTestcase instace given an input and a filename
|
/// Create a new Testcase instace given an input and a filename
|
||||||
pub fn new_with_filename(input: I, filename: PathBuf) -> Self {
|
pub fn with_filename(input: I, filename: PathBuf) -> Self {
|
||||||
Testcase {
|
Testcase {
|
||||||
input: Some(input),
|
input: Some(input),
|
||||||
filename: Some(filename),
|
filename: Some(filename),
|
||||||
metadatas: HashMap::default(),
|
metadatas: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new Testcase instace given an input behind a Rc RefCell
|
||||||
|
pub fn new_rr(input: I) -> Rc<RefCell<Self>> {
|
||||||
|
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<RefCell<Self>> {
|
||||||
|
Rc::new(RefCell::new(Self::with_filename(input, filename)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ where
|
|||||||
) -> Result<bool, AflError>;
|
) -> Result<bool, AflError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Engine<'a, I, C, E>: Evaluator<I>
|
pub trait Engine<I, C, E>: Evaluator<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -34,11 +34,11 @@ where
|
|||||||
self.feedbacks_mut().push(feedback);
|
self.feedbacks_mut().push(feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages(&self) -> &Vec<Box<dyn Stage<'a, I, E = Self>>>;
|
fn stages(&self) -> &Vec<Box<dyn Stage<I, E = Self>>>;
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<'a, I, E = Self>>>;
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<I, E = Self>>>;
|
||||||
|
|
||||||
fn add_stage(&mut self, stage: Box<dyn Stage<'a, I, E = Self>>) {
|
fn add_stage(&mut self, stage: Box<dyn Stage<I, E = Self>>) {
|
||||||
self.stages_mut().push(stage);
|
self.stages_mut().push(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,19 +91,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultEngine<'a, I, C, E>
|
pub struct DefaultEngine<I, C, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
feedbacks: Vec<Box<dyn Feedback<I>>>,
|
||||||
stages: Vec<Box<dyn Stage<'a, I, E = Self>>>,
|
stages: Vec<Box<dyn Stage<I, E = Self>>>,
|
||||||
executor: &'a mut E,
|
executor: E,
|
||||||
corpus: &'a mut C,
|
corpus: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, C, E> Evaluator<I> for DefaultEngine<'a, I, C, E>
|
impl<I, C, E> Evaluator<I> for DefaultEngine<I, C, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -118,7 +118,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, C, E> Engine<'a, I, C, E> for DefaultEngine<'a, I, C, E>
|
impl<I, C, E> Engine<I, C, E> for DefaultEngine<I, C, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
@ -132,38 +132,38 @@ where
|
|||||||
&mut self.feedbacks
|
&mut self.feedbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages(&self) -> &Vec<Box<dyn Stage<'a, I, E = Self>>> {
|
fn stages(&self) -> &Vec<Box<dyn Stage<I, E = Self>>> {
|
||||||
&self.stages
|
&self.stages
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<'a, I, E = Self>>> {
|
fn stages_mut(&mut self) -> &mut Vec<Box<dyn Stage<I, E = Self>>> {
|
||||||
&mut self.stages
|
&mut self.stages
|
||||||
}
|
}
|
||||||
|
|
||||||
fn corpus(&self) -> &C {
|
fn corpus(&self) -> &C {
|
||||||
self.corpus
|
&self.corpus
|
||||||
}
|
}
|
||||||
|
|
||||||
fn corpus_mut(&mut self) -> &mut C {
|
fn corpus_mut(&mut self) -> &mut C {
|
||||||
self.corpus
|
&mut self.corpus
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executor(&self) -> &E {
|
fn executor(&self) -> &E {
|
||||||
self.executor
|
&self.executor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executor_mut(&mut self) -> &mut E {
|
fn executor_mut(&mut self) -> &mut E {
|
||||||
self.executor
|
&mut self.executor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, C, E> DefaultEngine<'a, I, C, E>
|
impl<I, C, E> DefaultEngine<I, C, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
E: Executor<I>,
|
E: Executor<I>,
|
||||||
{
|
{
|
||||||
pub fn new(corpus: &'a mut C, executor: &'a mut E) -> Self {
|
pub fn new(corpus: C, executor: E) -> Self {
|
||||||
DefaultEngine {
|
DefaultEngine {
|
||||||
feedbacks: vec![],
|
feedbacks: vec![],
|
||||||
stages: vec![],
|
stages: vec![],
|
||||||
@ -171,11 +171,15 @@ where
|
|||||||
executor: executor,
|
executor: executor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_rr(corpus: C, executor: E) -> Rc<RefCell<Self>> {
|
||||||
|
Rc::new(RefCell::new(Self::new(corpus, executor)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::corpus::InMemoryCorpus;
|
use crate::corpus::{Corpus, InMemoryCorpus};
|
||||||
use crate::engines::{DefaultEngine, Engine};
|
use crate::engines::{DefaultEngine, Engine};
|
||||||
use crate::executors::inmemory::InMemoryExecutor;
|
use crate::executors::inmemory::InMemoryExecutor;
|
||||||
use crate::executors::{Executor, ExitKind};
|
use crate::executors::{Executor, ExitKind};
|
||||||
@ -192,14 +196,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_engine() {
|
fn test_engine() {
|
||||||
let rand = Rc::new(RefCell::new(Xoshiro256StarRand::new()));
|
let rand = Xoshiro256StarRand::new_rr();
|
||||||
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
|
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
|
||||||
let mut executor = InMemoryExecutor::new(harness);
|
let mut executor = InMemoryExecutor::new(harness);
|
||||||
let mut engine = DefaultEngine::new(&mut corpus, &mut executor);
|
let mut engine = DefaultEngine::new_rr(corpus, executor);
|
||||||
let stage = Box::new(DefaultMutationalStage::new(&rand, &mut engine));
|
let stage = Box::new(DefaultMutationalStage::new(&rand, &engine));
|
||||||
engine.add_stage(stage);
|
engine.borrow_mut().add_stage(stage);
|
||||||
engine.fuzz_one().unwrap();
|
engine.borrow_mut().fuzz_one().unwrap();
|
||||||
let stage1 = Box::new(DefaultMutationalStage::new(&rand, &mut engine));
|
|
||||||
engine.fuzz_one().unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,10 @@ where
|
|||||||
{
|
{
|
||||||
type E: Evaluator<I>;
|
type E: Evaluator<I>;
|
||||||
|
|
||||||
fn eval(&self) -> &Self::E;
|
fn eval(&self) -> &Rc<RefCell<Self::E>>;
|
||||||
|
|
||||||
fn eval_mut(&mut self) -> &mut Self::E;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Stage<'a, I>: HasEvaluator<I>
|
pub trait Stage<I>: HasEvaluator<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
// TODO create HasMutatorsVec trait
|
// TODO create HasMutatorsVec trait
|
||||||
|
|
||||||
pub trait MutationalStage<'a, I>: Stage<'a, I> + HasRand
|
pub trait MutationalStage<I>: Stage<I> + HasRand
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
@ -36,7 +36,10 @@ where
|
|||||||
m.mutate(&mut input, i as i32)?;
|
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() {
|
for m in self.mutators_mut() {
|
||||||
m.post_exec(interesting, i as i32)?;
|
m.post_exec(interesting, i as i32)?;
|
||||||
@ -48,18 +51,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultMutationalStage<'a, I, R, E>
|
pub struct DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Evaluator<I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
rand: Rc<RefCell<R>>,
|
rand: Rc<RefCell<R>>,
|
||||||
eval: &'a mut E,
|
eval: Rc<RefCell<E>>,
|
||||||
mutators: Vec<Box<dyn Mutator<I, R = R>>>,
|
mutators: Vec<Box<dyn Mutator<I, R = R>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R, E> HasRand for DefaultMutationalStage<'a, I, R, E>
|
impl<I, R, E> HasRand for DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -72,7 +75,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R, E> HasEvaluator<I> for DefaultMutationalStage<'a, I, R, E>
|
impl<I, R, E> HasEvaluator<I> for DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -80,16 +83,12 @@ where
|
|||||||
{
|
{
|
||||||
type E = E;
|
type E = E;
|
||||||
|
|
||||||
fn eval(&self) -> &Self::E {
|
fn eval(&self) -> &Rc<RefCell<Self::E>> {
|
||||||
self.eval
|
&self.eval
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_mut(&mut self) -> &mut Self::E {
|
|
||||||
self.eval
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R, E> MutationalStage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
impl<I, R, E> MutationalStage<I> for DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -104,7 +103,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R, E> Stage<'a, I> for DefaultMutationalStage<'a, I, R, E>
|
impl<I, R, E> Stage<I> for DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
@ -115,16 +114,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, R, E> DefaultMutationalStage<'a, I, R, E>
|
impl<I, R, E> DefaultMutationalStage<I, R, E>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
E: Evaluator<I>,
|
E: Evaluator<I>,
|
||||||
{
|
{
|
||||||
pub fn new(rand: &Rc<RefCell<R>>, eval: &'a mut E) -> Self {
|
pub fn new(rand: &Rc<RefCell<R>>, eval: &Rc<RefCell<E>>) -> Self {
|
||||||
DefaultMutationalStage {
|
DefaultMutationalStage {
|
||||||
rand: Rc::clone(rand),
|
rand: Rc::clone(rand),
|
||||||
eval: eval,
|
eval: Rc::clone(eval),
|
||||||
mutators: vec![],
|
mutators: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ pub trait Rand: Debug {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has a Rand box field
|
/// Has a Rand Rc RefCell field
|
||||||
pub trait HasRand {
|
pub trait HasRand {
|
||||||
type R: Rand;
|
type R: Rand;
|
||||||
|
|
||||||
@ -106,13 +106,13 @@ impl Rand for Xoshiro256StarRand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Xoshiro256StarRand {
|
impl Xoshiro256StarRand {
|
||||||
pub fn new() -> Xoshiro256StarRand {
|
pub fn new() -> Self {
|
||||||
let mut ret: Xoshiro256StarRand = Default::default();
|
let mut ret: Xoshiro256StarRand = Default::default();
|
||||||
ret.set_seed(0); // TODO: Proper random seed?
|
ret.set_seed(0); // TODO: Proper random seed?
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_rc() -> Rc<RefCell<Xoshiro256StarRand>> {
|
pub fn new_rr() -> Rc<RefCell<Self>> {
|
||||||
Rc::new(RefCell::new(Xoshiro256StarRand::new()))
|
Rc::new(RefCell::new(Xoshiro256StarRand::new()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_has_rand() {
|
fn test_has_rand() {
|
||||||
let rand = Xoshiro256StarRand::new_rc();
|
let rand = Xoshiro256StarRand::new_rr();
|
||||||
let has_rand = HasRandTest {
|
let has_rand = HasRandTest {
|
||||||
rand: Rc::clone(&rand),
|
rand: Rc::clone(&rand),
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user