trident_config/
lib.rs

1pub mod afl;
2pub mod argument;
3pub mod constants;
4pub mod fuzz;
5pub mod honggfuzz;
6
7use afl::*;
8use constants::*;
9use fuzz::*;
10use honggfuzz::*;
11
12pub mod utils;
13
14use serde::Deserialize;
15use std::{fs, io};
16use thiserror::Error;
17use utils::{discover_root, resolve_path};
18
19#[derive(Error, Debug)]
20pub enum Error {
21    #[error("invalid workspace")]
22    BadWorkspace,
23    #[error("{0:?}")]
24    Anyhow(#[from] anyhow::Error),
25    #[error("{0:?}")]
26    Io(#[from] io::Error),
27    #[error("{0:?}")]
28    Toml(#[from] toml::de::Error),
29}
30
31#[derive(Debug, Deserialize, Clone)]
32pub struct TridentConfig {
33    pub honggfuzz: Option<HonggFuzz>,
34    pub afl: Option<Afl>,
35    pub fuzz: Option<Fuzz>,
36}
37
38impl Default for TridentConfig {
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44impl TridentConfig {
45    pub fn new() -> Self {
46        let root = discover_root().expect("failed to find the root folder");
47        let s = fs::read_to_string(root.join(TRIDENT_TOML).as_path())
48            .expect("failed to read the Trident config file");
49        let _config: TridentConfig =
50            toml::from_str(&s).expect("failed to parse the Trident config file");
51        _config
52    }
53
54    // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
55    // honggfuzz
56    pub fn get_honggfuzz_args(&self, cli_input: String) -> String {
57        if let Some(honggfuzz) = &self.honggfuzz {
58            let mut args = honggfuzz.get_collect_fuzz_args();
59            args.push(cli_input);
60            args.join(" ")
61        } else {
62            String::default()
63        }
64    }
65    pub fn get_honggfuzz_workspace(&self) -> String {
66        let path = self
67            .honggfuzz
68            .as_ref()
69            .map(|honggfuzz| honggfuzz.get_hfuzz_workspace().value)
70            .unwrap_or_else(|| HFUZZ_WORKSPACE_DEFAULT_HFUZZ.to_string());
71        let full_path = resolve_path(&path);
72        full_path.to_str().unwrap().to_string()
73    }
74    pub fn get_honggfuzz_target_dir(&self) -> String {
75        let path = self
76            .honggfuzz
77            .as_ref()
78            .map(|honggfuzz| honggfuzz.get_cargo_target_dir().value)
79            .unwrap_or_else(|| CARGO_TARGET_DIR_DEFAULT_HFUZZ.to_string());
80        let full_path = resolve_path(&path);
81        full_path.to_str().unwrap().to_string()
82    }
83    // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
84    // afl
85    pub fn get_afl_target_dir(&self) -> String {
86        let path = self
87            .afl
88            .as_ref()
89            .map(|afl| afl.get_cargo_target_dir().value.unwrap())
90            .unwrap_or_else(|| CARGO_TARGET_DIR_DEFAULT_AFL.to_string());
91        let full_path = resolve_path(&path);
92        full_path.to_str().unwrap().to_string()
93    }
94    pub fn get_afl_target_path(&self, target: &str) -> String {
95        let mut afl_target_dir = self.get_afl_target_dir();
96        afl_target_dir.push_str("/debug/");
97        afl_target_dir.push_str(target);
98        afl_target_dir
99    }
100    pub fn get_afl_workspace_in(&self) -> String {
101        let path = self
102            .afl
103            .as_ref()
104            .map(|afl| afl.get_workspace_in().value.unwrap())
105            .unwrap_or_else(|| AFL_WORKSPACE_DEFAULT_IN.to_string());
106        let full_path = resolve_path(&path);
107        full_path.to_str().unwrap().to_string()
108    }
109    pub fn get_afl_workspace_out(&self) -> String {
110        let path = self
111            .afl
112            .as_ref()
113            .map(|afl| afl.get_workspace_out().value.unwrap())
114            .unwrap_or_else(|| AFL_WORKSPACE_DEFAULT_OUT.to_string());
115        let full_path = resolve_path(&path);
116        full_path.to_str().unwrap().to_string()
117    }
118    pub fn get_afl_build_args(&self) -> Vec<String> {
119        self.afl
120            .as_ref()
121            .map(|afl| afl.get_collect_build_args())
122            .unwrap_or_default()
123    }
124    pub fn get_afl_fuzz_args(&self) -> Vec<String> {
125        self.afl
126            .as_ref()
127            .map(|afl| afl.get_collect_fuzz_args())
128            .unwrap_or_default()
129    }
130
131    pub fn get_initial_seed(&self) -> Vec<AflSeed> {
132        self.afl
133            .as_ref()
134            .map(|afl| afl.get_seeds())
135            .unwrap_or_else(|| vec![AflSeed::default()])
136    }
137    // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
138    // fuzz
139    pub fn get_fuzzing_with_stats(&self) -> bool {
140        self.fuzz
141            .as_ref()
142            .map(|fuzz| fuzz.get_fuzzing_with_stats())
143            .unwrap_or_default()
144    }
145    pub fn get_allow_duplicate_txs(&self) -> bool {
146        self.fuzz
147            .as_ref()
148            .map(|fuzz| fuzz.get_allow_duplicate_txs())
149            .unwrap_or_default()
150    }
151
152    pub fn programs(&self) -> Vec<FuzzProgram> {
153        self.fuzz
154            .as_ref()
155            .map(|fuzz| {
156                if let Some(programs) = &fuzz.programs {
157                    programs.iter().map(FuzzProgram::from).collect()
158                } else {
159                    Vec::default()
160                }
161            })
162            .unwrap_or_default()
163    }
164    pub fn accounts(&self) -> Vec<FuzzAccount> {
165        self.fuzz
166            .as_ref()
167            .map(|fuzz| {
168                if let Some(accounts) = &fuzz.accounts {
169                    accounts.iter().map(FuzzAccount::from).collect()
170                } else {
171                    Vec::default()
172                }
173            })
174            .unwrap_or_default()
175    }
176}