Rename ResizableMutator, make it generic (#2859)
* Rename ResizableMutator, make it generic * fix * more fix * reorer * fmt, fixes * fixes * more commit * fmt
This commit is contained in:
parent
2a36b78fd6
commit
a949452453
@ -11,7 +11,7 @@ use core::cell::RefCell;
|
||||
use libafl_bolts::{ownedref::OwnedSlice, HasLen};
|
||||
|
||||
use super::ValueInput;
|
||||
use crate::inputs::{HasMutatorBytes, HasMutatorResizableBytes, HasTargetBytes};
|
||||
use crate::inputs::{HasMutatorBytes, HasTargetBytes, ResizableMutator};
|
||||
|
||||
/// A bytes input is the basic input
|
||||
pub type BytesInput = ValueInput<Vec<u8>>;
|
||||
@ -24,16 +24,16 @@ impl From<BytesInput> for Rc<RefCell<BytesInput>> {
|
||||
}
|
||||
|
||||
impl HasMutatorBytes for BytesInput {
|
||||
fn bytes(&self) -> &[u8] {
|
||||
fn mutator_bytes(&self) -> &[u8] {
|
||||
self.as_ref()
|
||||
}
|
||||
|
||||
fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn mutator_bytes_mut(&mut self) -> &mut [u8] {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl HasMutatorResizableBytes for BytesInput {
|
||||
impl ResizableMutator<u8> for BytesInput {
|
||||
fn resize(&mut self, new_len: usize, value: u8) {
|
||||
self.as_mut().resize(new_len, value);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use libafl_bolts::{
|
||||
HasLen,
|
||||
};
|
||||
|
||||
use crate::inputs::{HasMutatorBytes, HasMutatorResizableBytes};
|
||||
use crate::inputs::{HasMutatorBytes, ResizableMutator};
|
||||
|
||||
/// The [`BytesSubInput`] makes it possible to use [`crate::mutators::Mutator`]`s` that work on
|
||||
/// inputs implementing the [`HasMutatorBytes`] for a sub-range of this input.
|
||||
@ -31,13 +31,13 @@ use crate::inputs::{HasMutatorBytes, HasMutatorResizableBytes};
|
||||
/// let mut sub_input = bytes_input.sub_input(1..);
|
||||
///
|
||||
/// // Run any mutations on the sub input.
|
||||
/// sub_input.bytes_mut()[0] = 42;
|
||||
/// sub_input.mutator_bytes_mut()[0] = 42;
|
||||
///
|
||||
/// // The mutations are applied to the underlying input.
|
||||
/// assert_eq!(bytes_input.bytes()[1], 42);
|
||||
/// assert_eq!(bytes_input.mutator_bytes()[1], 42);
|
||||
/// ```
|
||||
///
|
||||
/// If inputs implement the [`HasMutatorResizableBytes`] trait, growing or shrinking the sub input
|
||||
/// If inputs implement the [`ResizableMutator`] trait, growing or shrinking the sub input
|
||||
/// will grow or shrink the parent input,
|
||||
/// and keep elements around the current range untouched / move them accordingly.
|
||||
///
|
||||
@ -45,7 +45,7 @@ use crate::inputs::{HasMutatorBytes, HasMutatorResizableBytes};
|
||||
/// ```rust
|
||||
/// # extern crate alloc;
|
||||
/// # extern crate libafl;
|
||||
/// # use libafl::inputs::{BytesInput, HasMutatorBytes, HasMutatorResizableBytes};
|
||||
/// # use libafl::inputs::{BytesInput, HasMutatorBytes, ResizableMutator};
|
||||
/// # use alloc::vec::Vec;
|
||||
/// #
|
||||
/// # #[cfg(not(feature = "std"))]
|
||||
@ -57,13 +57,13 @@ use crate::inputs::{HasMutatorBytes, HasMutatorResizableBytes};
|
||||
/// // Note that the range ends on an exclusive value this time.
|
||||
/// let mut sub_input = bytes_input.sub_input(1..=3);
|
||||
///
|
||||
/// assert_eq!(sub_input.bytes(), &[2, 3, 4]);
|
||||
/// assert_eq!(sub_input.mutator_bytes(), &[2, 3, 4]);
|
||||
///
|
||||
/// // We extend it with a few values.
|
||||
/// sub_input.extend(&[42, 42, 42]);
|
||||
///
|
||||
/// // The values outside of the range are moved back and forwards, accordingly.
|
||||
/// assert_eq!(bytes_input.bytes(), [1, 2, 3, 4, 42, 42, 42, 5]);
|
||||
/// assert_eq!(bytes_input.mutator_bytes(), [1, 2, 3, 4, 42, 42, 42, 5]);
|
||||
/// ```
|
||||
///
|
||||
/// The input supports all methods in the [`HasMutatorBytes`] trait if the parent input also implements this trait.
|
||||
@ -102,19 +102,19 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
#[inline]
|
||||
fn bytes(&self) -> &[u8] {
|
||||
&self.parent_input.bytes()[self.range.clone()]
|
||||
fn mutator_bytes(&self) -> &[u8] {
|
||||
&self.parent_input.mutator_bytes()[self.range.clone()]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.parent_input.bytes_mut()[self.range.clone()]
|
||||
fn mutator_bytes_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.parent_input.mutator_bytes_mut()[self.range.clone()]
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> HasMutatorResizableBytes for BytesSubInput<'_, I>
|
||||
impl<I> ResizableMutator<u8> for BytesSubInput<'_, I>
|
||||
where
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes + HasLen,
|
||||
{
|
||||
fn resize(&mut self, new_len: usize, value: u8) {
|
||||
let start_index = self.range.start;
|
||||
@ -134,7 +134,7 @@ where
|
||||
|
||||
if old_parent_len > end_index {
|
||||
// the parent has a reminder, move it back.
|
||||
let parent_bytes = self.parent_input.bytes_mut();
|
||||
let parent_bytes = self.parent_input.mutator_bytes_mut();
|
||||
|
||||
// move right
|
||||
let (_, rest) = parent_bytes.split_at_mut(start_index + old_len);
|
||||
@ -151,7 +151,7 @@ where
|
||||
// We shrink. Remove the values, then remove the underlying buffer.
|
||||
let diff = old_len - new_len;
|
||||
|
||||
let parent_bytes = self.parent_input.bytes_mut();
|
||||
let parent_bytes = self.parent_input.mutator_bytes_mut();
|
||||
|
||||
// move left
|
||||
let (_, rest) = parent_bytes.split_at_mut(start_index + new_len);
|
||||
@ -171,7 +171,7 @@ where
|
||||
|
||||
let new_values: Vec<u8> = iter.into_iter().copied().collect();
|
||||
self.resize(old_len + new_values.len(), 0);
|
||||
self.bytes_mut()[old_len..].copy_from_slice(&new_values);
|
||||
self.mutator_bytes_mut()[old_len..].copy_from_slice(&new_values);
|
||||
}
|
||||
|
||||
/// Creates a splicing iterator that replaces the specified range in the vector
|
||||
@ -214,7 +214,7 @@ mod tests {
|
||||
use libafl_bolts::HasLen;
|
||||
|
||||
use crate::{
|
||||
inputs::{BytesInput, HasMutatorBytes, HasMutatorResizableBytes, NopInput},
|
||||
inputs::{BytesInput, HasMutatorBytes, NopInput, ResizableMutator},
|
||||
mutators::{havoc_mutations_no_crossover, MutatorsTuple},
|
||||
state::NopState,
|
||||
};
|
||||
@ -245,19 +245,19 @@ mod tests {
|
||||
|
||||
let mut sub_input = bytes_input.sub_input(0..1);
|
||||
assert_eq!(sub_input.len(), 1);
|
||||
sub_input.bytes_mut()[0] = 2;
|
||||
assert_eq!(bytes_input.bytes()[0], 2);
|
||||
sub_input.mutator_bytes_mut()[0] = 2;
|
||||
assert_eq!(bytes_input.mutator_bytes()[0], 2);
|
||||
|
||||
let mut sub_input = bytes_input.sub_input(1..=2);
|
||||
assert_eq!(sub_input.len(), 2);
|
||||
sub_input.bytes_mut()[0] = 3;
|
||||
assert_eq!(bytes_input.bytes()[1], 3);
|
||||
sub_input.mutator_bytes_mut()[0] = 3;
|
||||
assert_eq!(bytes_input.mutator_bytes()[1], 3);
|
||||
|
||||
let mut sub_input = bytes_input.sub_input(..);
|
||||
assert_eq!(sub_input.len(), len_orig);
|
||||
sub_input.bytes_mut()[0] = 1;
|
||||
sub_input.bytes_mut()[1] = 2;
|
||||
assert_eq!(bytes_input.bytes()[0], 1);
|
||||
sub_input.mutator_bytes_mut()[0] = 1;
|
||||
sub_input.mutator_bytes_mut()[1] = 2;
|
||||
assert_eq!(bytes_input.mutator_bytes()[0], 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -268,10 +268,10 @@ mod tests {
|
||||
let mut sub_input = bytes_input.sub_input(2..);
|
||||
assert_eq!(sub_input.len(), len_orig - 2);
|
||||
sub_input.resize(len_orig, 0);
|
||||
assert_eq!(sub_input.bytes()[sub_input.len() - 1], 0);
|
||||
assert_eq!(sub_input.mutator_bytes()[sub_input.len() - 1], 0);
|
||||
assert_eq!(sub_input.len(), len_orig);
|
||||
assert_eq!(bytes_input.len(), len_orig + 2);
|
||||
assert_eq!(bytes_input.bytes()[bytes_input.len() - 1], 0);
|
||||
assert_eq!(bytes_input.mutator_bytes()[bytes_input.len() - 1], 0);
|
||||
|
||||
let (mut bytes_input, len_orig) = init_bytes_input();
|
||||
|
||||
@ -279,7 +279,7 @@ mod tests {
|
||||
assert_eq!(sub_input.len(), 2);
|
||||
sub_input.resize(3, 0);
|
||||
assert_eq!(sub_input.len(), 3);
|
||||
assert_eq!(sub_input.bytes()[sub_input.len() - 1], 0);
|
||||
assert_eq!(sub_input.mutator_bytes()[sub_input.len() - 1], 0);
|
||||
assert_eq!(bytes_input.len(), len_orig + 1);
|
||||
|
||||
let mut sub_input = bytes_input.sub_input(..3);
|
||||
@ -300,7 +300,7 @@ mod tests {
|
||||
sub_input.resize(10, 0);
|
||||
assert_eq!(sub_input.len(), 10);
|
||||
assert_eq!(bytes_input.len(), 10);
|
||||
assert_eq!(bytes_input.bytes()[2], 0);
|
||||
assert_eq!(bytes_input.mutator_bytes()[2], 0);
|
||||
|
||||
let mut sub_input = bytes_input.sub_input(..);
|
||||
sub_input.resize(1, 0);
|
||||
|
@ -158,17 +158,17 @@ pub trait HasTargetBytes {
|
||||
/// Contains mutable bytes
|
||||
pub trait HasMutatorBytes: HasLen {
|
||||
/// The bytes
|
||||
fn bytes(&self) -> &[u8];
|
||||
fn mutator_bytes(&self) -> &[u8];
|
||||
|
||||
/// The bytes to mutate
|
||||
fn bytes_mut(&mut self) -> &mut [u8];
|
||||
fn mutator_bytes_mut(&mut self) -> &mut [u8];
|
||||
|
||||
/// Creates a [`SubRangeSlice`] from this input, that can be used to slice a byte array.
|
||||
fn sub_bytes<R>(&self, range: R) -> SubRangeSlice<u8>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
SubRangeSlice::new(OwnedSlice::from(self.bytes()), range)
|
||||
SubRangeSlice::new(OwnedSlice::from(self.mutator_bytes()), range)
|
||||
}
|
||||
|
||||
/// Creates a [`SubRangeMutSlice`] from this input, that can be used to slice a byte array.
|
||||
@ -176,7 +176,7 @@ pub trait HasMutatorBytes: HasLen {
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
SubRangeMutSlice::new(OwnedMutSlice::from(self.bytes_mut()), range)
|
||||
SubRangeMutSlice::new(OwnedMutSlice::from(self.mutator_bytes_mut()), range)
|
||||
}
|
||||
|
||||
/// Creates a [`BytesSubInput`] from this input, that can be used for local mutations.
|
||||
@ -189,11 +189,11 @@ pub trait HasMutatorBytes: HasLen {
|
||||
}
|
||||
|
||||
impl HasMutatorBytes for Vec<u8> {
|
||||
fn bytes(&self) -> &[u8] {
|
||||
fn mutator_bytes(&self) -> &[u8] {
|
||||
self.as_ref()
|
||||
}
|
||||
|
||||
fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn mutator_bytes_mut(&mut self) -> &mut [u8] {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
@ -203,63 +203,68 @@ impl HasMutatorBytes for Vec<u8> {
|
||||
pub type MutVecInput<'a> = &'a mut Vec<u8>;
|
||||
|
||||
impl HasMutatorBytes for &'_ mut Vec<u8> {
|
||||
fn bytes(&self) -> &[u8] {
|
||||
fn mutator_bytes(&self) -> &[u8] {
|
||||
self
|
||||
}
|
||||
|
||||
fn bytes_mut(&mut self) -> &mut [u8] {
|
||||
fn mutator_bytes_mut(&mut self) -> &mut [u8] {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains mutable and resizable bytes
|
||||
pub trait HasMutatorResizableBytes: HasMutatorBytes {
|
||||
/// Resize the mutator bytes to a given new size.
|
||||
/// Contains resizable bytes
|
||||
pub trait ResizableMutator<T> {
|
||||
/// Resize the mutator content to a given new size.
|
||||
/// Use `value` to fill new slots in case the buffer grows.
|
||||
/// See [`Vec::splice`].
|
||||
fn resize(&mut self, new_len: usize, value: u8);
|
||||
fn resize(&mut self, new_len: usize, value: T);
|
||||
|
||||
/// Extends the given buffer with an iterator. See [`alloc::vec::Vec::extend`]
|
||||
fn extend<'a, I: IntoIterator<Item = &'a u8>>(&mut self, iter: I);
|
||||
fn extend<'a, I: IntoIterator<Item = &'a T>>(&mut self, iter: I)
|
||||
where
|
||||
T: 'a;
|
||||
|
||||
/// Splices the given target bytes according to [`Vec::splice`]'s rules
|
||||
/// Splices the given target values according to [`Vec::splice`]'s rules
|
||||
fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
I: IntoIterator<Item = u8>;
|
||||
I: IntoIterator<Item = T>;
|
||||
|
||||
/// Drains the given target bytes according to [`Vec::drain`]'s rules
|
||||
fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
|
||||
/// Drains the given target value according to [`Vec::drain`]'s rules
|
||||
fn drain<R>(&mut self, range: R) -> Drain<'_, T>
|
||||
where
|
||||
R: RangeBounds<usize>;
|
||||
}
|
||||
|
||||
impl HasMutatorResizableBytes for Vec<u8> {
|
||||
fn resize(&mut self, new_len: usize, value: u8) {
|
||||
<Vec<u8>>::resize(self, new_len, value);
|
||||
impl<T> ResizableMutator<T> for Vec<T>
|
||||
where
|
||||
T: Copy + 'static,
|
||||
{
|
||||
fn resize(&mut self, new_len: usize, value: T) {
|
||||
<Vec<T>>::resize(self, new_len, value);
|
||||
}
|
||||
|
||||
fn extend<'a, I: IntoIterator<Item = &'a u8>>(&mut self, iter: I) {
|
||||
<Vec<u8> as Extend<I::Item>>::extend(self, iter);
|
||||
fn extend<'a, I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
|
||||
<Vec<T> as Extend<I::Item>>::extend(self, iter);
|
||||
}
|
||||
|
||||
fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
I: IntoIterator<Item = u8>,
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
<Vec<u8>>::splice(self, range, replace_with)
|
||||
<Vec<T>>::splice(self, range, replace_with)
|
||||
}
|
||||
|
||||
fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
|
||||
fn drain<R>(&mut self, range: R) -> Drain<'_, T>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
<Vec<u8>>::drain(self, range)
|
||||
<Vec<T>>::drain(self, range)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasMutatorResizableBytes for &mut Vec<u8> {
|
||||
impl ResizableMutator<u8> for &mut Vec<u8> {
|
||||
fn resize(&mut self, new_len: usize, value: u8) {
|
||||
self.deref_mut().resize(new_len, value);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use libafl_bolts::{rands::Rand, Error};
|
||||
use crate::{
|
||||
corpus::{Corpus, CorpusId},
|
||||
impl_default_multipart,
|
||||
inputs::{multi::MultipartInput, HasMutatorResizableBytes, Input},
|
||||
inputs::{multi::MultipartInput, HasMutatorBytes, Input, ResizableMutator},
|
||||
mutators::{
|
||||
mutations::{
|
||||
rand_range, BitFlipMutator, ByteAddMutator, ByteDecMutator, ByteFlipMutator,
|
||||
@ -119,7 +119,7 @@ impl_default_multipart!(
|
||||
impl<I, S> Mutator<MultipartInput<I>, S> for CrossoverInsertMutator
|
||||
where
|
||||
S: HasCorpus<MultipartInput<I>> + HasMaxSize + HasRand,
|
||||
I: Input + HasMutatorResizableBytes,
|
||||
I: Input + ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(
|
||||
&mut self,
|
||||
@ -140,7 +140,7 @@ where
|
||||
let choice = name_choice % input.names().len();
|
||||
let name = input.names()[choice].clone();
|
||||
|
||||
let other_size = input.parts()[choice].bytes().len();
|
||||
let other_size = input.parts()[choice].mutator_bytes().len();
|
||||
if other_size < 2 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -155,7 +155,7 @@ where
|
||||
.parts_by_name(&name)
|
||||
.filter(|&(p, _)| p != choice)
|
||||
.nth(part_choice % parts)
|
||||
.map(|(id, part)| (id, part.bytes().len()));
|
||||
.map(|(id, part)| (id, part.mutator_bytes().len()));
|
||||
|
||||
if let Some((part_idx, size)) = maybe_size {
|
||||
let Some(nz) = NonZero::new(size) else {
|
||||
@ -186,7 +186,7 @@ where
|
||||
size,
|
||||
target,
|
||||
range,
|
||||
chosen.bytes(),
|
||||
chosen.mutator_bytes(),
|
||||
));
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ where
|
||||
let choice = name_choice % other.names().len();
|
||||
let name = &other.names()[choice];
|
||||
|
||||
let other_size = other.parts()[choice].bytes().len();
|
||||
let other_size = other.parts()[choice].mutator_bytes().len();
|
||||
if other_size < 2 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -217,7 +217,7 @@ where
|
||||
.nth(part_choice % parts)
|
||||
.unwrap();
|
||||
drop(other_testcase);
|
||||
let size = part.bytes().len();
|
||||
let size = part.mutator_bytes().len();
|
||||
let Some(nz) = NonZero::new(size) else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
};
|
||||
@ -240,7 +240,7 @@ where
|
||||
size,
|
||||
target,
|
||||
range,
|
||||
other.parts()[choice].bytes(),
|
||||
other.parts()[choice].mutator_bytes(),
|
||||
))
|
||||
} else {
|
||||
// just add it!
|
||||
@ -254,7 +254,7 @@ where
|
||||
impl<I, S> Mutator<MultipartInput<I>, S> for CrossoverReplaceMutator
|
||||
where
|
||||
S: HasCorpus<MultipartInput<I>> + HasMaxSize + HasRand,
|
||||
I: Input + HasMutatorResizableBytes,
|
||||
I: Input + ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(
|
||||
&mut self,
|
||||
@ -275,7 +275,7 @@ where
|
||||
let choice = name_choice % input.names().len();
|
||||
let name = input.names()[choice].clone();
|
||||
|
||||
let other_size = input.parts()[choice].bytes().len();
|
||||
let other_size = input.parts()[choice].mutator_bytes().len();
|
||||
if other_size < 2 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -290,7 +290,7 @@ where
|
||||
.parts_by_name(&name)
|
||||
.filter(|&(p, _)| p != choice)
|
||||
.nth(part_choice % parts)
|
||||
.map(|(id, part)| (id, part.bytes().len()));
|
||||
.map(|(id, part)| (id, part.mutator_bytes().len()));
|
||||
|
||||
if let Some((part_idx, size)) = maybe_size {
|
||||
let Some(nz) = NonZero::new(size) else {
|
||||
@ -316,7 +316,12 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(Self::crossover_replace(part, target, range, chosen.bytes()));
|
||||
return Ok(Self::crossover_replace(
|
||||
part,
|
||||
target,
|
||||
range,
|
||||
chosen.mutator_bytes(),
|
||||
));
|
||||
}
|
||||
|
||||
return Ok(MutationResult::Skipped);
|
||||
@ -333,7 +338,7 @@ where
|
||||
let choice = name_choice % other.names().len();
|
||||
let name = &other.names()[choice];
|
||||
|
||||
let other_size = other.parts()[choice].bytes().len();
|
||||
let other_size = other.parts()[choice].mutator_bytes().len();
|
||||
if other_size < 2 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -346,7 +351,7 @@ where
|
||||
.nth(part_choice % parts)
|
||||
.unwrap();
|
||||
drop(other_testcase);
|
||||
let size = part.bytes().len();
|
||||
let size = part.mutator_bytes().len();
|
||||
let Some(nz) = NonZero::new(size) else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
};
|
||||
@ -367,7 +372,7 @@ where
|
||||
part,
|
||||
target,
|
||||
range,
|
||||
other.parts()[choice].bytes(),
|
||||
other.parts()[choice].mutator_bytes(),
|
||||
))
|
||||
} else {
|
||||
// just add it!
|
||||
|
@ -16,7 +16,7 @@ use libafl_bolts::{rands::Rand, Named};
|
||||
|
||||
use crate::{
|
||||
corpus::Corpus,
|
||||
inputs::{HasMutatorBytes, HasMutatorResizableBytes},
|
||||
inputs::{HasMutatorBytes, ResizableMutator},
|
||||
mutators::{MutationResult, Mutator},
|
||||
nonzero, random_corpus_id_with_disabled,
|
||||
state::{HasCorpus, HasMaxSize, HasRand},
|
||||
@ -132,11 +132,11 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let bit = 1 << state.rand_mut().choose(0..8).unwrap();
|
||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||
let byte = state.rand_mut().choose(input.mutator_bytes_mut()).unwrap();
|
||||
*byte ^= bit;
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -168,10 +168,10 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
*state.rand_mut().choose(input.bytes_mut()).unwrap() ^= 0xff;
|
||||
*state.rand_mut().choose(input.mutator_bytes_mut()).unwrap() ^= 0xff;
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
}
|
||||
@ -202,10 +202,10 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||
let byte = state.rand_mut().choose(input.mutator_bytes_mut()).unwrap();
|
||||
*byte = byte.wrapping_add(1);
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -237,10 +237,10 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||
let byte = state.rand_mut().choose(input.mutator_bytes_mut()).unwrap();
|
||||
*byte = byte.wrapping_sub(1);
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -272,10 +272,10 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||
let byte = state.rand_mut().choose(input.mutator_bytes_mut()).unwrap();
|
||||
*byte = (!(*byte)).wrapping_add(1);
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -307,10 +307,10 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().is_empty() {
|
||||
if input.mutator_bytes().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||
let byte = state.rand_mut().choose(input.mutator_bytes_mut()).unwrap();
|
||||
*byte ^= 1 + state.rand_mut().below(nonzero!(254)) as u8;
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -352,13 +352,13 @@ macro_rules! add_mutator_impl {
|
||||
input: &mut I,
|
||||
|
||||
) -> Result<MutationResult, Error> {
|
||||
if input.bytes().len() < size_of::<$size>() {
|
||||
if input.mutator_bytes().len() < size_of::<$size>() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
// choose a random window of bytes (windows overlap) and convert to $size
|
||||
let (index, bytes) = state
|
||||
.rand_mut()
|
||||
.choose(input.bytes().windows(size_of::<$size>()).enumerate()).unwrap();
|
||||
.choose(input.mutator_bytes().windows(size_of::<$size>()).enumerate()).unwrap();
|
||||
let val = <$size>::from_ne_bytes(bytes.try_into().unwrap());
|
||||
|
||||
// mutate
|
||||
@ -371,7 +371,7 @@ macro_rules! add_mutator_impl {
|
||||
};
|
||||
|
||||
// set bytes to mutated value
|
||||
let new_bytes = &mut input.bytes_mut()[index..index + size_of::<$size>()];
|
||||
let new_bytes = &mut input.mutator_bytes_mut()[index..index + size_of::<$size>()];
|
||||
new_bytes.copy_from_slice(&new_val.to_ne_bytes());
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -415,10 +415,10 @@ macro_rules! interesting_mutator_impl {
|
||||
{
|
||||
#[expect(clippy::cast_sign_loss)]
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
if input.bytes().len() < size_of::<$size>() {
|
||||
if input.mutator_bytes().len() < size_of::<$size>() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let bytes = input.bytes_mut();
|
||||
let bytes = input.mutator_bytes_mut();
|
||||
let upper_bound = (bytes.len() + 1 - size_of::<$size>());
|
||||
// # Safety
|
||||
// the length is at least as large as the size here (checked above), and we add a 1 -> never zero.
|
||||
@ -464,10 +464,10 @@ pub struct BytesDeleteMutator;
|
||||
impl<I, S> Mutator<I, S> for BytesDeleteMutator
|
||||
where
|
||||
S: HasRand,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size <= 2 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -506,11 +506,11 @@ pub struct BytesExpandMutator;
|
||||
impl<I, S> Mutator<I, S> for BytesExpandMutator
|
||||
where
|
||||
S: HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let max_size = state.max_size();
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 || size >= max_size {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -524,7 +524,7 @@ where
|
||||
input.resize(size + range.len(), 0);
|
||||
unsafe {
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
range.start,
|
||||
range.start + range.len(),
|
||||
size - range.start,
|
||||
@ -557,11 +557,11 @@ pub struct BytesInsertMutator;
|
||||
impl<I, S> Mutator<I, S> for BytesInsertMutator
|
||||
where
|
||||
S: HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let max_size = state.max_size();
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 || size >= max_size {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -584,15 +584,20 @@ where
|
||||
|
||||
// # Safety
|
||||
// size is larger than 0, checked above.
|
||||
let val = input.bytes()[state
|
||||
let val = input.mutator_bytes()[state
|
||||
.rand_mut()
|
||||
.below(unsafe { NonZero::new(size).unwrap_unchecked() })];
|
||||
|
||||
input.resize(size + amount, 0);
|
||||
unsafe {
|
||||
buffer_self_copy(input.bytes_mut(), offset, offset + amount, size - offset);
|
||||
buffer_self_copy(
|
||||
input.mutator_bytes_mut(),
|
||||
offset,
|
||||
offset + amount,
|
||||
size - offset,
|
||||
);
|
||||
}
|
||||
buffer_set(input.bytes_mut(), offset, amount, val);
|
||||
buffer_set(input.mutator_bytes_mut(), offset, amount, val);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -620,11 +625,11 @@ pub struct BytesRandInsertMutator;
|
||||
impl<I, S> Mutator<I, S> for BytesRandInsertMutator
|
||||
where
|
||||
S: HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let max_size = state.max_size();
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size >= max_size {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -648,9 +653,14 @@ where
|
||||
|
||||
input.resize(size + amount, 0);
|
||||
unsafe {
|
||||
buffer_self_copy(input.bytes_mut(), offset, offset + amount, size - offset);
|
||||
buffer_self_copy(
|
||||
input.mutator_bytes_mut(),
|
||||
offset,
|
||||
offset + amount,
|
||||
size - offset,
|
||||
);
|
||||
}
|
||||
buffer_set(input.bytes_mut(), offset, amount, val);
|
||||
buffer_set(input.mutator_bytes_mut(), offset, amount, val);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -681,7 +691,7 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -691,9 +701,9 @@ where
|
||||
NonZero::new(min(size, 16)).unwrap_unchecked()
|
||||
});
|
||||
|
||||
let val = *state.rand_mut().choose(input.bytes()).unwrap();
|
||||
let val = *state.rand_mut().choose(input.mutator_bytes()).unwrap();
|
||||
let quantity = range.len();
|
||||
buffer_set(input.bytes_mut(), range.start, quantity, val);
|
||||
buffer_set(input.mutator_bytes_mut(), range.start, quantity, val);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -724,7 +734,7 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -736,7 +746,7 @@ where
|
||||
|
||||
let val = state.rand_mut().next() as u8;
|
||||
let quantity = range.len();
|
||||
buffer_set(input.bytes_mut(), range.start, quantity, val);
|
||||
buffer_set(input.mutator_bytes_mut(), range.start, quantity, val);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -767,7 +777,7 @@ where
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size <= 1 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -784,7 +794,7 @@ where
|
||||
});
|
||||
|
||||
unsafe {
|
||||
buffer_self_copy(input.bytes_mut(), range.start, target, range.len());
|
||||
buffer_self_copy(input.mutator_bytes_mut(), range.start, target, range.len());
|
||||
}
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
@ -815,10 +825,10 @@ pub struct BytesInsertCopyMutator {
|
||||
impl<I, S> Mutator<I, S> for BytesInsertCopyMutator
|
||||
where
|
||||
S: HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size <= 1 || size >= state.max_size() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -843,19 +853,25 @@ where
|
||||
unsafe {
|
||||
buffer_copy(
|
||||
&mut self.tmp_buf,
|
||||
input.bytes(),
|
||||
input.mutator_bytes(),
|
||||
range.start,
|
||||
0,
|
||||
range.len(),
|
||||
);
|
||||
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
target,
|
||||
target + range.len(),
|
||||
size - target,
|
||||
);
|
||||
buffer_copy(input.bytes_mut(), &self.tmp_buf, 0, target, range.len());
|
||||
buffer_copy(
|
||||
input.mutator_bytes_mut(),
|
||||
&self.tmp_buf,
|
||||
0,
|
||||
target,
|
||||
range.len(),
|
||||
);
|
||||
}
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
@ -886,10 +902,10 @@ pub struct BytesSwapMutator {
|
||||
impl<I, S> Mutator<I, S> for BytesSwapMutator
|
||||
where
|
||||
S: HasRand,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size <= 1 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -916,7 +932,7 @@ where
|
||||
// copy first range to tmp
|
||||
buffer_copy(
|
||||
&mut self.tmp_buf,
|
||||
input.bytes(),
|
||||
input.mutator_bytes(),
|
||||
first.start,
|
||||
0,
|
||||
first.len(),
|
||||
@ -924,7 +940,7 @@ where
|
||||
|
||||
// adjust second.end..first.start, move them by diff_in_size to the right
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
second.end,
|
||||
second.end + diff_in_size,
|
||||
first.start - second.end,
|
||||
@ -932,7 +948,7 @@ where
|
||||
|
||||
// copy second to where first was
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
second.start,
|
||||
first.start + diff_in_size,
|
||||
second.len(),
|
||||
@ -940,7 +956,7 @@ where
|
||||
|
||||
// copy first back
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
&self.tmp_buf,
|
||||
0,
|
||||
second.start,
|
||||
@ -952,7 +968,7 @@ where
|
||||
// copy first range to tmp
|
||||
buffer_copy(
|
||||
&mut self.tmp_buf,
|
||||
input.bytes(),
|
||||
input.mutator_bytes(),
|
||||
first.start,
|
||||
0,
|
||||
first.len(),
|
||||
@ -960,7 +976,7 @@ where
|
||||
|
||||
// adjust second.end..first.start, move them by diff_in_size to the left
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
second.end,
|
||||
second.end - diff_in_size,
|
||||
first.start - second.end,
|
||||
@ -968,7 +984,7 @@ where
|
||||
|
||||
// copy second to where first was
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
second.start,
|
||||
first.start - diff_in_size,
|
||||
second.len(),
|
||||
@ -976,7 +992,7 @@ where
|
||||
|
||||
// copy first back
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
&self.tmp_buf,
|
||||
0,
|
||||
second.start,
|
||||
@ -1001,7 +1017,7 @@ where
|
||||
// copy second range to tmp
|
||||
buffer_copy(
|
||||
&mut self.tmp_buf,
|
||||
input.bytes(),
|
||||
input.mutator_bytes(),
|
||||
second.start,
|
||||
0,
|
||||
second.len(),
|
||||
@ -1009,7 +1025,7 @@ where
|
||||
|
||||
// adjust first.end..second.start, move them by diff_in_size to the right
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
first.end,
|
||||
first.end + diff_in_size,
|
||||
second.start - first.end,
|
||||
@ -1017,7 +1033,7 @@ where
|
||||
|
||||
// copy first to where second was
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
first.start,
|
||||
second.start + diff_in_size,
|
||||
first.len(),
|
||||
@ -1025,7 +1041,7 @@ where
|
||||
|
||||
// copy second back
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
&self.tmp_buf,
|
||||
0,
|
||||
first.start,
|
||||
@ -1036,7 +1052,7 @@ where
|
||||
// copy second range to tmp
|
||||
buffer_copy(
|
||||
&mut self.tmp_buf,
|
||||
input.bytes(),
|
||||
input.mutator_bytes(),
|
||||
second.start,
|
||||
0,
|
||||
second.len(),
|
||||
@ -1044,7 +1060,7 @@ where
|
||||
|
||||
// adjust first.end..second.start, move them by diff_in_size to the left
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
first.end,
|
||||
first.end - diff_in_size,
|
||||
second.start - first.end,
|
||||
@ -1052,7 +1068,7 @@ where
|
||||
|
||||
// copy first to where second was
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
first.start,
|
||||
second.start - diff_in_size,
|
||||
first.len(),
|
||||
@ -1060,7 +1076,7 @@ where
|
||||
|
||||
// copy second back
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
&self.tmp_buf,
|
||||
0,
|
||||
first.start,
|
||||
@ -1104,12 +1120,12 @@ impl CrossoverInsertMutator {
|
||||
other: &[u8],
|
||||
) -> MutationResult
|
||||
where
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
input.resize(size + range.len(), 0);
|
||||
unsafe {
|
||||
buffer_self_copy(
|
||||
input.bytes_mut(),
|
||||
input.mutator_bytes_mut(),
|
||||
target,
|
||||
target + range.len(),
|
||||
size - target,
|
||||
@ -1117,7 +1133,13 @@ impl CrossoverInsertMutator {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), other, range.start, target, range.len());
|
||||
buffer_copy(
|
||||
input.mutator_bytes_mut(),
|
||||
other,
|
||||
range.start,
|
||||
target,
|
||||
range.len(),
|
||||
);
|
||||
}
|
||||
MutationResult::Mutated
|
||||
}
|
||||
@ -1125,11 +1147,11 @@ impl CrossoverInsertMutator {
|
||||
|
||||
impl<I, S> Mutator<I, S> for CrossoverInsertMutator
|
||||
where
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
S: HasCorpus<I> + HasRand + HasMaxSize,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
let Some(nonzero_size) = NonZero::new(size) else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
};
|
||||
@ -1149,7 +1171,10 @@ where
|
||||
|
||||
let other_size = {
|
||||
let mut other_testcase = state.corpus().get_from_all(id)?.borrow_mut();
|
||||
other_testcase.load_input(state.corpus())?.bytes().len()
|
||||
other_testcase
|
||||
.load_input(state.corpus())?
|
||||
.mutator_bytes()
|
||||
.len()
|
||||
};
|
||||
|
||||
if other_size < 2 {
|
||||
@ -1173,7 +1198,7 @@ where
|
||||
size,
|
||||
target,
|
||||
range,
|
||||
other.bytes(),
|
||||
other.mutator_bytes(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -1208,7 +1233,13 @@ impl CrossoverReplaceMutator {
|
||||
I: HasMutatorBytes,
|
||||
{
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), other, range.start, target, range.len());
|
||||
buffer_copy(
|
||||
input.mutator_bytes_mut(),
|
||||
other,
|
||||
range.start,
|
||||
target,
|
||||
range.len(),
|
||||
);
|
||||
}
|
||||
MutationResult::Mutated
|
||||
}
|
||||
@ -1220,7 +1251,7 @@ where
|
||||
S: HasCorpus<I> + HasRand,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -1235,7 +1266,7 @@ where
|
||||
|
||||
let other_size = {
|
||||
let mut testcase = state.corpus().get_from_all(id)?.borrow_mut();
|
||||
testcase.load_input(state.corpus())?.bytes().len()
|
||||
testcase.load_input(state.corpus())?.mutator_bytes().len()
|
||||
};
|
||||
|
||||
if other_size < 2 {
|
||||
@ -1258,7 +1289,12 @@ where
|
||||
// No need to load the input again, it'll still be cached.
|
||||
let other = other_testcase.input().as_ref().unwrap();
|
||||
|
||||
Ok(Self::crossover_replace(input, target, range, other.bytes()))
|
||||
Ok(Self::crossover_replace(
|
||||
input,
|
||||
target,
|
||||
range,
|
||||
other.mutator_bytes(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1313,12 +1349,12 @@ impl<F, I, O> MappedCrossoverInsertMutator<F, I, O> {
|
||||
impl<S, F, I1, I2, O> Mutator<I2, S> for MappedCrossoverInsertMutator<F, I1, O>
|
||||
where
|
||||
F: Fn(&I1) -> &O,
|
||||
I2: HasMutatorResizableBytes,
|
||||
I2: ResizableMutator<u8> + HasMutatorBytes,
|
||||
O: IntoOptionBytes,
|
||||
S: HasCorpus<I1> + HasMaxSize + HasRand,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I2) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
let max_size = state.max_size();
|
||||
// TODO: fix bug if size is 0 (?)
|
||||
if size >= max_size || size == 0 {
|
||||
@ -1407,7 +1443,7 @@ where
|
||||
S: HasCorpus<I1> + HasMaxSize + HasRand,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I2) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
@ -1491,7 +1527,7 @@ pub struct SpliceMutator;
|
||||
impl<I, S> Mutator<I, S> for SpliceMutator
|
||||
where
|
||||
S: HasCorpus<I> + HasRand,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
#[expect(clippy::cast_sign_loss)]
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
@ -1507,7 +1543,7 @@ where
|
||||
let mut other_testcase = state.corpus().get_from_all(id)?.borrow_mut();
|
||||
let other = other_testcase.load_input(state.corpus())?;
|
||||
|
||||
let (f, l) = locate_diffs(input.bytes(), other.bytes());
|
||||
let (f, l) = locate_diffs(input.mutator_bytes(), other.mutator_bytes());
|
||||
|
||||
if f != l && f >= 0 && l >= 2 {
|
||||
(f as usize, l as usize)
|
||||
@ -1522,7 +1558,10 @@ where
|
||||
// Input will already be loaded.
|
||||
let other = other_testcase.input().as_ref().unwrap();
|
||||
|
||||
input.splice(split_at.., other.bytes()[split_at..].iter().copied());
|
||||
input.splice(
|
||||
split_at..,
|
||||
other.mutator_bytes()[split_at..].iter().copied(),
|
||||
);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
}
|
||||
|
@ -352,10 +352,10 @@ mod tests {
|
||||
let mut splice = SpliceMutator::new();
|
||||
splice.mutate(&mut state, &mut input).unwrap();
|
||||
|
||||
log::trace!("{:?}", input.bytes());
|
||||
log::trace!("{:?}", input.mutator_bytes());
|
||||
|
||||
// The pre-seeded rand should have spliced at position 2.
|
||||
assert_eq!(input.bytes(), b"abf");
|
||||
assert_eq!(input.mutator_bytes(), b"abf");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -25,13 +25,13 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::mutators::str_decode;
|
||||
use crate::{
|
||||
corpus::{CorpusId, HasCurrentCorpusId},
|
||||
inputs::HasMutatorResizableBytes,
|
||||
inputs::{HasMutatorBytes, ResizableMutator},
|
||||
mutators::{
|
||||
buffer_self_copy, mutations::buffer_copy, MultiMutator, MutationResult, Mutator, Named,
|
||||
},
|
||||
observers::cmp::{AFLppCmpValuesMetadata, CmpValues, CmpValuesMetadata},
|
||||
stages::TaintMetadata,
|
||||
state::{HasMaxSize, HasRand},
|
||||
state::{HasCorpus, HasMaxSize, HasRand},
|
||||
Error, HasMetadata,
|
||||
};
|
||||
|
||||
@ -306,7 +306,7 @@ pub struct TokenInsert;
|
||||
impl<I, S> Mutator<I, S> for TokenInsert
|
||||
where
|
||||
S: HasMetadata + HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let max_size = state.max_size();
|
||||
@ -322,7 +322,7 @@ where
|
||||
};
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
// # Safety
|
||||
// after saturating add it's always above 0
|
||||
|
||||
@ -344,8 +344,8 @@ where
|
||||
|
||||
input.resize(size + len, 0);
|
||||
unsafe {
|
||||
buffer_self_copy(input.bytes_mut(), off, off + len, size - off);
|
||||
buffer_copy(input.bytes_mut(), token, 0, off, len);
|
||||
buffer_self_copy(input.mutator_bytes_mut(), off, off + len, size - off);
|
||||
buffer_copy(input.mutator_bytes_mut(), token, 0, off, len);
|
||||
}
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
@ -375,10 +375,10 @@ pub struct TokenReplace;
|
||||
impl<I, S> Mutator<I, S> for TokenReplace
|
||||
where
|
||||
S: HasMetadata + HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
let off = if let Some(nz) = NonZero::new(size) {
|
||||
state.rand_mut().below(nz)
|
||||
} else {
|
||||
@ -405,7 +405,7 @@ where
|
||||
}
|
||||
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), token, 0, off, len);
|
||||
buffer_copy(input.mutator_bytes_mut(), token, 0, off, len);
|
||||
}
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
@ -435,11 +435,11 @@ pub struct I2SRandReplace;
|
||||
impl<I, S> Mutator<I, S> for I2SRandReplace
|
||||
where
|
||||
S: HasMetadata + HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
#[expect(clippy::too_many_lines)]
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
let Some(size) = NonZero::new(size) else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
};
|
||||
@ -459,8 +459,8 @@ where
|
||||
let idx = state.rand_mut().below(cmps_len);
|
||||
|
||||
let off = state.rand_mut().below(size);
|
||||
let len = input.bytes().len();
|
||||
let bytes = input.bytes_mut();
|
||||
let len = input.mutator_bytes().len();
|
||||
let bytes = input.mutator_bytes_mut();
|
||||
|
||||
let meta = state.metadata_map().get::<CmpValuesMetadata>().unwrap();
|
||||
let cmp_values = &meta.list[idx];
|
||||
@ -571,9 +571,9 @@ where
|
||||
'outer: for i in off..len {
|
||||
let mut size = core::cmp::min(v.0.len(), len - i);
|
||||
while size != 0 {
|
||||
if v.0.as_slice()[0..size] == input.bytes()[i..i + size] {
|
||||
if v.0.as_slice()[0..size] == input.mutator_bytes()[i..i + size] {
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), v.1.as_slice(), 0, i, size);
|
||||
buffer_copy(input.mutator_bytes_mut(), v.1.as_slice(), 0, i, size);
|
||||
}
|
||||
result = MutationResult::Mutated;
|
||||
break 'outer;
|
||||
@ -582,9 +582,9 @@ where
|
||||
}
|
||||
size = core::cmp::min(v.1.len(), len - i);
|
||||
while size != 0 {
|
||||
if v.1.as_slice()[0..size] == input.bytes()[i..i + size] {
|
||||
if v.1.as_slice()[0..size] == input.mutator_bytes()[i..i + size] {
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), v.0.as_slice(), 0, i, size);
|
||||
buffer_copy(input.mutator_bytes_mut(), v.0.as_slice(), 0, i, size);
|
||||
}
|
||||
result = MutationResult::Mutated;
|
||||
break 'outer;
|
||||
@ -636,11 +636,11 @@ where
|
||||
impl<I, S> Mutator<I, S> for I2SRandReplaceBinonly
|
||||
where
|
||||
S: HasMetadata + HasRand + HasMaxSize,
|
||||
I: HasMutatorResizableBytes,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes,
|
||||
{
|
||||
#[expect(clippy::too_many_lines)]
|
||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
let Some(size) = NonZero::new(input.bytes().len()) else {
|
||||
let Some(size) = NonZero::new(input.mutator_bytes().len()) else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
};
|
||||
let Some(meta) = state.metadata_map().get::<CmpValuesMetadata>() else {
|
||||
@ -654,8 +654,8 @@ where
|
||||
let idx = state.rand_mut().below(cmps_len);
|
||||
|
||||
let off = state.rand_mut().below(size);
|
||||
let len = input.bytes().len();
|
||||
let bytes = input.bytes_mut();
|
||||
let len = input.mutator_bytes().len();
|
||||
let bytes = input.mutator_bytes_mut();
|
||||
|
||||
let meta = state.metadata_map().get::<CmpValuesMetadata>().unwrap();
|
||||
let cmp_values = &meta.list[idx];
|
||||
@ -779,9 +779,9 @@ where
|
||||
'outer: for i in off..len {
|
||||
let mut size = core::cmp::min(v.0.len(), len - i);
|
||||
while size != 0 {
|
||||
if v.0.as_slice()[0..size] == input.bytes()[i..i + size] {
|
||||
if v.0.as_slice()[0..size] == input.mutator_bytes()[i..i + size] {
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), v.1.as_slice(), 0, i, size);
|
||||
buffer_copy(input.mutator_bytes_mut(), v.1.as_slice(), 0, i, size);
|
||||
}
|
||||
result = MutationResult::Mutated;
|
||||
break 'outer;
|
||||
@ -790,9 +790,9 @@ where
|
||||
}
|
||||
size = core::cmp::min(v.1.len(), len - i);
|
||||
while size != 0 {
|
||||
if v.1.as_slice()[0..size] == input.bytes()[i..i + size] {
|
||||
if v.1.as_slice()[0..size] == input.mutator_bytes()[i..i + size] {
|
||||
unsafe {
|
||||
buffer_copy(input.bytes_mut(), v.0.as_slice(), 0, i, size);
|
||||
buffer_copy(input.mutator_bytes_mut(), v.0.as_slice(), 0, i, size);
|
||||
}
|
||||
result = MutationResult::Mutated;
|
||||
break 'outer;
|
||||
@ -1305,8 +1305,8 @@ impl AFLppRedQueen {
|
||||
|
||||
impl<I, S> MultiMutator<I, S> for AFLppRedQueen
|
||||
where
|
||||
S: HasMetadata + HasRand + HasMaxSize + HasCurrentCorpusId,
|
||||
I: HasMutatorResizableBytes + From<Vec<u8>>,
|
||||
S: HasMetadata + HasRand + HasMaxSize + HasCorpus<I> + HasCurrentCorpusId,
|
||||
I: ResizableMutator<u8> + From<Vec<u8>> + HasMutatorBytes,
|
||||
{
|
||||
#[expect(clippy::needless_range_loop, clippy::too_many_lines)]
|
||||
fn multi_mutate(
|
||||
@ -1317,7 +1317,7 @@ where
|
||||
) -> Result<Vec<I>, Error> {
|
||||
// TODO
|
||||
// handle 128-bits logs
|
||||
let size = input.bytes().len();
|
||||
let size = input.mutator_bytes().len();
|
||||
if size == 0 {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
@ -1342,9 +1342,9 @@ where
|
||||
let orig_cmpvals = cmp_meta.orig_cmpvals();
|
||||
let new_cmpvals = cmp_meta.new_cmpvals();
|
||||
let headers = cmp_meta.headers();
|
||||
let input_len = input.bytes().len();
|
||||
let input_len = input.mutator_bytes().len();
|
||||
let new_bytes = taint_meta.input_vec();
|
||||
let orig_bytes = input.bytes();
|
||||
let orig_bytes = input.mutator_bytes();
|
||||
|
||||
let taint = taint_meta.ranges();
|
||||
let mut ret = max_count.map_or_else(Vec::new, Vec::with_capacity);
|
||||
|
@ -11,7 +11,7 @@ use libafl_bolts::{rands::Rand, Error, HasLen, Named};
|
||||
|
||||
use crate::{
|
||||
corpus::{CorpusId, HasTestcase, Testcase},
|
||||
inputs::{BytesInput, HasMutatorBytes, HasMutatorResizableBytes},
|
||||
inputs::{BytesInput, HasMutatorBytes, ResizableMutator},
|
||||
mutators::{rand_range, MutationResult, Mutator, Tokens},
|
||||
nonzero,
|
||||
stages::{
|
||||
@ -233,7 +233,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
||||
) -> MutationResult {
|
||||
let temp_range = rand_range(state, range.end - range.start, nonzero!(MAX_CHARS));
|
||||
let range = (range.start + temp_range.start)..(range.start + temp_range.end);
|
||||
let range = match core::str::from_utf8(&input.0.bytes()[range.clone()]) {
|
||||
let range = match core::str::from_utf8(&input.0.mutator_bytes()[range.clone()]) {
|
||||
Ok(_) => range,
|
||||
Err(e) => range.start..(range.start + e.valid_up_to()),
|
||||
};
|
||||
@ -242,7 +242,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
||||
println!(
|
||||
"mutating range: {:?} ({:?})",
|
||||
range,
|
||||
core::str::from_utf8(&input.0.bytes()[range.clone()])
|
||||
core::str::from_utf8(&input.0.mutator_bytes()[range.clone()])
|
||||
);
|
||||
if range.start == range.end {
|
||||
return MutationResult::Skipped;
|
||||
@ -270,7 +270,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
||||
}
|
||||
|
||||
input.0.splice(range, replacement);
|
||||
input.1 = extract_metadata(input.0.bytes());
|
||||
input.1 = extract_metadata(input.0.mutator_bytes());
|
||||
|
||||
MutationResult::Mutated
|
||||
}
|
||||
@ -292,11 +292,11 @@ where
|
||||
S: HasRand + HasMaxSize,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
|
||||
if input.0.bytes().is_empty() {
|
||||
if input.0.mutator_bytes().is_empty() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let bytes = input.0.mutator_bytes();
|
||||
let meta = &input.1;
|
||||
if let Some((base, len)) = choose_start(state.rand_mut(), bytes, meta) {
|
||||
let substring = core::str::from_utf8(&bytes[base..][..len])?;
|
||||
@ -354,11 +354,11 @@ where
|
||||
S: HasRand + HasMaxSize,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
|
||||
if input.0.bytes().is_empty() {
|
||||
if input.0.mutator_bytes().is_empty() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let bytes = input.0.mutator_bytes();
|
||||
let meta = &input.1;
|
||||
if let Some((base, len)) = choose_start(state.rand_mut(), bytes, meta) {
|
||||
let substring = core::str::from_utf8(&bytes[base..][..len])?;
|
||||
@ -404,7 +404,7 @@ where
|
||||
S: HasRand + HasMaxSize + HasMetadata,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
|
||||
if input.0.bytes().is_empty() {
|
||||
if input.0.mutator_bytes().is_empty() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ where
|
||||
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let bytes = input.0.mutator_bytes();
|
||||
let meta = &input.1;
|
||||
if let Some((base, len)) = choose_start(state.rand_mut(), bytes, meta) {
|
||||
let substring = core::str::from_utf8(&bytes[base..][..len])?;
|
||||
@ -439,7 +439,7 @@ where
|
||||
}
|
||||
|
||||
input.0.splice(range, token.iter().copied());
|
||||
input.1 = extract_metadata(input.0.bytes());
|
||||
input.1 = extract_metadata(input.0.mutator_bytes());
|
||||
return Ok(MutationResult::Mutated);
|
||||
}
|
||||
|
||||
@ -463,7 +463,7 @@ where
|
||||
S: HasRand + HasMaxSize + HasMetadata,
|
||||
{
|
||||
fn mutate(&mut self, state: &mut S, input: &mut UnicodeInput) -> Result<MutationResult, Error> {
|
||||
if input.0.bytes().is_empty() {
|
||||
if input.0.mutator_bytes().is_empty() {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
@ -477,7 +477,7 @@ where
|
||||
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let bytes = input.0.mutator_bytes();
|
||||
let meta = &input.1;
|
||||
if let Some((base, len)) = choose_start(state.rand_mut(), bytes, meta) {
|
||||
let substring = core::str::from_utf8(&bytes[base..][..len])?;
|
||||
@ -498,7 +498,7 @@ where
|
||||
}
|
||||
|
||||
input.0.splice(range, token.iter().copied());
|
||||
input.1 = extract_metadata(input.0.bytes());
|
||||
input.1 = extract_metadata(input.0.mutator_bytes());
|
||||
return Ok(MutationResult::Mutated);
|
||||
}
|
||||
|
||||
@ -536,10 +536,13 @@ mod test {
|
||||
)?;
|
||||
|
||||
for _ in 0..(1 << 12) {
|
||||
let metadata = extract_metadata(bytes.bytes());
|
||||
let metadata = extract_metadata(bytes.mutator_bytes());
|
||||
let mut input = (bytes, metadata);
|
||||
let _ = mutator.mutate(&mut state, &mut input);
|
||||
println!("{:?}", core::str::from_utf8(input.0.bytes()).unwrap());
|
||||
println!(
|
||||
"{:?}",
|
||||
core::str::from_utf8(input.0.mutator_bytes()).unwrap()
|
||||
);
|
||||
bytes = input.0;
|
||||
}
|
||||
|
||||
@ -568,10 +571,13 @@ mod test {
|
||||
)?;
|
||||
|
||||
for _ in 0..(1 << 12) {
|
||||
let metadata = extract_metadata(bytes.bytes());
|
||||
let metadata = extract_metadata(bytes.mutator_bytes());
|
||||
let mut input = (bytes, metadata);
|
||||
let _ = mutator.mutate(&mut state, &mut input);
|
||||
println!("{:?}", core::str::from_utf8(input.0.bytes()).unwrap());
|
||||
println!(
|
||||
"{:?}",
|
||||
core::str::from_utf8(input.0.mutator_bytes()).unwrap()
|
||||
);
|
||||
bytes = input.0;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ use crate::{
|
||||
corpus::HasCurrentCorpusId,
|
||||
events::EventFirer,
|
||||
executors::{Executor, HasObservers},
|
||||
inputs::HasMutatorResizableBytes,
|
||||
inputs::{HasMutatorBytes, ResizableMutator},
|
||||
mutators::mutations::buffer_copy,
|
||||
nonzero,
|
||||
observers::ObserversTuple,
|
||||
@ -81,7 +81,7 @@ where
|
||||
E: HasObservers + Executor<EM, I, S, Z>,
|
||||
S: HasCorpus<I> + HasMetadata + HasRand + HasNamedMetadata + HasCurrentCorpusId,
|
||||
E::Observers: ObserversTuple<I, S>,
|
||||
I: HasMutatorResizableBytes + Clone,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes + Clone,
|
||||
O: Hash,
|
||||
C: AsRef<O> + Named,
|
||||
{
|
||||
@ -158,7 +158,7 @@ where
|
||||
E: HasObservers + Executor<EM, I, S, Z>,
|
||||
E::Observers: ObserversTuple<I, S>,
|
||||
S: HasCorpus<I> + HasMetadata + HasRand + HasCurrentCorpusId + HasCurrentTestcase<I>,
|
||||
I: HasMutatorResizableBytes + Clone,
|
||||
I: ResizableMutator<u8> + HasMutatorBytes + Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn colorize(
|
||||
@ -179,7 +179,7 @@ where
|
||||
// Idea: No need to do this every time
|
||||
let orig_hash =
|
||||
Self::get_raw_map_hash_run(fuzzer, executor, state, manager, &input, observer_handle)?;
|
||||
let changed_bytes = changed.bytes_mut();
|
||||
let changed_bytes = changed.mutator_bytes_mut();
|
||||
let input_len = changed_bytes.len();
|
||||
|
||||
// Binary heap, pop is logN, insert is logN
|
||||
@ -208,8 +208,8 @@ where
|
||||
let copy_len = r.len();
|
||||
unsafe {
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
changed.bytes(),
|
||||
input.mutator_bytes_mut(),
|
||||
changed.mutator_bytes(),
|
||||
range_start,
|
||||
range_start,
|
||||
copy_len,
|
||||
@ -236,8 +236,8 @@ where
|
||||
// Revert the changes
|
||||
unsafe {
|
||||
buffer_copy(
|
||||
input.bytes_mut(),
|
||||
backup.bytes(),
|
||||
input.mutator_bytes_mut(),
|
||||
backup.mutator_bytes(),
|
||||
range_start,
|
||||
range_start,
|
||||
copy_len,
|
||||
@ -280,11 +280,11 @@ where
|
||||
}
|
||||
|
||||
if let Some(meta) = state.metadata_map_mut().get_mut::<TaintMetadata>() {
|
||||
meta.update(input.bytes().to_vec(), res);
|
||||
meta.update(input.mutator_bytes().to_vec(), res);
|
||||
|
||||
// println!("meta: {:#?}", meta);
|
||||
} else {
|
||||
let meta = TaintMetadata::new(input.bytes().to_vec(), res);
|
||||
let meta = TaintMetadata::new(input.mutator_bytes().to_vec(), res);
|
||||
state.add_metadata::<TaintMetadata>(meta);
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ where
|
||||
for mutation in mutations {
|
||||
let mut input_copy = state.current_input_cloned()?;
|
||||
for (index, new_byte) in mutation {
|
||||
input_copy.bytes_mut()[index] = new_byte;
|
||||
input_copy.mutator_bytes_mut()[index] = new_byte;
|
||||
}
|
||||
fuzzer.evaluate_filtered(state, executor, manager, input_copy)?;
|
||||
}
|
||||
|
@ -18,8 +18,7 @@ use crate::{
|
||||
executors::{Executor, HasObservers},
|
||||
feedbacks::map::MapNoveltiesMetadata,
|
||||
inputs::{
|
||||
BytesInput, GeneralizedInputMetadata, GeneralizedItem, HasMutatorBytes,
|
||||
HasMutatorResizableBytes,
|
||||
BytesInput, GeneralizedInputMetadata, GeneralizedItem, HasMutatorBytes, ResizableMutator,
|
||||
},
|
||||
mark_feature_time,
|
||||
observers::{CanTrack, MapObserver, ObserversTuple},
|
||||
@ -119,7 +118,7 @@ where
|
||||
let mut entry = state.corpus().get(corpus_id)?.borrow_mut();
|
||||
let input = entry.input_mut().as_mut().unwrap();
|
||||
|
||||
let payload: Vec<_> = input.bytes().iter().map(|&x| Some(x)).collect();
|
||||
let payload: Vec<_> = input.mutator_bytes().iter().map(|&x| Some(x)).collect();
|
||||
|
||||
if payload.len() > MAX_GENERALIZED_LEN {
|
||||
return Ok(());
|
||||
|
@ -9,7 +9,6 @@ use frida_gum::{
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use libafl::{
|
||||
corpus::Corpus,
|
||||
executors::{hooks::inprocess::InProcessHooks, inprocess::HasInProcessHooks},
|
||||
inputs::Input,
|
||||
state::{HasCurrentTestcase, HasSolutions},
|
||||
|
@ -767,9 +767,12 @@ where
|
||||
.match_first_type_mut::<DrCovRuntime>()
|
||||
{
|
||||
log::trace!("{basic_block_start:#016X}:{basic_block_size:X}");
|
||||
|
||||
// We can maybe remove the `basic_block_size as u64`` cast in the future
|
||||
#[allow(trivial_numeric_casts)]
|
||||
rt.drcov_basic_blocks.push(DrCovBasicBlock::new(
|
||||
basic_block_start,
|
||||
basic_block_start + basic_block_size as u64,
|
||||
basic_block_start + (basic_block_size as u64),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,10 @@ fn minimize_crash_with_mutator<M: Mutator<BytesInput, TMinState>>(
|
||||
}
|
||||
|
||||
let mut testcase = state.testcase_mut(id)?;
|
||||
let input = testcase.load_input(state.corpus())?.bytes().to_vec();
|
||||
let input = testcase
|
||||
.load_input(state.corpus())?
|
||||
.mutator_bytes()
|
||||
.to_vec();
|
||||
drop(testcase);
|
||||
if input.len() >= size {
|
||||
eprintln!(
|
||||
|
@ -11,7 +11,7 @@ use std::{
|
||||
|
||||
use libafl::{
|
||||
corpus::Corpus,
|
||||
inputs::{BytesInput, HasMutatorBytes, HasMutatorResizableBytes},
|
||||
inputs::{BytesInput, HasMutatorBytes, ResizableMutator},
|
||||
mutators::{
|
||||
ComposedByMutations, MutationId, MutationResult, Mutator, MutatorsTuple, ScheduledMutator,
|
||||
},
|
||||
@ -172,7 +172,7 @@ where
|
||||
drop(result);
|
||||
|
||||
if succeeded {
|
||||
let target = intermediary.bytes();
|
||||
let target = intermediary.mutator_bytes();
|
||||
if target.as_slice().len() > max_size {
|
||||
self.result
|
||||
.replace(Err(Error::illegal_state("Mutation result was too long!")))
|
||||
@ -322,7 +322,7 @@ where
|
||||
input: &mut BytesInput,
|
||||
) -> Result<MutationResult, Error> {
|
||||
let seed = state.rand_mut().next();
|
||||
let len_orig = input.bytes().len();
|
||||
let len_orig = input.mutator_bytes().len();
|
||||
let max_len = state.max_size();
|
||||
input.resize(max_len, 0);
|
||||
|
||||
@ -335,7 +335,7 @@ where
|
||||
});
|
||||
let new_len = unsafe {
|
||||
libafl_targets_libfuzzer_custom_mutator(
|
||||
input.bytes_mut().as_mut_ptr(),
|
||||
input.mutator_bytes_mut().as_mut_ptr(),
|
||||
len_orig,
|
||||
max_len,
|
||||
seed as u32,
|
||||
@ -408,7 +408,7 @@ where
|
||||
|
||||
let mut other_testcase = state.corpus().get_from_all(id)?.borrow_mut();
|
||||
let other = other_testcase.load_input(state.corpus())?;
|
||||
let data2 = Vec::from(other.bytes());
|
||||
let data2 = Vec::from(other.mutator_bytes());
|
||||
drop(other_testcase);
|
||||
|
||||
let seed = state.rand_mut().next();
|
||||
@ -428,7 +428,7 @@ where
|
||||
});
|
||||
let new_len = unsafe {
|
||||
libafl_targets_libfuzzer_custom_crossover(
|
||||
input.bytes_mut().as_mut_ptr(),
|
||||
input.mutator_bytes_mut().as_mut_ptr(),
|
||||
len_orig,
|
||||
data2.as_ptr(),
|
||||
data2.len(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user