#![deny(missing_docs, missing_debug_implementations)]
pub use arbitrary;
extern "C" {
#[allow(improper_ctypes)]
fn rust_fuzzer_test_input(input: &[u8]);
}
#[doc(hidden)]
#[export_name = "LLVMFuzzerTestOneInput"]
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
let test_input = ::std::panic::catch_unwind(|| unsafe {
let data_slice = ::std::slice::from_raw_parts(data, size);
rust_fuzzer_test_input(data_slice);
});
if test_input.err().is_some() {
::std::process::abort();
}
0
}
#[doc(hidden)]
#[export_name = "LLVMFuzzerInitialize"]
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
let default_hook = ::std::panic::take_hook();
::std::panic::set_hook(Box::new(move |panic_info| {
default_hook(panic_info);
::std::process::abort();
}));
0
}
#[macro_export]
macro_rules! fuzz_target {
(|$bytes:ident| $body:block) => {
#[no_mangle]
pub extern "C" fn rust_fuzzer_test_input($bytes: &[u8]) {
if let Ok(path) = std::env::var("RUST_LIBFUZZER_DEBUG_PATH") {
use std::io::Write;
let mut file = std::fs::File::create(path)
.expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
writeln!(&mut file, "{:?}", $bytes)
.expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
return;
}
$body
}
};
(|$data:ident: &[u8]| $body:block) => {
fuzz_target!(|$data| $body);
};
(|$data:ident: $dty: ty| $body:block) => {
#[no_mangle]
pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) {
use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured};
if bytes.len() < <$dty as Arbitrary>::size_hint(0).0 {
return;
}
let mut u = Unstructured::new(bytes);
let data = <$dty as Arbitrary>::arbitrary_take_rest(u);
if let Ok(path) = std::env::var("RUST_LIBFUZZER_DEBUG_PATH") {
use std::io::Write;
let mut file = std::fs::File::create(path)
.expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
(match data {
Ok(data) => writeln!(&mut file, "{:#?}", data),
Err(err) => writeln!(&mut file, "Arbitrary Error: {}", err),
})
.expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
return;
}
let $data = match data {
Ok(d) => d,
Err(_) => return,
};
$body
}
};
}