fixed splicing mutator
This commit is contained in:
parent
47ca9e3f6b
commit
d0f2507ab4
@ -38,6 +38,11 @@ where
|
||||
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.
|
||||
fn remove(&mut self, entry: &Testcase<I>) -> Option<Rc<RefCell<Testcase<I>>>> {
|
||||
let mut i: usize = 0;
|
||||
|
@ -162,7 +162,7 @@ pub fn mutation_bitflip<C, M, I>(
|
||||
) -> Result<(), AflError>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
M: Mutator<C, I>,
|
||||
M: HasRand,
|
||||
I: Input + HasBytesVec,
|
||||
{
|
||||
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>
|
||||
where
|
||||
C: Corpus<I>,
|
||||
M: Mutator<C, I>,
|
||||
M: HasRand,
|
||||
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 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;
|
||||
|
||||
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
|
||||
@ -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
|
||||
pub fn next_pow2(val: u64) -> u64 {
|
||||
let mut out = val.wrapping_sub(1);
|
||||
@ -149,7 +183,7 @@ pub fn next_pow2(val: u64) -> u64 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::{next_pow2, HasRand, Rand, Xoshiro256StarRand};
|
||||
use crate::utils::{next_pow2, DefaultHasRand, HasRand, Rand, Xoshiro256StarRand};
|
||||
|
||||
#[test]
|
||||
fn test_rand() {
|
||||
@ -161,32 +195,10 @@ mod tests {
|
||||
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]
|
||||
fn test_has_rand() {
|
||||
let rand = Xoshiro256StarRand::preseeded_rr();
|
||||
let has_rand = HasRandTest {
|
||||
rand: Rc::clone(&rand),
|
||||
};
|
||||
let has_rand = DefaultHasRand::new(&rand);
|
||||
|
||||
assert!(has_rand.rand_below(100) < 100);
|
||||
assert_eq!(has_rand.rand_below(1), 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user