// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Rust/LibFuzzer integration for Fuchsia

use {
    proc_macro::TokenStream,
    quote::{quote, quote_spanned},
    std::ops::Deref,
    syn::{
        parse::Error,
        parse_macro_input,
        FnArg::{self, Receiver, Typed},
        Type::Reference,
    },
};

/// Defines a fuzz target function.
///
/// This macro creates an exported function with a well-known symbol, `LLVMFuzzerTestOneInput`, as
/// defined in https://llvm.org/docs/LibFuzzer.html#fuzz-target. The macro can be used in two
/// ways:
///
/// The "manual" invocation simply takes a slice of bytes, uses them to exercise the API being
/// tested, and does not return anything. For example:
/// ```
/// use fuchsia_fuzzing::fuzz;
///
/// #[fuzz]
/// fn my_fuzzer(input: &[u8]) {
///     if let Some(x) = transform_bytes_to_something_else(input) {
///         do_something_with_my_api(x);
///     }
/// }
/// ```
///
/// The "automatic" invocation is more flexible: it can take one or more inputs of types with the
/// `Arbitrary` trait, use them to exercise the API being tested, and does not return anything.
/// For example:
/// ```
/// use {
///     arbitrary::Arbitrary,
///     fuchsia_fuzzing::fuzz,
/// };
///
/// #[derive(Arbitrary)]
/// pub enum Temp {
///     Celsius(i32),
///     Kelvin(u32),
/// }
///
/// #[derive(Arbitrary)]
/// pub struct Metrics {
///     name: Option<String>,
///     metrics: HashMap<String, Vec<Temp>>,
/// }
///
/// #[fuzz]
/// fn my_fuzzer(metrics: Metrics, log: Vec<String>) {
///    add_metrics_to_logs(metrics, logs);
/// }
/// ```
///
/// The recommended way to link the `LLVMFuzzerTestOneInput` into a fuzzer binary is to use the
/// `rustc_fuzzer` GN template from //build/rust/rustc_fuzzer.gni.
///
#[proc_macro_attribute]
pub fn fuzz(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let item = parse_macro_input!(item as syn::ItemFn);
    let syn::ItemFn { attrs, sig, vis: _, block } = item;
    let sig_ident = &sig.ident;
    let span = sig_ident.span();
    let name = sig_ident.to_string();

    // Validate function signature.
    if sig.inputs.len() == 0 {
        return Error::new(span, "expected at least 1 parameter").to_compile_error().into();
    }

    let first_input = sig.inputs.first().unwrap();
    if let Receiver(_r) = first_input {
        return Error::new(span, "fuzz target function cannot be a method")
            .to_compile_error()
            .into();
    }

    // Strip off a couple layers, and separate patterns and types.
    let num_inputs = sig.inputs.len();
    let mut input_pats = sig.inputs.iter().filter_map(|a| match a {
        Typed(p) => Some(p.pat.deref()),
        _ => None,
    });
    let mut input_tys = sig
        .inputs
        .iter()
        .filter_map(|a| match a {
            Typed(p) => Some(p.ty.deref()),
            _ => None,
        })
        .peekable();

    // Build an example of what an input to manual fuzz target function looks like.
    let manual_input: FnArg = syn::parse_quote! { input: &[u8] };
    let manual_input = match manual_input {
        Typed(p) => Some(p),
        _ => None,
    }
    .unwrap();

    // Detect which kind of fuzz target function we have, manual or automatic.
    let is_manual = if let (Reference(manual_ref), Reference(first_ref)) =
        (manual_input.ty.deref(), input_tys.peek().unwrap())
    {
        num_inputs == 1 && manual_ref.elem == first_ref.elem
    } else {
        false
    };

    let fuzz_target = if is_manual {
        // Manual fuzz target function: single byte slice input.
        let first_input_pat = input_pats.next();
        quote! {
            // Data must not be modified; make an immutable slice.
            let #first_input_pat = unsafe { std::slice::from_raw_parts(data, size) };
            let _ = #sig_ident(#first_input_pat);
        }
    } else {
        // Automatic fuzz target function: variable Arbitrary inputs.
        let input_tys_clone = input_tys.clone();
        let min_size = quote! { #(<#input_tys_clone as arbitrary::Arbitrary>::size_hint(0).0)+* };

        let input_pats_clone = input_pats.clone();
        let arbitrary_pats = quote! { #(Ok(#input_pats_clone)),* };

        let input_pats_clone = input_pats.clone();
        let invocation = quote! { #(#input_pats_clone),* };

        // It would be nice to use `quote`s interpolation repetition here, but we need to handle the
        // last input slightly differently than the others.
        let mut arbitrary_tys = quote! {};
        let input_tys_clone = input_tys.clone();
        for (i, input_ty) in input_tys_clone.enumerate() {
            if i != num_inputs - 1 {
                arbitrary_tys.extend(
                    quote! { <#input_ty as arbitrary::Arbitrary>::arbitrary(&mut unstructured), },
                );
            } else {
                arbitrary_tys
                    .extend(quote! { <#input_ty as arbitrary::Arbitrary>::arbitrary_take_rest(unstructured) });
            }
        }
        quote! {
            // Data must not be modified; make an immutable slice.
            let data = unsafe { std::slice::from_raw_parts(data, size) };
            // Early exit if not enough input bytes.
            if data.len() < #min_size {
                return 0;
            }
            let mut unstructured = arbitrary::Unstructured::new(data);
            if let ( #arbitrary_pats ) = ( #arbitrary_tys ) {
                let _ = #sig_ident(#invocation);
            }
        }
    };

    let output = quote_spanned! {span=>
        // This anonymous constant prevents Rust code from calling this symbol natively. It can
        // only be called by linking against the produced object file, e.g. with libFuzzer.
        const _: () = {
            // Creates a separate function to allow fuzzer authors to use `return`, etc.
            #[cfg(fuzz_target = #name)]
            #sig
            #block

            // This function wraps the fuzz target function above to create input parameters and
            // ensure the correct return value is used.
            #[cfg(fuzz_target = #name)]
            #[no_mangle]
            #(#attrs)*
            pub extern "C" fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32 {
                #fuzz_target
                0 // Always return zero per  https://llvm.org/docs/LibFuzzer.html#fuzz-target.
            }
        };
    };
    output.into()
}
