Restart loading initial inputs even after a crash/timeout (#1040)

* Track initial inputs loading

* libfuzzer libpng

* fuzzbench

* fix no_std

* fix no_std

* clippy

* fuzzers
This commit is contained in:
Andrea Fioraldi 2023-02-03 11:56:47 +01:00 committed by GitHub
parent 86ab682e5a
commit eaf5ff9de0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 94 additions and 72 deletions

View File

@ -190,7 +190,7 @@ pub fn main() {
.expect("Failed to create the executor."); .expect("Failed to create the executor.");
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {

View File

@ -190,7 +190,7 @@ pub fn main() {
.expect("Failed to create the executor."); .expect("Failed to create the executor.");
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {

View File

@ -198,7 +198,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -313,7 +313,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -443,7 +443,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -196,7 +196,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -311,7 +311,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -441,7 +441,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &options.input)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -369,7 +369,7 @@ fn fuzz(
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -356,7 +356,7 @@ fn fuzz(
} }
} }
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -371,7 +371,7 @@ fn fuzz(
} }
} }
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -430,7 +430,7 @@ fn fuzz_binary(
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -647,7 +647,7 @@ fn fuzz_text(
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()]) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -318,7 +318,7 @@ pub fn LLVMFuzzerRunDriver(
let mut stages = tuple_list!(tracing, i2s, mutational); let mut stages = tuple_list!(tracing, i2s, mutational);
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
if input_dirs.is_empty() { if input_dirs.is_empty() {
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandBytesGenerator::new(32); let mut generator = RandBytesGenerator::new(32);

View File

@ -157,7 +157,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));

View File

@ -191,7 +191,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));

View File

@ -226,7 +226,7 @@ pub fn libafl_main() {
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input)
.unwrap_or_else(|e| { .unwrap_or_else(|e| {

View File

@ -190,7 +190,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));

View File

@ -217,7 +217,7 @@ pub fn libafl_main() {
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &opt.input)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &opt.input));

View File

@ -222,7 +222,7 @@ pub fn libafl_main() {
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, &opt.input)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &opt.input)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &opt.input));

View File

@ -136,7 +136,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", corpus_dirs));

View File

@ -142,7 +142,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", corpus_dirs));

View File

@ -179,7 +179,7 @@ fn fuzz(
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {corpus_dirs:?}")); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {corpus_dirs:?}"));

View File

@ -154,7 +154,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));

View File

@ -195,7 +195,7 @@ pub fn fuzz() {
// Wrap the executor to keep track of the timeout // Wrap the executor to keep track of the timeout
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -176,7 +176,7 @@ pub fn fuzz() {
// Wrap the executor to keep track of the timeout // Wrap the executor to keep track of the timeout
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -204,7 +204,7 @@ pub fn fuzz() {
// Wrap the executor to keep track of the timeout // Wrap the executor to keep track of the timeout
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -158,7 +158,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
} }
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
state state
.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs)
.unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs));

View File

