testcase refcell
This commit is contained in:
parent
2c299a1518
commit
016f2f30a5
@ -4,6 +4,7 @@ pub use testcase::{Testcase, TestcaseMetadata};
|
|||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::cell::RefCell;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -18,10 +19,10 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Get the entries vector field
|
/// Get the entries vector field
|
||||||
fn entries(&self) -> &[Testcase<I>];
|
fn entries(&self) -> &[RefCell<Testcase<I>>];
|
||||||
|
|
||||||
/// Get the entries vector field (mutable)
|
/// Get the entries vector field (mutable)
|
||||||
fn entries_mut(&mut self) -> &mut Vec<Testcase<I>>;
|
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Corpus with all current testcases
|
/// Corpus with all current testcases
|
||||||
@ -37,7 +38,7 @@ where
|
|||||||
|
|
||||||
/// Add an entry to the corpus and return its index
|
/// Add an entry to the corpus and return its index
|
||||||
fn add(&mut self, testcase: Testcase<I>) -> usize {
|
fn add(&mut self, testcase: Testcase<I>) -> usize {
|
||||||
self.entries_mut().push(testcase);
|
self.entries_mut().push(RefCell::new(testcase));
|
||||||
self.entries().len() - 1
|
self.entries().len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,25 +50,25 @@ where
|
|||||||
idx
|
idx
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
self.entries_mut()[idx] = testcase;
|
self.entries_mut()[idx] = RefCell::new(testcase);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get by id
|
/// Get by id
|
||||||
fn get(&self, idx: usize) -> &Testcase<I> {
|
fn get(&self, idx: usize) -> &RefCell<Testcase<I>> {
|
||||||
&self.entries()[idx]
|
&self.entries()[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an entry from the corpus, returning it if it was present.
|
/// Removes an entry from the corpus, returning it if it was present.
|
||||||
fn remove(&mut self, entry: &Testcase<I>) -> Option<Testcase<I>> {
|
fn remove(&mut self, entry: &Testcase<I>) -> Option<Testcase<I>> {
|
||||||
match self.entries().iter().position(|x| ptr::eq(x, entry)) {
|
match self.entries().iter().position(|x| ptr::eq(x.as_ptr(), entry)) {
|
||||||
Some(i) => Some(self.entries_mut().remove(i)),
|
Some(i) => Some(self.entries_mut().remove(i).into_inner()),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random entry
|
/// Gets a random entry
|
||||||
fn random_entry(&self, rand: &mut R) -> Result<(&Testcase<I>, usize), AflError> {
|
fn random_entry(&self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
|
||||||
if self.count() == 0 {
|
if self.count() == 0 {
|
||||||
Err(AflError::Empty("No entries in corpus".to_owned()))
|
Err(AflError::Empty("No entries in corpus".to_owned()))
|
||||||
} else {
|
} else {
|
||||||
@ -78,7 +79,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the testcase for the given idx, with loaded input
|
/// Returns the testcase for the given idx, with loaded input
|
||||||
fn load_testcase(&mut self, idx: usize) -> Result<(), AflError> {
|
/*fn load_testcase(&mut self, idx: usize) -> Result<(), AflError> {
|
||||||
let testcase = self.get(idx);
|
let testcase = self.get(idx);
|
||||||
// Ensure testcase is loaded
|
// Ensure testcase is loaded
|
||||||
match testcase.input() {
|
match testcase.input() {
|
||||||
@ -97,14 +98,14 @@ where
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// TODO: IntoIter
|
// TODO: IntoIter
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&mut self, rand: &mut R) -> Result<(&Testcase<I>, usize), AflError>;
|
fn next(&mut self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError>;
|
||||||
|
|
||||||
/// Returns the testacase we currently use
|
/// Returns the testacase we currently use
|
||||||
fn current_testcase(&self) -> (&Testcase<I>, usize);
|
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InMemoryCorpus<I, R>
|
pub struct InMemoryCorpus<I, R>
|
||||||
@ -112,7 +113,7 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
entries: Vec<Testcase<I>>,
|
entries: Vec<RefCell<Testcase<I>>>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
phantom: PhantomData<R>,
|
phantom: PhantomData<R>,
|
||||||
}
|
}
|
||||||
@ -122,10 +123,10 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn entries(&self) -> &[Testcase<I>] {
|
fn entries(&self) -> &[RefCell<Testcase<I>>] {
|
||||||
&self.entries
|
&self.entries
|
||||||
}
|
}
|
||||||
fn entries_mut(&mut self) -> &mut Vec<Testcase<I>> {
|
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>> {
|
||||||
&mut self.entries
|
&mut self.entries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +137,7 @@ where
|
|||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&mut self, rand: &mut R) -> Result<(&Testcase<I>, usize), AflError> {
|
fn next(&mut self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
|
||||||
if self.count() == 0 {
|
if self.count() == 0 {
|
||||||
Err(AflError::Empty("No entries in corpus".to_owned()))
|
Err(AflError::Empty("No entries in corpus".to_owned()))
|
||||||
} else {
|
} else {
|
||||||
@ -148,7 +149,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the testacase we currently use
|
/// Returns the testacase we currently use
|
||||||
fn current_testcase(&self) -> (&Testcase<I>, usize) {
|
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
|
||||||
(self.get(self.pos), self.pos)
|
(self.get(self.pos), self.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +174,7 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
entries: Vec<Testcase<I>>,
|
entries: Vec<RefCell<Testcase<I>>>,
|
||||||
dir_path: PathBuf,
|
dir_path: PathBuf,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
phantom: PhantomData<R>,
|
phantom: PhantomData<R>,
|
||||||
@ -185,10 +186,10 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn entries(&self) -> &[Testcase<I>] {
|
fn entries(&self) -> &[RefCell<Testcase<I>>] {
|
||||||
&self.entries
|
&self.entries
|
||||||
}
|
}
|
||||||
fn entries_mut(&mut self) -> &mut Vec<Testcase<I>> {
|
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>> {
|
||||||
&mut self.entries
|
&mut self.entries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,16 +211,16 @@ where
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
self.entries.push(entry);
|
self.entries.push(RefCell::new(entry));
|
||||||
self.entries.len() - 1
|
self.entries.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_testcase(&self) -> (&Testcase<I>, usize) {
|
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
|
||||||
(self.get(self.pos), self.pos)
|
(self.get(self.pos), self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&mut self, rand: &mut R) -> Result<(&Testcase<I>, usize), AflError> {
|
fn next(&mut self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
|
||||||
if self.count() == 0 {
|
if self.count() == 0 {
|
||||||
Err(AflError::Empty("No entries in corpus".to_owned()))
|
Err(AflError::Empty("No entries in corpus".to_owned()))
|
||||||
} else {
|
} else {
|
||||||
@ -268,10 +269,10 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
fn entries(&self) -> &[Testcase<I>] {
|
fn entries(&self) -> &[RefCell<Testcase<I>>] {
|
||||||
self.corpus.entries()
|
self.corpus.entries()
|
||||||
}
|
}
|
||||||
fn entries_mut(&mut self) -> &mut Vec<Testcase<I>> {
|
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>> {
|
||||||
self.corpus.entries_mut()
|
self.corpus.entries_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,17 +298,17 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random entry
|
/// Gets a random entry
|
||||||
fn random_entry(&self, rand: &mut R) -> Result<(&Testcase<I>, usize), AflError> {
|
fn random_entry(&self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
|
||||||
self.corpus.random_entry(rand)
|
self.corpus.random_entry(rand)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the testacase we currently use
|
/// Returns the testacase we currently use
|
||||||
fn current_testcase(&self) -> (&Testcase<I>, usize) {
|
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
|
||||||
(self.get(self.pos - 1), self.pos - 1)
|
(self.get(self.pos - 1), self.pos - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the next entry
|
/// Gets the next entry
|
||||||
fn next(&mut self, _rand: &mut R) -> Result<(&Testcase<I>, usize), AflError> {
|
fn next(&mut self, _rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
if self.corpus.count() == 0 {
|
if self.corpus.count() == 0 {
|
||||||
return Err(AflError::Empty("Corpus".to_owned()));
|
return Err(AflError::Empty("Corpus".to_owned()));
|
||||||
@ -417,6 +418,7 @@ mod tests {
|
|||||||
.next(&mut rand)
|
.next(&mut rand)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
|
.borrow()
|
||||||
.filename()
|
.filename()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -426,6 +428,7 @@ mod tests {
|
|||||||
q.next(&mut rand)
|
q.next(&mut rand)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
|
.borrow()
|
||||||
.filename()
|
.filename()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -75,9 +75,11 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// Returns this testcase with a loaded input
|
/// Returns this testcase with a loaded input
|
||||||
pub fn load_from_disk(filename: &str) -> Result<Self, AflError> {
|
pub fn load_input(&mut self) -> Result<&I, AflError> {
|
||||||
let input = I::from_file(filename)?;
|
if self.input.is_none() {
|
||||||
Ok(Testcase::new(input))
|
self.input = Some(I::from_file(self.filename.as_ref().unwrap())?);
|
||||||
|
}
|
||||||
|
Ok(self.input.as_ref().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the input, if any
|
/// Get the input, if any
|
||||||
|
@ -293,19 +293,10 @@ where
|
|||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<EM, E, C, I, R>,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
) -> Result<usize, AflError> {
|
) -> Result<usize, AflError> {
|
||||||
let (testcase, idx) = corpus.next(rand)?;
|
let (_, idx) = corpus.next(rand)?;
|
||||||
match testcase.input() {
|
|
||||||
None => {
|
|
||||||
// Load from disk.
|
|
||||||
corpus.load_testcase(idx)?;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = corpus.get(idx).input().as_ref().unwrap();
|
|
||||||
|
|
||||||
for stage in self.stages_mut() {
|
for stage in self.stages_mut() {
|
||||||
stage.perform(rand, state, corpus, engine, &input)?;
|
stage.perform(rand, state, corpus, engine, idx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.events_manager_mut().process(state, corpus)?;
|
engine.events_manager_mut().process(state, corpus)?;
|
||||||
|
@ -4,7 +4,6 @@ use core::ptr;
|
|||||||
use crate::executors::{Executor, ExitKind};
|
use crate::executors::{Executor, ExitKind};
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
use crate::observers::observer_serde::NamedSerdeAnyMap;
|
||||||
use crate::observers::Observer;
|
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||||
|
@ -686,13 +686,13 @@ where
|
|||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
// We don't want to use the testcase we're already using for splicing
|
// We don't want to use the testcase we're already using for splicing
|
||||||
let (other_testcase, _) = corpus.random_entry(rand)?.clone();
|
let (other_testcase, idx) = corpus.random_entry(rand)?;
|
||||||
// TODO: Load let other = Testcase::load_from_disk(other_test)?;
|
if idx == corpus.current_testcase().1 {
|
||||||
|
return Ok(MutationResult::Skipped);
|
||||||
|
}
|
||||||
// println!("Input: {:?}, other input: {:?}", input.bytes(), other.bytes());
|
// println!("Input: {:?}, other input: {:?}", input.bytes(), other.bytes());
|
||||||
let other = match other_testcase.input() {
|
let mut other_ref = other_testcase.borrow_mut();
|
||||||
Some(i) => i,
|
let other = other_ref.load_input()?;
|
||||||
None => return Ok(MutationResult::Skipped), //TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let (first_diff, last_diff) = loop {
|
let (first_diff, last_diff) = loop {
|
||||||
|
@ -265,7 +265,7 @@ mod tests {
|
|||||||
let (testcase, _) = corpus
|
let (testcase, _) = corpus
|
||||||
.next(&mut rand)
|
.next(&mut rand)
|
||||||
.expect("Corpus did not contain entries");
|
.expect("Corpus did not contain entries");
|
||||||
let mut input = testcase.input().as_ref().unwrap().clone();
|
let mut input = testcase.borrow_mut().load_input().unwrap().clone();
|
||||||
|
|
||||||
rand.set_seed(5);
|
rand.set_seed(5);
|
||||||
let mut mutator = StdScheduledMutator::new();
|
let mut mutator = StdScheduledMutator::new();
|
||||||
|
@ -24,6 +24,6 @@ where
|
|||||||
state: &mut State<I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<EM, E, C, I, R>,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError>;
|
) -> Result<(), AflError>;
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,11 @@ where
|
|||||||
state: &mut State<I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<EM, E, C, I, R>,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
let num = self.iterations(rand);
|
let num = self.iterations(rand);
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
let mut input_mut = input.clone();
|
let mut input_mut = corpus.get(corpus_idx).borrow_mut().load_input()?.clone();
|
||||||
self.mutator_mut()
|
self.mutator_mut()
|
||||||
.mutate(rand, corpus, &mut input_mut, i as i32)?;
|
.mutate(rand, corpus, &mut input_mut, i as i32)?;
|
||||||
|
|
||||||
@ -120,9 +120,9 @@ where
|
|||||||
state: &mut State<I, R>,
|
state: &mut State<I, R>,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
engine: &mut Engine<EM, E, C, I, R>,
|
engine: &mut Engine<EM, E, C, I, R>,
|
||||||
input: &I,
|
corpus_idx: usize,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
self.perform_mutational(rand, state, corpus, engine, input)
|
self.perform_mutational(rand, state, corpus, engine, corpus_idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user