Skip to content

Commit 459e74d

Browse files
Introduce NautilusUnparseToMetadataFeedback (AFLplusplus#3480)
* Introduce NautilusUnparseToMetadataFeedback * Add a note about the interestingness of NautilusUnparseToMetadataFeedback * Add implementation for track_hit_feedbacks on NautilusUnparseToMetadataFeedback * Re-add the unparsing logic to the feedback after accidental removal * Switch to manual invocation of the serdeany macro * Re-add last_result implementation * Clippy fixes * Rely on default behavior for is_interesting * Clippy
1 parent 96f8169 commit 459e74d

File tree

4 files changed

+259
-177
lines changed

4 files changed

+259
-177
lines changed

crates/libafl/src/feedbacks/nautilus.rs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Nautilus grammar mutator, see <https://github.com/nautilus-fuzz/nautilus>
2-
use alloc::{borrow::Cow, string::String};
2+
use alloc::{
3+
borrow::Cow,
4+
string::{String, ToString},
5+
};
36
use core::fmt::Debug;
47
use std::fs::create_dir_all;
58

@@ -10,7 +13,6 @@ use crate::{
1013
Error, HasMetadata,
1114
common::nautilus::grammartec::{chunkstore::ChunkStore, context::Context},
1215
corpus::{Corpus, Testcase},
13-
executors::ExitKind,
1416
feedbacks::{Feedback, StateInitializer},
1517
generators::NautilusContext,
1618
inputs::NautilusInput,
@@ -94,29 +96,72 @@ impl<EM, OT, S> Feedback<EM, NautilusInput, OT, S> for NautilusFeedback<'_>
9496
where
9597
S: HasMetadata + HasCorpus<NautilusInput>,
9698
{
97-
fn is_interesting(
99+
fn append_metadata(
98100
&mut self,
99-
_state: &mut S,
101+
state: &mut S,
100102
_manager: &mut EM,
101-
_input: &NautilusInput,
102103
_observers: &OT,
103-
_exit_kind: &ExitKind,
104-
) -> Result<bool, Error> {
104+
testcase: &mut Testcase<NautilusInput>,
105+
) -> Result<(), Error> {
106+
self.append_nautilus_metadata_to_state(state, testcase)
107+
}
108+
109+
#[cfg(feature = "track_hit_feedbacks")]
110+
fn last_result(&self) -> Result<bool, Error> {
105111
Ok(false)
106112
}
113+
}
114+
115+
#[derive(Serialize, Deserialize, Clone, Debug)]
116+
struct NautilusUnparseMetadata {
117+
unparsed: String,
118+
}
119+
120+
libafl_bolts::impl_serdeany!(NautilusUnparseMetadata);
121+
122+
/// Add the unparsed input to the testcase metadata. Useful e.g. if you want to have the input be unparsed on any solution automatically.
123+
///
124+
/// Returns a constant `false` for `is_interesting`.
125+
#[derive(Debug)]
126+
pub struct NautilusUnparseToMetadataFeedback<'a> {
127+
context: &'a NautilusContext,
128+
}
129+
130+
impl<'a> NautilusUnparseToMetadataFeedback<'a> {
131+
/// Create a new [`NautilusUnparseToMetadataFeedback`]
132+
#[must_use]
133+
pub fn new(context: &'a NautilusContext) -> Self {
134+
Self { context }
135+
}
136+
}
137+
impl<S> StateInitializer<S> for NautilusUnparseToMetadataFeedback<'_> {}
107138

139+
impl<EM, OT, S> Feedback<EM, NautilusInput, OT, S> for NautilusUnparseToMetadataFeedback<'_> {
108140
fn append_metadata(
109141
&mut self,
110-
state: &mut S,
142+
_state: &mut S,
111143
_manager: &mut EM,
112144
_observers: &OT,
113145
testcase: &mut Testcase<NautilusInput>,
114146
) -> Result<(), Error> {
115-
self.append_nautilus_metadata_to_state(state, testcase)
147+
let input = testcase.input().as_ref().unwrap().clone();
148+
let mut unparse_target = vec![];
149+
input.unparse(self.context, &mut unparse_target);
150+
let unparsed = String::from_utf8_lossy(&unparse_target).to_string();
151+
testcase.metadata_or_insert_with(|| NautilusUnparseMetadata { unparsed });
152+
153+
Ok(())
116154
}
117155

118156
#[cfg(feature = "track_hit_feedbacks")]
119157
fn last_result(&self) -> Result<bool, Error> {
120158
Ok(false)
121159
}
122160
}
161+
162+
impl Named for NautilusUnparseToMetadataFeedback<'_> {
163+
fn name(&self) -> &Cow<'static, str> {
164+
static NAME: Cow<'static, str> = Cow::Borrowed("NautilusUnparseToMetadataFeedback");
165+
&NAME
166+
}
167+
}

crates/libafl/src/generators/nautilus.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ impl NautilusContext {
101101
#[cfg(not(feature = "nautilus_py"))]
102102
{
103103
return Err(Error::illegal_argument(format!(
104-
"Feature `nautilus_py` is required to load grammar from {grammar_file:?}"
104+
"Feature `nautilus_py` is required to load grammar from {}",
105+
grammar_file.display()
105106
)));
106107
}
107108
}

0 commit comments

Comments
 (0)