fixed splicing mutator
This commit is contained in:
parent
47ca9e3f6b
commit
d0f2507ab4
@ -38,6 +38,11 @@ where
|
|||||||
self.entries_mut().push(entry);
|
self.entries_mut().push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an input to the corpus
|
||||||
|
fn add_input(&mut self, input: I) {
|
||||||
|
self.add(Testcase::new_rr(input));
|
||||||
|
}
|
||||||
|
|
||||||
/// 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<Rc<RefCell<Testcase<I>>>> {
|
fn remove(&mut self, entry: &Testcase<I>) -> Option<Rc<RefCell<Testcase<I>>>> {
|
||||||
let mut i: usize = 0;
|
let mut i: usize = 0;
|
||||||
|
@ -162,7 +162,7 @@ pub fn mutation_bitflip<C, M, I>(
|
|||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
M: Mutator<C, I>,
|
M: HasRand,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
{
|
{
|
||||||
let bit = mutator.rand_below(input.bytes().len() as u64) as usize;
|
let bit = mutator.rand_below(input.bytes().len() as u64) as usize;
|
||||||
@ -194,10 +194,28 @@ pub fn mutation_splice<C, M, I>(
|
|||||||
) -> Result<(), AflError>
|
) -> Result<(), AflError>
|
||||||
where
|
where
|
||||||
C: Corpus<I>,
|
C: Corpus<I>,
|
||||||
M: Mutator<C, I>,
|
M: HasRand,
|
||||||
I: Input + HasBytesVec,
|
I: Input + HasBytesVec,
|
||||||
{
|
{
|
||||||
let other_rr = corpus.random_entry()?;
|
let mut retry_count = 0;
|
||||||
|
// We don't want to use the testcase we're already using for splicing
|
||||||
|
let other_rr = loop {
|
||||||
|
let mut found = false;
|
||||||
|
let other_rr = corpus.random_entry()?.clone();
|
||||||
|
match other_rr.try_borrow_mut() {
|
||||||
|
Ok(_) => found = true,
|
||||||
|
Err(_) => {
|
||||||
|
if retry_count == 20 {
|
||||||
|
return Err(AflError::Empty("No suitable testcase found for splicing".to_owned()));
|
||||||
|
}
|
||||||
|
retry_count += 1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if found {
|
||||||
|
break other_rr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// This should work now, as we successfully try_borrow_mut'd before.
|
||||||
let mut other_testcase = other_rr.borrow_mut();
|
let mut other_testcase = other_rr.borrow_mut();
|
||||||
let other = other_testcase.load_input()?;
|
let other = other_testcase.load_input()?;
|
||||||
|
|
||||||
@ -215,11 +233,12 @@ where
|
|||||||
|
|
||||||
let split_at = mutator.rand_between(first_diff as u64, last_diff as u64) as usize;
|
let split_at = mutator.rand_between(first_diff as u64, last_diff as u64) as usize;
|
||||||
|
|
||||||
Err(AflError::NotImplemented(format!("TODO: fix Splice (would split at {})", split_at)))
|
let _: Vec<_> = input
|
||||||
|
.bytes_mut()
|
||||||
|
.splice(split_at.., other.bytes()[split_at..].iter().cloned())
|
||||||
|
.collect();
|
||||||
|
|
||||||
//input.bytes_mut().splice(split_at.., other.bytes()[split_at..]).collect();
|
Ok(())
|
||||||
|
|
||||||
//Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
/// Schedule some selected byte level mutations given a ScheduledMutator type
|
||||||
@ -292,3 +311,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use crate::corpus::{Corpus, InMemoryCorpus};
|
||||||
|
use crate::inputs::BytesInput;
|
||||||
|
use crate::mutators::scheduled::mutation_splice;
|
||||||
|
use crate::utils::{Xoshiro256StarRand, DefaultHasRand};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mut_splice() {
|
||||||
|
let rand = &Xoshiro256StarRand::new_rr(0);
|
||||||
|
let mut has_rand = DefaultHasRand::new(&rand);
|
||||||
|
let mut corpus = InMemoryCorpus::new(&rand);
|
||||||
|
corpus.add_input(BytesInput::new(vec!['a' as u8, 'b' as u8, 'c' as u8]));
|
||||||
|
corpus.add_input(BytesInput::new(vec!['d' as u8, 'e' as u8, 'f' as u8]));
|
||||||
|
|
||||||
|
let testcase_rr = corpus.next().expect("Corpus did not contain entries");
|
||||||
|
let mut testcase = testcase_rr.borrow_mut();
|
||||||
|
let mut input = testcase.load_input().expect("No input in testcase").clone();
|
||||||
|
|
||||||
|
mutation_splice(&mut has_rand, &mut corpus, &mut input).unwrap()
|
||||||
|
|
||||||
|
// TODO: Finish testcase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
60
src/utils.rs
60
src/utils.rs
@ -136,6 +136,40 @@ impl Xoshiro256StarRand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A very basic HasRand
|
||||||
|
pub struct DefaultHasRand<R>
|
||||||
|
where
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
rand: Rc<RefCell<R>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A very basic HasRand
|
||||||
|
impl<R> HasRand for DefaultHasRand<R>
|
||||||
|
where
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
type R = R;
|
||||||
|
|
||||||
|
/// Get the rand rc refcell
|
||||||
|
fn rand(&self) -> &Rc<RefCell<R>> {
|
||||||
|
&self.rand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A very basic HasRand
|
||||||
|
impl<R> DefaultHasRand<R>
|
||||||
|
where
|
||||||
|
R: Rand,
|
||||||
|
{
|
||||||
|
/// Create a new DefaultHasRand, cloning the refcell
|
||||||
|
pub fn new(rand: &Rc<RefCell<R>>) -> Self {
|
||||||
|
Self {
|
||||||
|
rand: Rc::clone(rand),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the next higher power of two
|
/// Get the next higher power of two
|
||||||
pub fn next_pow2(val: u64) -> u64 {
|
pub fn next_pow2(val: u64) -> u64 {
|
||||||
let mut out = val.wrapping_sub(1);
|
let mut out = val.wrapping_sub(1);
|
||||||
@ -149,7 +183,7 @@ pub fn next_pow2(val: u64) -> u64 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::utils::{next_pow2, HasRand, Rand, Xoshiro256StarRand};
|
use crate::utils::{next_pow2, DefaultHasRand, HasRand, Rand, Xoshiro256StarRand};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rand() {
|
fn test_rand() {
|
||||||
@ -161,32 +195,10 @@ mod tests {
|
|||||||
assert!(rand.between(11, 20) > 10);
|
assert!(rand.between(11, 20) > 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
|
||||||
use core::cell::RefCell;
|
|
||||||
struct HasRandTest<R>
|
|
||||||
where
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
rand: Rc<RefCell<R>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> HasRand for HasRandTest<R>
|
|
||||||
where
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
type R = R;
|
|
||||||
|
|
||||||
fn rand(&self) -> &Rc<RefCell<R>> {
|
|
||||||
&self.rand
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_has_rand() {
|
fn test_has_rand() {
|
||||||
let rand = Xoshiro256StarRand::preseeded_rr();
|
let rand = Xoshiro256StarRand::preseeded_rr();
|
||||||
let has_rand = HasRandTest {
|
let has_rand = DefaultHasRand::new(&rand);
|
||||||
rand: Rc::clone(&rand),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(has_rand.rand_below(100) < 100);
|
assert!(has_rand.rand_below(100) < 100);
|
||||||
assert_eq!(has_rand.rand_below(1), 0);
|
assert_eq!(has_rand.rand_below(1), 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user