started reworking Testcases

This commit is contained in:
Dominik Maier 2020-11-15 04:34:03 +01:00
parent 0cb5c33a29
commit 397099f0be
5 changed files with 57 additions and 29 deletions

View File

@ -18,7 +18,7 @@ where
I: Input, I: Input,
{ {
/// Get the entries vector field /// Get the entries vector field
fn entries(&self) -> &Vec<Rc<RefCell<Testcase<I>>>>; fn entries(&self) -> &[Rc<RefCell<Testcase<I>>>];
/// Get the entries vector field (mutable) /// Get the entries vector field (mutable)
fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>>; fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>>;
@ -89,7 +89,7 @@ where
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn entries(&self) -> &Vec<Rc<RefCell<Testcase<I>>>> { fn entries(&self) -> &[Rc<RefCell<Testcase<I>>>] {
&self.entries &self.entries
} }
fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> { fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> {
@ -147,7 +147,7 @@ where
I: Input, I: Input,
R: Rand, R: Rand,
{ {
fn entries(&self) -> &Vec<Rc<RefCell<Testcase<I>>>> { fn entries(&self) -> &[Rc<RefCell<Testcase<I>>>] {
&self.entries &self.entries
} }
fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> { fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> {
@ -220,7 +220,7 @@ where
I: Input, I: Input,
C: Corpus<I>, C: Corpus<I>,
{ {
fn entries(&self) -> &Vec<Rc<RefCell<Testcase<I>>>> { fn entries(&self) -> &[Rc<RefCell<Testcase<I>>>] {
self.corpus.entries() self.corpus.entries()
} }
fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> { fn entries_mut(&mut self) -> &mut Vec<Rc<RefCell<Testcase<I>>>> {

View File

@ -24,23 +24,26 @@ pub trait TestcaseMetadata {
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
} }
/* pub trait TestcaseTraitTODO<I, T>
pub trait Testcase<I, T>
where where
I: Input, I: Input,
T: TestcaseMetadata, T: TestcaseMetadata,
{ {
/// The input associated with this testcase
fn input(&self) -> &Option<I>;
fn input(&mut self) -> Option<I> /// The input associated with this testcase (mutable)
fn input_mut(&mut self) -> &mut Option<I>;
input: Option<I>,
/// Filename, if this testcase is backed by a file in the filesystem /// Filename, if this testcase is backed by a file in the filesystem
filename: Option<String>, fn filename(&self) -> &Option<String>;
/// Map of metadatas associated with this testcase
metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
/// Map of metadatas associated with this testcase
fn metadatas(&self) -> &HashMap<&'static str, Box<dyn TestcaseMetadata>>;
/// Map of metadatas associated with this testcase
fn metadatas_mut(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>>;
} }
*/
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub enum FileBackedTestcase<I, P> { pub enum FileBackedTestcase<I, P> {
@ -49,10 +52,18 @@ pub enum FileBackedTestcase<I, P> {
/// A testcase that has been loaded, and not yet dirtied. /// A testcase that has been loaded, and not yet dirtied.
/// The input should be equal to the on-disk state. /// The input should be equal to the on-disk state.
Loaded { input: I, filename: P }, Loaded {
input: I,
filename: P,
//metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
},
/// A testcase that has been mutated, but not yet written to disk /// A testcase that has been mutated, but not yet written to disk
Dirty { input: I, filename: P }, Dirty {
input: I,
filename: P,
//metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
},
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -69,7 +80,10 @@ where
match self { match self {
Self::Stored { filename } => { Self::Stored { filename } => {
let input = I::from_file(&filename)?; let input = I::from_file(&filename)?;
Ok(Self::Loaded { filename, input }) Ok(Self::Loaded {
filename,
input,
})
} }
Self::Loaded { Self::Loaded {
input: _, input: _,
@ -171,25 +185,18 @@ where
pub fn input_mut(&mut self) -> &mut Option<I> { pub fn input_mut(&mut self) -> &mut Option<I> {
&mut self.input &mut self.input
} }
/// Set the input
pub fn set_input(&mut self, input: Option<I>) {
self.input = input;
}
/// Get the filename, if any /// Get the filename, if any
pub fn filename(&self) -> &Option<String> { pub fn filename(&self) -> &Option<String> {
&self.filename &self.filename
} }
/// Get the filename, if any (mutable) /// Get the filename, if any (mutable)
pub fn filename_mut(&mut self) -> &mut Option<String> { pub fn filename_mut(&mut self) -> &mut Option<String> {
&mut self.filename &mut self.filename
} }
/// Set the filename
pub fn set_filename(&mut self, filename: Option<String>) {
self.filename = filename;
}
/// Get all the metadatas into an HashMap /// Get all the metadatas into an HashMap (mutable)
pub fn metadatas(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>> { pub fn metadatas(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>> {
&mut self.metadatas &mut self.metadatas
} }

View File

@ -1,5 +1,3 @@
extern crate alloc;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -201,13 +199,13 @@ compile_error!("InMemoryExecutor not yet supported on this OS");
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
extern crate alloc; use alloc::boxed::Box;
use crate::executors::inmemory::InMemoryExecutor; use crate::executors::inmemory::InMemoryExecutor;
use crate::executors::{Executor, ExitKind}; use crate::executors::{Executor, ExitKind};
use crate::inputs::Input; use crate::inputs::Input;
use crate::observers::Observer; use crate::observers::Observer;
use crate::AflError; use crate::AflError;
use alloc::boxed::Box;
#[derive(Clone)] #[derive(Clone)]
struct NopInput {} struct NopInput {}
@ -233,7 +231,7 @@ mod tests {
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind { fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind {
println! {"Fake exec with buf of len {}", buf.len()}; println!("Fake exec with buf of len {}", buf.len());
ExitKind::Ok ExitKind::Ok
} }

View File

@ -22,15 +22,24 @@ use std::io;
/// Main error struct for AFL /// Main error struct for AFL
#[derive(Debug)] #[derive(Debug)]
pub enum AflError { pub enum AflError {
/// Serialization error
Serialize(String), Serialize(String),
/// File related error
#[cfg(feature = "std")] #[cfg(feature = "std")]
File(io::Error), File(io::Error),
/// Optional val was supposed to be set, but isn't.
EmptyOptional(String), EmptyOptional(String),
/// Key not in Map
KeyNotFound(String), KeyNotFound(String),
/// No elements in the current item
Empty(String), Empty(String),
/// End of iteration
IteratorEnd(String), IteratorEnd(String),
/// This is not supported (yet)
NotImplemented(String), NotImplemented(String),
/// You're holding it wrong
IllegalState(String), IllegalState(String),
/// Something else happened
Unknown(String), Unknown(String),
} }
@ -53,6 +62,7 @@ impl fmt::Display for AflError {
} }
} }
/// Create an AFL Error from io Error
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl From<io::Error> for AflError { impl From<io::Error> for AflError {
fn from(err: io::Error) -> Self { fn from(err: io::Error) -> Self {

View File

@ -231,6 +231,19 @@ mod tests {
assert!(rand.between(11, 20) > 10); assert!(rand.between(11, 20) > 10);
} }
#[cfg(feature = "std")]
#[test]
fn test_rand_preseeded() {
let mut rand_fixed = DefaultRand::new(0);
let mut rand = DefaultRand::preseeded();
assert_ne!(rand.next(), rand_fixed.next());
assert_ne!(rand.next(), rand.next());
assert!(rand.below(100) < 100);
assert_eq!(rand.below(1), 0);
assert_eq!(rand.between(10, 10), 10);
assert!(rand.between(11, 20) > 10);
}
#[test] #[test]
fn test_has_rand() { fn test_has_rand() {
let rand = DefaultRand::new(0).into(); let rand = DefaultRand::new(0).into();