1use serde_derive::Deserialize;
10
11pub use crate::fuzz_config::FuzzConfig;
12pub use crate::mutators::{Mutation, MutationType};
13pub use crate::undo_buffer::UndoBuffer;
14
15pub mod fuzz_config;
16pub mod mutators;
17pub mod undo_buffer;
18
19#[derive(Clone, Debug, Deserialize)]
22pub enum Iterations {
23 Bits,
25 Bytes,
27 Unlimited,
29 Limited(usize),
31}
32
33#[derive(Clone, Debug, Deserialize)]
35pub struct Stage {
36 pub count: usize,
39 pub max: Option<usize>,
41 pub mutations: Vec<Mutation>,
43}
44
45impl Stage {
46 pub fn new(count: usize, mutations: Vec<Mutation>, max: Option<usize>) -> Self {
47 Self {
48 count,
49 mutations,
50 max,
51 }
52 }
53
54 pub fn is_done(&self) -> bool {
56 match self.max {
57 None => false,
58 Some(n) => self.count >= n,
59 }
60 }
61
62 pub fn next(&mut self) {
64 self.count += 1;
65 }
66
67 pub fn add_mutation(&mut self, mutation: Mutation) {
69 self.mutations.push(mutation);
70 }
71}
72
73impl Default for Stage {
74 fn default() -> Self {
76 Stage::new(0, vec![], None)
77 }
78}
79
80#[derive(Debug, Clone)]
82pub struct ByteMutator {
83 stages: Vec<Stage>,
85 cur_stage: usize,
87}
88
89impl ByteMutator {
90 pub fn new() -> Self {
92 Self {
93 stages: vec![],
94 cur_stage: 0,
95 }
96 }
97
98 pub fn with_stages(mut self, stages: Vec<Stage>) -> Self {
99 self.stages = stages;
100 self
101 }
102
103 pub fn new_from_config(config: FuzzConfig) -> Self {
105 Self {
106 stages: config.stages,
107 cur_stage: 0,
108 }
109 }
110
111 pub fn remaining_stages(&self) -> usize {
113 self.stages.len()
114 }
115
116 pub fn add_stage(&mut self, stage: Stage) {
118 self.stages.push(stage);
119 }
120
121 pub fn next(&mut self) {
125 let stage = match self.stages.get_mut(0) {
126 None => return, Some(s) => s,
128 };
129
130 stage.next();
131
132 if stage.is_done() {
133 self.stages.drain(..1);
134 }
135 }
136
137 pub fn mutate(&self, bytes: &mut [u8]) {
138 let stage = match self.stages.get(0) {
139 None => return, Some(s) => s,
141 };
142
143 for mutation in &stage.mutations {
144 match mutation.range {
145 Some((start, end)) => mutation.mutate(&mut bytes[start..end], stage.count),
146 None => mutation.mutate(bytes, stage.count),
147 };
148 }
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use crate::mutators::MutationType;
156
157 #[test]
158 fn mutator_stage() {
159 let mut byte_mutator = ByteMutator::new();
160
161 byte_mutator.add_stage(Stage::new(
162 0,
163 vec![Mutation {
164 range: None,
165 mutation: MutationType::BitFlipper { width: 1 },
166 }],
167 Some(10),
168 ));
169
170 assert_eq!(byte_mutator.remaining_stages(), 1);
171
172 for _ in 0..10 {
173 byte_mutator.next();
174 }
175
176 assert_eq!(byte_mutator.remaining_stages(), 0);
177 }
178}