(&mut self, fuzzer: &mut Fuzzer)
| 135 | } |
| 136 | |
| 137 | fn extend_current_input(&mut self, fuzzer: &mut Fuzzer) { |
| 138 | let num_extensions = crate::utils::rand_pow2(&mut fuzzer.rng, self.log2_max_extensions); |
| 139 | let input = &mut fuzzer.state.input; |
| 140 | let before_len = input.total_bytes(); |
| 141 | for (&addr, &factor) in &self.streams_to_mutate { |
| 142 | let stream = &mut input.streams.entry(addr).or_default(); |
| 143 | |
| 144 | let local_dict = fuzzer.dict.entry(addr).or_default(); |
| 145 | local_dict.compute_weights(); |
| 146 | let dict = DictionaryRef { local: local_dict, global: &fuzzer.global_dict }; |
| 147 | |
| 148 | // We extend all streams we end at the same number of times. This may result in some |
| 149 | // streams ending up oversized, however this will be fixed by the auto-trim step. |
| 150 | for _ in 0..num_extensions { |
| 151 | if stream.bytes.len() >= config::MAX_STREAM_LEN { |
| 152 | continue; |
| 153 | } |
| 154 | let kind = extend_input_by_rand( |
| 155 | &mut fuzzer.rng, |
| 156 | factor, |
| 157 | dict, |
| 158 | &mut stream.bytes, |
| 159 | self.extension_limit, |
| 160 | ); |
| 161 | fuzzer.state.mutation_kinds.push((addr, kind).into()); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | if input.total_bytes() <= before_len { |
| 166 | tracing::warn!( |
| 167 | "[{}] input length ({before_len} bytes) did not increase after applying extensions ({num_extensions} extensions of {} streams)\nmutations: {:x?}", |
| 168 | fuzzer.input_id.unwrap_or(0), |
| 169 | self.streams_to_mutate.len(), |
| 170 | fuzzer.state.mutation_kinds |
| 171 | ); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | fn prepare_new_input(&mut self, fuzzer: &mut Fuzzer) -> Result<(), StageExit> { |
| 176 | const RARE_EXTENSIONS: bool = true; |
no test coverage detected