Skip to content

Commit 028f4e1

Browse files
committed
Add changes suggested from code review.
Docs: make it explicit that we're ignoring the return value of the function under test. Add comments from libfuzzer explaining why one might want to keep inputs out of the corpus. Convert From<Corpus> to i32 to a pub fn to_libfuzzer_code() that is impl on Corpus to avoid accidental conversion.
1 parent dfe756f commit 028f4e1

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/lib.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ impl From<()> for Corpus {
3232
}
3333
}
3434

35-
impl From<Corpus> for i32 {
36-
fn from(value: Corpus) -> i32 {
37-
match value {
35+
impl Corpus {
36+
#[doc(hidden)]
37+
/// Convert this Corpus result into the [integer codes used by
38+
/// `libFuzzer`](https://llvm.org/docs/LibFuzzer.html#rejecting-unwanted-inputs).
39+
/// This is -1 for reject, 0 for keep.
40+
pub fn to_libfuzzer_code(self) -> i32 {
41+
match self {
3842
Corpus::Keep => 0,
3943
Corpus::Reject => -1,
4044
}
@@ -118,8 +122,17 @@ pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize
118122
///
119123
/// ## Rejecting Inputs
120124
///
121-
/// To indicate whether an input should be kept in or rejected from the corpus,
122-
/// return a [Corpus] value from your fuzz target. For example:
125+
/// It may be desirable to reject some inputs, i.e. to not add them to the
126+
/// corpus.
127+
///
128+
/// For example, when fuzzing an API consisting of parsing and other logic,
129+
/// one may want to allow only those inputs into the corpus that parse
130+
/// successfully. To indicate whether an input should be kept in or rejected
131+
/// from the corpus, return either [Corpus::Keep] or [Corpus::Reject] from your
132+
/// fuzz target. The default behavior (e.g. if `()` is returned) is to keep the
133+
/// input in the corpus.
134+
///
135+
/// For example:
123136
///
124137
/// ```no_run
125138
/// #![no_main]
@@ -134,7 +147,7 @@ pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize
134147
///
135148
/// let key = parts[0];
136149
/// let value = parts[1];
137-
/// my_crate::parse(key, value);
150+
/// let _result: Result<_, _> = my_crate::parse(key, value);
138151
/// Corpus::Keep
139152
/// );
140153
/// # mod my_crate { pub fn parse(_key: &str, _value: &str) -> Result<(), ()> { unimplemented!() } }
@@ -281,8 +294,8 @@ macro_rules! fuzz_target {
281294
Err(_) => return -1,
282295
};
283296

284-
let result: i32 = ::libfuzzer_sys::Corpus::from(run(data)).into();
285-
result
297+
let result = ::libfuzzer_sys::Corpus::from(run(data));
298+
result.to_libfuzzer_code()
286299
}
287300

288301
// See above for why this is split to a separate function.

0 commit comments

Comments
 (0)