@ -5,6 +5,7 @@ use core::{fmt::Debug, marker::PhantomData, time::Duration};
use std::{ use std::{
fs, fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
vec::Vec,
}; };
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
@ -194,6 +195,9 @@ pub struct StdState<I, C, R, SC> {
/// Performance statistics for this fuzzer /// Performance statistics for this fuzzer
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
introspection_monitor: ClientPerfMonitor, introspection_monitor: ClientPerfMonitor,
#[cfg(feature = "std")]
/// Remaining initial inputs to load, if any
remaining_initial_files: Option<Vec<PathBuf>>,
phantom: PhantomData<I>, phantom: PhantomData<I>,
} }
@ -347,23 +351,15 @@ where
R: Rand, R: Rand,
SC: Corpus<Input = <Self as UsesInput>::Input>, SC: Corpus<Input = <Self as UsesInput>::Input>,
{ {
/// Loads inputs from a directory. /// Decide if the state nust load the inputs
/// If `forced` is `true`, the value will be loaded, pub fn must_load_initial_inputs(&self) -> bool {
/// even if it's not considered to be `interesting`. self.corpus().count() == 0
pub fn load_from_directory<E, EM, Z>( || (self.remaining_initial_files.is_some()
&mut self, && !self.remaining_initial_files.as_ref().unwrap().is_empty())
fuzzer: &mut Z, }
executor: &mut E,
manager: &mut EM, /// List initial inputs from a directory.
in_dir: &Path, fn visit_initial_directory(files: &mut Vec<PathBuf>, in_dir: &Path) -> Result<(), Error> {
forced: bool,
loader: &mut dyn FnMut(&mut Z, &mut Self, &Path) -> Result<I, Error>,
) -> Result<(), Error>
where
E: UsesState<State = Self>,
EM: UsesState<State = Self>,
Z: Evaluator<E, EM, State = Self>,
{
for entry in fs::read_dir(in_dir)? { for entry in fs::read_dir(in_dir)? {
let entry = entry?; let entry = entry?;
let path = entry.path(); let path = entry.path();
@ -380,18 +376,9 @@ where
let attr = attributes?; let attr = attributes?;
if attr.is_file() && attr.len() > 0 { if attr.is_file() && attr.len() > 0 {
println!("Loading file {:?} ...", &path); files.push(path);
let input = loader(fuzzer, self, &path)?;
if forced {
let _ = fuzzer.add_input(self, executor, manager, input)?;
} else {
let (res, _) = fuzzer.evaluate_input(self, executor, manager, input)?;
if res == ExecuteInputResult::None {
println!("File {:?} was not interesting, skipped.", &path);
}
}
} else if attr.is_dir() { } else if attr.is_dir() {
self.load_from_directory(fuzzer, executor, manager, &path, forced, loader)?; Self::visit_initial_directory(files, in_dir)?;
} }
} }
@ -400,29 +387,48 @@ where
/// Loads initial inputs from the passed-in `in_dirs`. /// Loads initial inputs from the passed-in `in_dirs`.
/// If `forced` is true, will add all testcases, no matter what. /// If `forced` is true, will add all testcases, no matter what.
fn load_initial_inputs_internal<E, EM, Z>( fn load_initial_inputs_custom<E, EM, Z>(
&mut self, &mut self,
fuzzer: &mut Z, fuzzer: &mut Z,
executor: &mut E, executor: &mut E,
manager: &mut EM, manager: &mut EM,
in_dirs: &[PathBuf], in_dirs: &[PathBuf],
forced: bool, forced: bool,
loader: &mut dyn FnMut(&mut Z, &mut Self, &Path) -> Result<I, Error>,
) -> Result<(), Error> ) -> Result<(), Error>
where where
E: UsesState<State = Self>, E: UsesState<State = Self>,
EM: EventFirer<State = Self>, EM: EventFirer<State = Self>,
Z: Evaluator<E, EM, State = Self>, Z: Evaluator<E, EM, State = Self>,
{ {
for in_dir in in_dirs { if let Some(remaining) = self.remaining_initial_files.as_ref() {
self.load_from_directory( // everything was loaded
fuzzer, if remaining.is_empty() {
executor, return Ok(());
manager, }
in_dir, } else {
forced, let mut files = vec![];
&mut |_, _, path| I::from_file(path), for in_dir in in_dirs {
)?; Self::visit_initial_directory(&mut files, in_dir)?;
}
self.remaining_initial_files = Some(files);
} }
// TODO option to shuffle the initial files
while let Some(path) = self.remaining_initial_files.as_mut().unwrap().pop() {
println!("Loading file {:?} ...", &path);
let input = loader(fuzzer, self, &path)?;
if forced {
let _ = fuzzer.add_input(self, executor, manager, input)?;
} else {
let (res, _) = fuzzer.evaluate_input(self, executor, manager, input)?;
if res == ExecuteInputResult::None {
println!("File {:?} was not interesting, skipped.", &path);
}
}
}
manager.fire( manager.fire(
self, self,
Event::Log { Event::Log {
@ -449,7 +455,14 @@ where
EM: EventFirer<State = Self>, EM: EventFirer<State = Self>,
Z: Evaluator<E, EM, State = Self>, Z: Evaluator<E, EM, State = Self>,
{ {
self.load_initial_inputs_internal(fuzzer, executor, manager, in_dirs, true) self.load_initial_inputs_custom(
fuzzer,
executor,
manager,
in_dirs,
true,
&mut |_, _, path| I::from_file(path),
)
} }
/// Loads initial inputs from the passed-in `in_dirs`. /// Loads initial inputs from the passed-in `in_dirs`.
@ -465,7 +478,14 @@ where
EM: EventFirer<State = Self>, EM: EventFirer<State = Self>,
Z: Evaluator<E, EM, State = Self>, Z: Evaluator<E, EM, State = Self>,
{ {
self.load_initial_inputs_internal(fuzzer, executor, manager, in_dirs, false) self.load_initial_inputs_custom(
fuzzer,
executor,
manager,
in_dirs,
false,
&mut |_, _, path| I::from_file(path),
)
} }
} }
@ -574,6 +594,8 @@ where
max_size: DEFAULT_MAX_SIZE, max_size: DEFAULT_MAX_SIZE,
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
introspection_monitor: ClientPerfMonitor::new(), introspection_monitor: ClientPerfMonitor::new(),
#[cfg(feature = "std")]
remaining_initial_files: None,
phantom: PhantomData, phantom: PhantomData,
}; };
feedback.init_state(&mut state)?; feedback.init_state(&mut state)?;

View File

@ -196,7 +196,7 @@ impl<'a, const MAP_SIZE: usize> ForkserverBytesCoverageSugar<'a, MAP_SIZE> {
.expect("Failed to create the executor."); .expect("Failed to create the executor.");
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
if self.input_dirs.is_empty() { if self.input_dirs.is_empty() {
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandBytesGenerator::new(32); let mut generator = RandBytesGenerator::new(32);

View File

@ -216,7 +216,7 @@ where
); );
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
if self.input_dirs.is_empty() { if self.input_dirs.is_empty() {
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandBytesGenerator::new(32); let mut generator = RandBytesGenerator::new(32);

View File

@ -232,7 +232,7 @@ where
let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer)); let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer));
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
if self.input_dirs.is_empty() { if self.input_dirs.is_empty() {
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandBytesGenerator::new(32); let mut generator = RandBytesGenerator::new(32);
@ -335,7 +335,7 @@ where
let mut executor = TimeoutExecutor::new(executor, timeout); let mut executor = TimeoutExecutor::new(executor, timeout);
// In case the corpus is empty (on first run), reset // In case the corpus is empty (on first run), reset
if state.corpus().count() < 1 { if state.must_load_initial_inputs() {
if self.input_dirs.is_empty() { if self.input_dirs.is_empty() {
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandBytesGenerator::new(32); let mut generator = RandBytesGenerator::new(32);