introduce CustomFilenameToTestcaseFeedback (#2256)

* introduce CustomTestcaseFilenameFeedback

* rename CustomTestcaseFilenameFeedback to CustomFilenameToTestcaseFeedback

* rename custom_testcase_filename to custom_filename

---------

Co-authored-by: Romain Malmain <romain.malmain@pm.me>
This commit is contained in:
Aarnav 2024-05-30 19:05:53 +02:00 committed by GitHub
parent 1102ea0fe7
commit 7b90873305
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 139 additions and 3 deletions

View File

@ -0,0 +1,134 @@
use alloc::{borrow::Cow, string::String};
use core::{
fmt::{self, Debug, Formatter},
marker::PhantomData,
};
use libafl_bolts::Named;
use serde::{Deserialize, Serialize};
use crate::{
corpus::Testcase,
events::EventFirer,
executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory},
inputs::Input,
observers::ObserversTuple,
state::State,
Error,
};
/// A [`CustomFilenameToTestcaseFeedback`] takes a closure which returns a filename for the testcase.
/// Is never interesting (use with an Eager OR).
/// Note: Use only in conjunction with a `Corpus` type that writes to disk.
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
/// `Objectives`, vice versa for `Feedback`.
#[derive(Serialize, Deserialize)]
pub struct CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Closure that returns the filename.
func: F,
phantomm: PhantomData<(I, S)>,
}
impl<F, I, S> CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Create a new [`CustomFilenameToTestcaseFeedback`].
pub fn new(func: F) -> Self {
Self {
func,
phantomm: PhantomData,
}
}
}
impl<F, I, S, T> FeedbackFactory<CustomFilenameToTestcaseFeedback<F, I, S>, S, T>
for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error> + Clone,
{
fn create_feedback(&self, _ctx: &T) -> CustomFilenameToTestcaseFeedback<F, I, S> {
Self {
func: self.func.clone(),
phantomm: self.phantomm,
}
}
}
impl<F, I, S> Named for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilenameToTestcaseFeedback");
&NAME
}
}
impl<F, I, S> Debug for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("CustomFilenameToTestcaseFeedback")
.finish_non_exhaustive()
}
}
impl<F, I, S> Feedback<S> for CustomFilenameToTestcaseFeedback<F, I, S>
where
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<S::Input>) -> Result<String, Error>,
I: Input,
{
#[allow(clippy::wrong_self_convention)]
#[inline]
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &I,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
{
Ok(false)
}
fn append_metadata<EM, OT>(
&mut self,
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<<S>::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
EM: EventFirer<State = S>,
{
*testcase.filename_mut() = Some((self.func)(state, testcase)?);
Ok(())
}
#[cfg(feature = "track_hit_feedbacks")]
#[inline]
fn last_result(&self) -> Result<bool, Error> {
Ok(false)
}
}

View File

@ -39,7 +39,12 @@ use crate::{
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod concolic; pub mod concolic;
#[cfg(feature = "std")]
/// The module for `CustomFilenameToTestcaseFeedback`
pub mod custom_filename;
pub mod differential; pub mod differential;
/// The module for list feedback
pub mod list;
pub mod map; pub mod map;
#[cfg(feature = "nautilus")] #[cfg(feature = "nautilus")]
pub mod nautilus; pub mod nautilus;
@ -49,9 +54,6 @@ pub mod new_hash_feedback;
pub mod stdio; pub mod stdio;
pub mod transferred; pub mod transferred;
/// The module for list feedback
pub mod list;
/// Feedbacks evaluate the observers. /// Feedbacks evaluate the observers.
/// Basically, they reduce the information provided by an observer to a value, /// Basically, they reduce the information provided by an observer to a value,
/// indicating the "interestingness" of the last run. /// indicating the "interestingness" of the last run.