summaryrefslogtreecommitdiff
path: root/fuzz/atom/parser/fuzz.rs
blob: b727c24740995a0e228699387e94e07896b496b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#![deny(unused_imports)]
#![allow(clippy::missing_safety_doc)]

use core::slice;
use gentoo_utils::{Parseable, atom::Atom};
use std::{
    env::{self},
    io::{self, Write},
};

#[unsafe(no_mangle)]
pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) -> i32 {
    let slice = unsafe { slice::from_raw_parts(input, len) };
    let str = str::from_utf8(slice).expect("expected ascii input");

    if str.chars().any(|c| !c.is_ascii_graphic()) {
        return -1;
    }

    let stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut buffer = String::new();

    writeln!(&mut stdout, "{str}").unwrap();

    stdin.read_line(&mut buffer).unwrap();

    let control = match buffer.as_str().trim() {
        "0" => Ok(()),
        "1" => Err(()),
        other => panic!("unexpected input from pipes: {other}"),
    };

    let gentoo_utils = Atom::parse(str);

    match (control, gentoo_utils) {
        (Ok(_), Ok(_)) => {
            if env::var("FUZZER_LOG").is_ok() {
                eprintln!("agreement that {str} is valid");
            }
        }
        (Err(_), Err(_)) => {
            if env::var("FUZZER_LOG").is_ok() {
                eprintln!("agreement that {str} is invalid");
            }
        }
        (Ok(_), Err(rest)) => {
            panic!("disagreement on {str}\ncontrol:Ok\ngentoo-utils:Err({rest})");
        }
        (Err(_), Ok(atom))
            if atom.usedeps().iter().any(|usedep| {
                atom.usedeps()
                    .iter()
                    .filter(|u| *usedep.flag() == *u.flag())
                    .count()
                    > 1
            }) =>
        {
            if env::var("FUZZER_LOG").is_ok() {
                eprintln!(
                    "disagreement, but we will allow it since its probably because of duplicated usdeps"
                );
            }
        }
        (Err(_), Ok(_)) => {
            panic!("disagreement on {str}\ncontrol:Err\ngentoo-utils:Ok")
        }
    }

    0
}