Skip to content

Commit 0c45075

Browse files
authored
Merge pull request #50 from fitzgen/clean-ups
Clean ups
2 parents 864aabf + cc49a08 commit 0c45075

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn main() {
1818
.filter(|p| p.extension().map(|ext| ext == "cpp") == Some(true))
1919
.collect::<Vec<_>>();
2020
for source in sources.iter() {
21+
println!("cargo:rerun-if-changed={}", source.display());
2122
build.file(source.to_str().unwrap());
2223
}
2324
build.flag("-std=c++11");

src/lib.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1+
//! Bindings to [libFuzzer](http://llvm.org/docs/LibFuzzer.html): a runtime for
2+
//! coverage-guided fuzzing.
3+
//!
4+
//! See [the `cargo-fuzz`
5+
//! guide](https://rust-fuzz.github.io/book/cargo-fuzz.html) for a usage
6+
//! tutorial.
7+
//!
8+
//! The main export of this crate is [the `fuzz_target!`
9+
//! macro](./macro.fuzz_target.html), which allows you to define targets for
10+
//! libFuzzer to exercise.
11+
12+
#![deny(missing_docs, missing_debug_implementations)]
13+
114
pub use arbitrary;
215

316
extern "C" {
4-
#![allow(improper_ctypes)] // we do not actually cross the FFI bound here
5-
17+
// We do not actually cross the FFI bound here.
18+
#[allow(improper_ctypes)]
619
fn rust_fuzzer_test_input(input: &[u8]);
720
}
821

22+
#[doc(hidden)]
923
#[export_name = "LLVMFuzzerTestOneInput"]
1024
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
1125
let test_input = ::std::panic::catch_unwind(|| unsafe {
@@ -20,6 +34,7 @@ pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
2034
0
2135
}
2236

37+
#[doc(hidden)]
2338
#[export_name = "LLVMFuzzerInitialize"]
2439
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
2540
// Registers a panic hook that aborts the process before unwinding.
@@ -38,6 +53,66 @@ pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize
3853
0
3954
}
4055

56+
/// Define a fuzz target.
57+
///
58+
/// ## Example
59+
///
60+
/// This example takes a `&[u8]` slice and attempts to parse it. The parsing
61+
/// might fail and return an `Err`, but it shouldn't ever panic or segfault.
62+
///
63+
/// ```no_run
64+
/// #![no_main]
65+
///
66+
/// use libfuzzer_sys::fuzz_target;
67+
///
68+
/// // Note: `|input|` is short for `|input: &[u8]|`.
69+
/// fuzz_target!(|input| {
70+
/// let _result: Result<_, _> = my_crate::parse(input);
71+
/// });
72+
/// # mod my_crate { pub fn parse(_: &[u8]) -> Result<(), ()> { unimplemented!() } }
73+
/// ```
74+
///
75+
/// ## Arbitrary Input Types
76+
///
77+
/// The input is a `&[u8]` slice by default, but you can take arbitrary input
78+
/// types, as long as the type implements [the `arbitrary` crate's `Arbitrary`
79+
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html) (which is
80+
/// also re-exported as `libfuzzer_sys::arbitrary::Arbitrary` for convenience).
81+
///
82+
/// For example, if you wanted to take an arbitrary RGB color, you could do the
83+
/// following:
84+
///
85+
/// ```no_run
86+
/// #![no_main]
87+
///
88+
/// use libfuzzer_sys::{arbitrary::{Arbitrary, Unstructured}, fuzz_target};
89+
///
90+
/// #[derive(Debug)]
91+
/// pub struct Rgb {
92+
/// r: u8,
93+
/// g: u8,
94+
/// b: u8,
95+
/// }
96+
///
97+
/// impl Arbitrary for Rgb {
98+
/// fn arbitrary<U>(raw: &mut U) -> Result<Self, U::Error>
99+
/// where
100+
/// U: Unstructured + ?Sized
101+
/// {
102+
/// let mut buf = [0; 3];
103+
/// raw.fill_buffer(&mut buf)?;
104+
/// let r = buf[0];
105+
/// let g = buf[1];
106+
/// let b = buf[2];
107+
/// Ok(Rgb { r, g, b })
108+
/// }
109+
/// }
110+
///
111+
/// // Write a fuzz target that works with RGB colors instead of raw bytes.
112+
/// fuzz_target!(|color: Rgb| {
113+
/// my_crate::convert_color(color);
114+
/// });
115+
/// # mod my_crate { fn convert_color(_: super::Rgb) {} }
41116
#[macro_export]
42117
macro_rules! fuzz_target {
43118
(|$bytes:ident| $body:block) => {
@@ -46,9 +121,11 @@ macro_rules! fuzz_target {
46121
$body
47122
}
48123
};
124+
49125
(|$data:ident: &[u8]| $body:block) => {
50126
fuzz_target!(|$data| $body);
51127
};
128+
52129
(|$data:ident: $dty: ty| $body:block) => {
53130
#[no_mangle]
54131
pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) {

0 commit comments

Comments
 (0)