(fuzzer: &mut Fuzzer)
| 178 | |
| 179 | impl I2SReplaceStage { |
| 180 | fn start(fuzzer: &mut Fuzzer) -> Result<Self, StageExit> { |
| 181 | let input_id = fuzzer.input_id.ok_or(StageExit::Skip)?; |
| 182 | |
| 183 | // Colorization would have just run before this stage, so the current input is the colorized |
| 184 | // input. |
| 185 | fuzzer.state.input.seek_to_start(); |
| 186 | let mut base_input = fuzzer.state.input.clone(); |
| 187 | |
| 188 | Snapshot::restore_initial(fuzzer); |
| 189 | let (_, comparisons) = finder::capture_comparisons(fuzzer).ok_or(StageExit::Skip)?; |
| 190 | |
| 191 | if fuzzer.debug.cmplog && fuzzer.global.is_main_instance() { |
| 192 | comparisons |
| 193 | .save_to_file(&fuzzer.workdir.join(format!("cmplog/{input_id}.cmplog.txt"))) |
| 194 | .unwrap(); |
| 195 | if let Some(cmplog) = fuzzer.cmplog { |
| 196 | log_cmplog_data( |
| 197 | &mut fuzzer.vm, |
| 198 | cmplog, |
| 199 | &fuzzer.workdir.join(format!("cmplog/{input_id}.cmplog_raw.txt")), |
| 200 | ) |
| 201 | .unwrap(); |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | // For all non-empty streams, extend them a bit to avoid cases where changes that we make |
| 206 | // exit due to reaching the end of the input. |
| 207 | for (_, stream) in &mut base_input.streams { |
| 208 | if stream.bytes.len() > 8 { |
| 209 | let start: usize = fuzzer.rng.gen_range(0..stream.bytes.len()); |
| 210 | let len: usize = fuzzer.rng.gen_range(1..=(stream.bytes.len() - start).min(32)); |
| 211 | stream.bytes.extend_from_within(start..start + len); |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | let parent_prefix = match fuzzer.features.skip_prefix { |
| 216 | true => crate::utils::count_parent_prefix(fuzzer, input_id, true), |
| 217 | false => HashMap::default(), |
| 218 | }; |
| 219 | |
| 220 | Ok(I2SReplaceStage { |
| 221 | comparisons, |
| 222 | cursor: Position::new(fuzzer.features.strided_int_matches), |
| 223 | base_input, |
| 224 | parent_prefix, |
| 225 | tried_matches: HashMap::new(), |
| 226 | tried_replacements: HashMap::new(), |
| 227 | replacement: Replacement::default(), |
| 228 | total_execs: 0, |
| 229 | end_icount: fuzzer.vm.cpu.icount(), |
| 230 | attempted: vec![], |
| 231 | }) |
| 232 | } |
| 233 | |
| 234 | fn next_replacement(&mut self, fuzzer: &Fuzzer) -> Option<()> { |
| 235 | loop { |
nothing calls this directly
no test coverage detected