Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove MutVecInput and MappedInput in Favour of Impls on References #2783

Merged
merged 8 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# 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`
-
- 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 `FunctionMappingMutator` `ToFunctionMappingMutatorMapper`

# 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> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

&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
14 changes: 5 additions & 9 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::{ToMappingMutatorMapper, ToOptionalMutatorMapper},
numeric::{int_mutators_no_crossover, mapped_int_mutators_crossover},
},
libafl_bolts::tuples::Map,
Expand Down Expand Up @@ -164,26 +164,22 @@ 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(ToMappingMutatorMapper::new(CustomInput::byte_array_mut));
riesentoaster marked this conversation as resolved.
Show resolved Hide resolved

// 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(
.map(ToOptionalMutatorMapper)
riesentoaster marked this conversation as resolved.
Show resolved Hide resolved
.map(ToMappingMutatorMapper::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(ToMappingMutatorMapper::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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this make using Vec a bit of a headache whenever HasMutatorBytes is in scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If, in the same file, one has HasMutatorBytes in scope and uses any of the duplicate functions on a Vec<u8> specifically, one would need to specify which implementation to use. Since one just forwards to the other, you can't really choose wrong, it's just annoying to write the extra code.

<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
Loading