Skip to content

Commit

Permalink
Remove MutVecInput and MappedInput in Favour of Impls on References (#…
Browse files Browse the repository at this point in the history
…2783)

* Remove MutVecInput and MappedInput

* Rename mapping mutators

* Update MIGRATION.md

* Fix test in docs

* Rename mapping mutators mappers

* Fix MIGRATION.md

* Fix docs link
  • Loading branch information
riesentoaster authored Dec 19, 2024
1 parent e46cf8a commit 5d70216
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 528 deletions.
18 changes: 11 additions & 7 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Pre 0.9 -> 0.9
- [Migrating from LibAFL <0.9 to 0.9](https://aflplus.plus/libafl-book/design/migration-0.9.html)

# 0.14.0 -> 0.14.1
- Removed `with_observers` from `Executor` trait.
- `MmapShMemProvider::new_shmem_persistent` has been removed in favour of `MmapShMem::persist`. You probably want to do something like this: `let shmem = MmapShMemProvider::new()?.new_shmem(size)?.persist()?;`

# 0.14.1 -> 0.15.0
- `MmapShMem::new` and `MmapShMemProvider::new_shmem_with_id` now take `AsRef<Path>` instead of a byte array for the filename/id.
- The closure passed to a `DumpToDiskStage` now provides the `Testcase` instead of just the `Input`.
- `StatsStage` is deleted, and it is superceded by `AflStatsStage`
-
- Renamed and changed mapping mutators to take borrows directly instead of `MappedInput`s. See `baby_fuzzer_custom_input` for example usage
- Related: `MutVecInput` is deprecated in favor of directly using `&mut Vec<u8>`
- Related: `MappedInputFunctionMappingMutator` and `ToMappedInputFunctionMappingMutatorMapper` have been removed as now duplicates of `MappingMutator` (previously `FunctionMappingMutator`) and `ToMappingMutator` (previously `ToFunctionMappingMutatorMapper`)
- Related: `ToOptionMappingMutatorMapper` and `ToFunctionMappingMutatorMapper` have been renamed to `ToOptionalMutator` and `ToMappingMutator` respectively

# 0.14.0 -> 0.14.1
- Removed `with_observers` from `Executor` trait.
- `MmapShMemProvider::new_shmem_persistent` has been removed in favour of `MmapShMem::persist`. You probably want to do something like this: `let shmem = MmapShMemProvider::new()?.new_shmem(size)?.persist()?;`

# Pre 0.9 -> 0.9
- [Migrating from LibAFL <0.9 to 0.9](https://aflplus.plus/libafl-book/design/migration-0.9.html)
20 changes: 10 additions & 10 deletions fuzzers/structure_aware/baby_fuzzer_custom_input/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{borrow::Cow, hash::Hash};
use libafl::{
corpus::CorpusId,
generators::{Generator, RandBytesGenerator},
inputs::{value::MutI16Input, BytesInput, HasTargetBytes, Input, MutVecInput},
inputs::{BytesInput, HasTargetBytes, Input},
mutators::{MutationResult, Mutator},
state::HasRand,
Error, SerdeAny,
Expand Down Expand Up @@ -36,28 +36,28 @@ impl Input for CustomInput {

impl CustomInput {
/// Returns a mutable reference to the byte array
pub fn byte_array_mut(&mut self) -> MutVecInput<'_> {
(&mut self.byte_array).into()
pub fn byte_array_mut(&mut self) -> &mut Vec<u8> {
&mut self.byte_array
}

/// Returns an immutable reference to the byte array
pub fn byte_array(&self) -> &[u8] {
pub fn byte_array(&self) -> &Vec<u8> {
&self.byte_array
}

/// Returns a mutable reference to the optional byte array
pub fn optional_byte_array_mut(&mut self) -> Option<MutVecInput<'_>> {
self.optional_byte_array.as_mut().map(|e| e.into())
pub fn optional_byte_array_mut(&mut self) -> &mut Option<Vec<u8>> {
&mut self.optional_byte_array
}

/// Returns an immutable reference to the optional byte array
pub fn optional_byte_array(&self) -> Option<&[u8]> {
self.optional_byte_array.as_deref()
pub fn optional_byte_array(&self) -> &Option<Vec<u8>> {
&self.optional_byte_array
}

/// Returns a mutable reference to the number
pub fn num_mut(&mut self) -> MutI16Input<'_> {
(&mut self.num).into()
pub fn num_mut(&mut self) -> &mut i16 {
&mut self.num
}

/// Returns an immutable reference to the number
Expand Down
16 changes: 5 additions & 11 deletions fuzzers/structure_aware/baby_fuzzer_custom_input/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use libafl_bolts::{
use {
libafl::mutators::{
havoc_mutations::{havoc_crossover_with_corpus_mapper, havoc_mutations_no_crossover},
mapping::{ToMappedInputFunctionMappingMutatorMapper, ToOptionMappingMutatorMapper},
mapping::{ToMappingMutator, ToOptionalMutator},
numeric::{int_mutators_no_crossover, mapped_int_mutators_crossover},
},
libafl_bolts::tuples::Map,
Expand Down Expand Up @@ -164,26 +164,20 @@ pub fn main() {
// Creating mutators that will operate on input.byte_array
let mapped_mutators = havoc_mutations_no_crossover()
.merge(havoc_crossover_with_corpus_mapper(CustomInput::byte_array))
.map(ToMappedInputFunctionMappingMutatorMapper::new(
CustomInput::byte_array_mut,
));
.map(ToMappingMutator::new(CustomInput::byte_array_mut));

// Creating mutators that will operate on input.optional_byte_array
let optional_mapped_mutators = havoc_mutations_no_crossover()
.merge(havoc_crossover_with_corpus_mapper(
CustomInput::optional_byte_array,
))
.map(ToOptionMappingMutatorMapper)
.map(ToMappedInputFunctionMappingMutatorMapper::new(
CustomInput::optional_byte_array_mut,
));
.map(ToOptionalMutator)
.map(ToMappingMutator::new(CustomInput::optional_byte_array_mut));

// Creating mutators that will operate on input.num
let int_mutators = int_mutators_no_crossover()
.merge(mapped_int_mutators_crossover(CustomInput::num))
.map(ToMappedInputFunctionMappingMutatorMapper::new(
CustomInput::num_mut,
));
.map(ToMappingMutator::new(CustomInput::num_mut));
(mapped_mutators, optional_mapped_mutators, int_mutators)
};

Expand Down
2 changes: 1 addition & 1 deletion libafl/src/inputs/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl HasMutatorBytes for BytesInput {
}

fn extend<'a, I: IntoIterator<Item = &'a u8>>(&mut self, iter: I) {
self.as_mut().extend(iter);
<Vec<u8> as Extend<I::Item>>::extend(self.as_mut(), iter);
}

fn splice<R, I>(&mut self, range: R, replace_with: I) -> vec::Splice<'_, I::IntoIter>
Expand Down
14 changes: 2 additions & 12 deletions libafl/src/inputs/bytessub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use libafl_bolts::{
HasLen,
};

use crate::inputs::{HasMutatorBytes, MappedInput};
use crate::inputs::HasMutatorBytes;

/// 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.
Expand Down Expand Up @@ -201,23 +201,14 @@ where
self.range.len()
}
}

impl<I> MappedInput for BytesSubInput<'_, I> {
type Type<'b>
= BytesSubInput<'b, I>
where
Self: 'b;
}

#[cfg(test)]
mod tests {

use alloc::vec::Vec;

use libafl_bolts::HasLen;

use crate::{
inputs::{BytesInput, HasMutatorBytes, MutVecInput, NopInput},
inputs::{BytesInput, HasMutatorBytes, NopInput},
mutators::{havoc_mutations_no_crossover, MutatorsTuple},
state::NopState,
};
Expand Down Expand Up @@ -346,7 +337,6 @@ mod tests {
#[test]
fn test_bytessubinput_use_vec() {
let mut test_vec = vec![0, 1, 2, 3, 4];
let mut test_vec = MutVecInput::from(&mut test_vec);
let mut sub_vec = test_vec.sub_input(1..2);
drop(sub_vec.drain(..));
assert_eq!(test_vec.len(), 4);
Expand Down
59 changes: 33 additions & 26 deletions libafl/src/inputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use core::{
clone::Clone,
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut, RangeBounds},
ops::{DerefMut, RangeBounds},
};
#[cfg(feature = "std")]
use std::{fs::File, hash::Hash, io::Read, path::Path};
Expand All @@ -50,7 +50,6 @@ use libafl_bolts::{
#[cfg(feature = "nautilus")]
pub use nautilus::*;
use serde::{Deserialize, Serialize};
use value::ValueMutRefInput;

use crate::corpus::CorpusId;

Expand Down Expand Up @@ -198,36 +197,44 @@ pub trait HasMutatorBytes: HasLen {
}
}

/// Mapping types to themselves, used to ensure lifetime consistency for mapped mutators.
///
/// Specifically, this is for [`Input`] types that are owned wrappers around a reference. The lifetime of the associated type should be the same as the reference.
pub trait MappedInput {
/// The type for which this trait is implemented
type Type<'a>
impl HasMutatorBytes for Vec<u8> {
fn bytes(&self) -> &[u8] {
self.as_ref()
}

fn bytes_mut(&mut self) -> &mut [u8] {
self.as_mut()
}

fn resize(&mut self, new_len: usize, value: u8) {
<Vec<u8>>::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 splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
where
Self: 'a;
}
R: RangeBounds<usize>,
I: IntoIterator<Item = u8>,
{
<Vec<u8>>::splice(self, range, replace_with)
}

impl<T> MappedInput for Option<T>
where
T: MappedInput,
{
type Type<'a>
= Option<T::Type<'a>>
fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
where
T: 'a;
R: RangeBounds<usize>,
{
<Vec<u8>>::drain(self, range)
}
}

/// A wrapper type that allows us to use mutators for Mutators for `&mut `[`Vec`].
pub type MutVecInput<'a> = ValueMutRefInput<'a, Vec<u8>>;

impl HasLen for MutVecInput<'_> {
fn len(&self) -> usize {
self.deref().len()
}
}
#[deprecated(since = "0.15.0", note = "Use &mut Vec<u8> directly")]
pub type MutVecInput<'a> = &'a mut Vec<u8>;

impl HasMutatorBytes for MutVecInput<'_> {
impl HasMutatorBytes for &mut Vec<u8> {
fn bytes(&self) -> &[u8] {
self
}
Expand All @@ -241,7 +248,7 @@ impl HasMutatorBytes for MutVecInput<'_> {
}

fn extend<'b, I: IntoIterator<Item = &'b u8>>(&mut self, iter: I) {
self.deref_mut().extend(iter);
<Vec<u8> as Extend<I::Item>>::extend(self, iter);
}

fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
Expand Down
Loading

0 comments on commit 5d70216

Please sign in to comment.