@@ -245,14 +245,64 @@ macro_rules! fuzz_target {
245245 } ;
246246 } ;
247247
248+ ( |mut $bytes: ident| $body: expr) => {
249+ const _: ( ) = {
250+ /// Auto-generated function
251+ #[ no_mangle]
252+ pub extern "C" fn rust_fuzzer_test_input( bytes: & [ u8 ] ) -> i32 {
253+ // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
254+ // formatting of the input to that file. This is only intended for
255+ // `cargo fuzz`'s use!
256+
257+ // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
258+ if let Some ( path) = $crate:: RUST_LIBFUZZER_DEBUG_PATH . get( ) {
259+ use std:: io:: Write ;
260+ let mut file = std:: fs:: File :: create( path)
261+ . expect( "failed to create `RUST_LIBFUZZER_DEBUG_PATH` file" ) ;
262+ writeln!( & mut file, "{:?}" , bytes)
263+ . expect( "failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file" ) ;
264+ return 0 ;
265+ }
266+
267+ __libfuzzer_sys_run( bytes) ;
268+ 0
269+ }
270+
271+ // Split out the actual fuzzer into a separate function which is
272+ // tagged as never being inlined. This ensures that if the fuzzer
273+ // panics there's at least one stack frame which is named uniquely
274+ // according to this specific fuzzer that this is embedded within.
275+ //
276+ // Systems like oss-fuzz try to deduplicate crashes and without this
277+ // panics in separate fuzzers can accidentally appear the same
278+ // because each fuzzer will have a function called
279+ // `rust_fuzzer_test_input`. By using a normal Rust function here
280+ // it's named something like `the_fuzzer_name::_::__libfuzzer_sys_run` which should
281+ // ideally help prevent oss-fuzz from deduplicate fuzz bugs across
282+ // distinct targets accidentally.
283+ #[ inline( never) ]
284+ fn __libfuzzer_sys_run( mut $bytes: & [ u8 ] ) {
285+ $body
286+ }
287+ } ;
288+ } ;
289+
248290 ( |$data: ident: & [ u8 ] | $body: expr) => {
249291 $crate:: fuzz_target!( |$data| $body) ;
250292 } ;
251293
294+ ( |mut $data: ident: & [ u8 ] | $body: expr) => {
295+ $crate:: fuzz_target!( |mut $data| $body) ;
296+ } ;
297+
252298 ( |$data: ident: $dty: ty| $body: expr) => {
253299 $crate:: fuzz_target!( |$data: $dty| -> ( ) { $body } ) ;
254300 } ;
255301
302+ ( |mut $data: ident: $dty: ty| $body: expr) => {
303+ $crate:: fuzz_target!( |mut $data: $dty| -> ( ) { $body } ) ;
304+ } ;
305+
256306 ( |$data: ident: $dty: ty| -> $rty: ty $body: block) => {
257307 const _: ( ) = {
258308 /// Auto-generated function
@@ -306,6 +356,60 @@ macro_rules! fuzz_target {
306356 }
307357 } ;
308358 } ;
359+
360+ ( |mut $data: ident: $dty: ty| -> $rty: ty $body: block) => {
361+ const _: ( ) = {
362+ /// Auto-generated function
363+ #[ no_mangle]
364+ pub extern "C" fn rust_fuzzer_test_input( bytes: & [ u8 ] ) -> i32 {
365+ use $crate:: arbitrary:: { Arbitrary , Unstructured } ;
366+
367+ // Early exit if we don't have enough bytes for the `Arbitrary`
368+ // implementation. This helps the fuzzer avoid exploring all the
369+ // different not-enough-input-bytes paths inside the `Arbitrary`
370+ // implementation. Additionally, it exits faster, letting the fuzzer
371+ // get to longer inputs that actually lead to interesting executions
372+ // quicker.
373+ if bytes. len( ) < <$dty as Arbitrary >:: size_hint( 0 ) . 0 {
374+ return -1 ;
375+ }
376+
377+ let mut u = Unstructured :: new( bytes) ;
378+ let data = <$dty as Arbitrary >:: arbitrary_take_rest( u) ;
379+
380+ // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
381+ // formatting of the input to that file. This is only intended for
382+ // `cargo fuzz`'s use!
383+
384+ // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
385+ if let Some ( path) = $crate:: RUST_LIBFUZZER_DEBUG_PATH . get( ) {
386+ use std:: io:: Write ;
387+ let mut file = std:: fs:: File :: create( path)
388+ . expect( "failed to create `RUST_LIBFUZZER_DEBUG_PATH` file" ) ;
389+ ( match data {
390+ Ok ( data) => writeln!( & mut file, "{:#?}" , data) ,
391+ Err ( err) => writeln!( & mut file, "Arbitrary Error: {}" , err) ,
392+ } )
393+ . expect( "failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file" ) ;
394+ return -1 ;
395+ }
396+
397+ let data = match data {
398+ Ok ( d) => d,
399+ Err ( _) => return -1 ,
400+ } ;
401+
402+ let result = :: libfuzzer_sys:: Corpus :: from( __libfuzzer_sys_run( data) ) ;
403+ result. to_libfuzzer_code( )
404+ }
405+
406+ // See above for why this is split to a separate function.
407+ #[ inline( never) ]
408+ fn __libfuzzer_sys_run( mut $data: $dty) -> $rty {
409+ $body
410+ }
411+ } ;
412+ } ;
309413}
310414
311415/// Define a custom mutator.
0 commit comments