// 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;
use quote::{quote, quote_spanned};
use std::ops::Deref;
use syn::parse::Error;
use syn::parse_macro_input;
use syn::FnArg::{self, Receiver, Typed};
use syn::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()
}
