libafl_bolts: more rands
improvements (#2096)
* rands: add missing inline directives See: - https://nnethercote.github.io/perf-book/inlining.html - https://users.rust-lang.org/t/enable-cross-crate-inlining-without-suggesting-inlining/55004/6 * rands: better fast_bound() signature
This commit is contained in:
parent
0f42efa12b
commit
1e8667a9f9
@ -67,8 +67,8 @@ impl From<CorpusId> for usize {
|
||||
#[macro_export]
|
||||
macro_rules! random_corpus_id {
|
||||
($corpus:expr, $rand:expr) => {{
|
||||
let cnt = $corpus.count() as u64;
|
||||
let nth = $rand.below(cnt) as usize;
|
||||
let cnt = $corpus.count();
|
||||
let nth = $rand.below(cnt);
|
||||
$corpus.nth(nth)
|
||||
}};
|
||||
}
|
||||
@ -78,8 +78,8 @@ macro_rules! random_corpus_id {
|
||||
#[macro_export]
|
||||
macro_rules! random_corpus_id_with_disabled {
|
||||
($corpus:expr, $rand:expr) => {{
|
||||
let cnt = $corpus.count_all() as u64;
|
||||
let nth = $rand.below(cnt) as usize;
|
||||
let cnt = $corpus.count_all();
|
||||
let nth = $rand.below(cnt);
|
||||
$corpus.nth_from_all(nth)
|
||||
}};
|
||||
}
|
||||
|
@ -76,13 +76,13 @@ where
|
||||
.last()
|
||||
.map_or(self.automaton.init_state, |last| {
|
||||
let triggers = &self.automaton.pda[last.state];
|
||||
let idx = state.rand_mut().below(triggers.len() as u64) as usize;
|
||||
let idx = state.rand_mut().below(triggers.len());
|
||||
triggers[idx].dest
|
||||
});
|
||||
|
||||
while current_state != final_state {
|
||||
let triggers = &self.automaton.pda[current_state];
|
||||
let idx = state.rand_mut().below(triggers.len() as u64) as usize;
|
||||
let idx = state.rand_mut().below(triggers.len());
|
||||
let trigger = &triggers[idx];
|
||||
input
|
||||
.terminals_mut()
|
||||
|
@ -101,7 +101,7 @@ where
|
||||
S: HasRand,
|
||||
{
|
||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||
let mut size = state.rand_mut().below(self.max_size as u64);
|
||||
let mut size = state.rand_mut().below(self.max_size);
|
||||
if size == 0 {
|
||||
size = 1;
|
||||
}
|
||||
@ -141,7 +141,7 @@ where
|
||||
S: HasRand,
|
||||
{
|
||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||
let mut size = state.rand_mut().below(self.max_size as u64);
|
||||
let mut size = state.rand_mut().below(self.max_size);
|
||||
if size == 0 {
|
||||
size = 1;
|
||||
}
|
||||
|
@ -159,8 +159,8 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDeleteMutator {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let off = state.rand_mut().below(size as u64) as usize;
|
||||
let len = state.rand_mut().below((size - off) as u64) as usize;
|
||||
let off = state.rand_mut().below(size);
|
||||
let len = state.rand_mut().below(size - off);
|
||||
input.codes_mut().drain(off..off + len);
|
||||
|
||||
Ok(MutationResult::Mutated)
|
||||
@ -198,8 +198,8 @@ where
|
||||
if size == 0 {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
let off = state.rand_mut().below((size + 1) as u64) as usize;
|
||||
let mut len = 1 + state.rand_mut().below(min(16, size as u64)) as usize;
|
||||
let off = state.rand_mut().below(size + 1);
|
||||
let mut len = 1 + state.rand_mut().below(min(16, size));
|
||||
|
||||
if size + len > max_size {
|
||||
if max_size > size {
|
||||
@ -212,7 +212,7 @@ where
|
||||
let from = if size == len {
|
||||
0
|
||||
} else {
|
||||
state.rand_mut().below((size - len) as u64) as usize
|
||||
state.rand_mut().below(size - len)
|
||||
};
|
||||
|
||||
input.codes_mut().resize(size + len, 0);
|
||||
@ -254,9 +254,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let from = state.rand_mut().below(size as u64) as usize;
|
||||
let to = state.rand_mut().below(size as u64) as usize;
|
||||
let len = 1 + state.rand_mut().below((size - max(from, to)) as u64) as usize;
|
||||
let from = state.rand_mut().below(size);
|
||||
let to = state.rand_mut().below(size);
|
||||
let len = 1 + state.rand_mut().below(size - max(from, to));
|
||||
|
||||
unsafe {
|
||||
buffer_self_copy(input.codes_mut(), from, to, len);
|
||||
@ -310,9 +310,9 @@ where
|
||||
}
|
||||
|
||||
let max_size = state.max_size();
|
||||
let from = state.rand_mut().below(other_size as u64) as usize;
|
||||
let to = state.rand_mut().below(size as u64) as usize;
|
||||
let mut len = 1 + state.rand_mut().below((other_size - from) as u64) as usize;
|
||||
let from = state.rand_mut().below(other_size);
|
||||
let to = state.rand_mut().below(size);
|
||||
let mut len = 1 + state.rand_mut().below(other_size - from);
|
||||
|
||||
if size + len > max_size {
|
||||
if max_size > size {
|
||||
@ -383,9 +383,9 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let from = state.rand_mut().below(other_size as u64) as usize;
|
||||
let len = state.rand_mut().below(min(other_size - from, size) as u64) as usize;
|
||||
let to = state.rand_mut().below((size - len) as u64) as usize;
|
||||
let from = state.rand_mut().below(other_size);
|
||||
let len = state.rand_mut().below(min(other_size - from, size));
|
||||
let to = state.rand_mut().below(size - len);
|
||||
|
||||
let other_testcase = state.corpus().get_from_all(idx)?.borrow_mut();
|
||||
// no need to load the input again, it'll already be present at this point.
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
Error, HasMetadata,
|
||||
};
|
||||
|
||||
const RECUR_THRESHOLD: u64 = 5;
|
||||
const RECUR_THRESHOLD: usize = 5;
|
||||
|
||||
/// A random mutator for grammar fuzzing
|
||||
#[derive(Debug)]
|
||||
@ -41,7 +41,7 @@ where
|
||||
input: &mut GramatronInput,
|
||||
) -> Result<MutationResult, Error> {
|
||||
if !input.terminals().is_empty() {
|
||||
let size = state.rand_mut().below(input.terminals().len() as u64 + 1) as usize;
|
||||
let size = state.rand_mut().below(input.terminals().len() + 1);
|
||||
input.terminals_mut().truncate(size);
|
||||
}
|
||||
if self.generator.append_generated_terminals(input, state) > 0 {
|
||||
@ -119,7 +119,7 @@ where
|
||||
|
||||
let idx = random_corpus_id!(state.corpus(), state.rand_mut());
|
||||
|
||||
let insert_at = state.rand_mut().below(input.terminals().len() as u64) as usize;
|
||||
let insert_at = state.rand_mut().below(input.terminals().len());
|
||||
|
||||
let rand_num = state.rand_mut().next();
|
||||
|
||||
@ -212,11 +212,11 @@ where
|
||||
let chosen_nums = self.counters.get(&chosen).unwrap().0;
|
||||
|
||||
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
||||
let mut first = state.rand_mut().below(chosen_nums as u64 - 1) as i64;
|
||||
let mut first = state.rand_mut().below(chosen_nums - 1) as i64;
|
||||
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
||||
let mut second = state
|
||||
.rand_mut()
|
||||
.between(first as u64 + 1, chosen_nums as u64 - 1) as i64;
|
||||
.between(first as usize + 1, chosen_nums - 1) as i64;
|
||||
|
||||
let mut idx_1 = 0;
|
||||
let mut idx_2 = 0;
|
||||
|
@ -252,10 +252,10 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
let token_find = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let mut token_replace = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let token_find = state.rand_mut().below(tokens_len);
|
||||
let mut token_replace = state.rand_mut().below(tokens_len);
|
||||
if token_find == token_replace {
|
||||
token_replace = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
token_replace = state.rand_mut().below(tokens_len);
|
||||
}
|
||||
|
||||
let stop_at_first = state.rand_mut().coinflip(0.5);
|
||||
@ -268,7 +268,7 @@ where
|
||||
let mut mutated = MutationResult::Skipped;
|
||||
|
||||
let gen = generalised_meta.generalized_mut();
|
||||
let rand_idx = fast_bound(rand_idx, gen.len() as u64) as usize;
|
||||
let rand_idx = fast_bound(rand_idx, gen.len());
|
||||
|
||||
'first: for item in &mut gen[..rand_idx] {
|
||||
if let GeneralizedItem::Bytes(bytes) = item {
|
||||
@ -360,10 +360,8 @@ where
|
||||
{
|
||||
self.gap_indices.push(i);
|
||||
}
|
||||
let min_idx =
|
||||
self.gap_indices[state.rand_mut().below(self.gap_indices.len() as u64) as usize];
|
||||
let max_idx =
|
||||
self.gap_indices[state.rand_mut().below(self.gap_indices.len() as u64) as usize];
|
||||
let min_idx = self.gap_indices[state.rand_mut().below(self.gap_indices.len())];
|
||||
let max_idx = self.gap_indices[state.rand_mut().below(self.gap_indices.len())];
|
||||
|
||||
let (min_idx, max_idx) = (min(min_idx, max_idx), max(min_idx, max_idx));
|
||||
|
||||
|
@ -368,7 +368,7 @@ where
|
||||
mode: MOptMode,
|
||||
finds_before: usize,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
max_stack_pow: usize,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ where
|
||||
pub fn new(
|
||||
state: &mut S,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
max_stack_pow: usize,
|
||||
swarm_num: usize,
|
||||
) -> Result<Self, Error> {
|
||||
if !state.has_metadata::<MOpt>() {
|
||||
|
@ -44,7 +44,7 @@ where
|
||||
if input.parts().is_empty() {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let selected = state.rand_mut().below(input.parts().len() as u64) as usize;
|
||||
let selected = state.rand_mut().below(input.parts().len());
|
||||
let mutated = input.part_mut(selected).unwrap();
|
||||
self.mutate(state, mutated)
|
||||
}
|
||||
@ -153,7 +153,7 @@ where
|
||||
.map(|(idx, part)| (idx, part.bytes().len()));
|
||||
|
||||
if let Some((part_idx, size)) = maybe_size {
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, other_size, min(other_size, size - target));
|
||||
|
||||
let [part, chosen] = match part_idx.cmp(&choice) {
|
||||
@ -195,7 +195,7 @@ where
|
||||
drop(other_testcase);
|
||||
let size = part.bytes().len();
|
||||
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, other_size, min(other_size, size - target));
|
||||
|
||||
let other_testcase = state.corpus().get(idx)?.borrow_mut();
|
||||
@ -257,7 +257,7 @@ where
|
||||
.map(|(idx, part)| (idx, part.bytes().len()));
|
||||
|
||||
if let Some((part_idx, size)) = maybe_size {
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, other_size, min(other_size, size - target));
|
||||
|
||||
let [part, chosen] = match part_idx.cmp(&choice) {
|
||||
@ -299,7 +299,7 @@ where
|
||||
drop(other_testcase);
|
||||
let size = part.bytes().len();
|
||||
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, other_size, min(other_size, size - target));
|
||||
|
||||
let other_testcase = state.corpus().get(idx)?.borrow_mut();
|
||||
|
@ -65,9 +65,9 @@ pub fn buffer_set<T: Clone>(data: &mut [T], from: usize, len: usize, val: T) {
|
||||
/// This problem corresponds to: <https://oeis.org/A059036>
|
||||
#[inline]
|
||||
pub fn rand_range<S: HasRand>(state: &mut S, upper: usize, max_len: usize) -> Range<usize> {
|
||||
let len = 1 + state.rand_mut().below(max_len as u64) as usize;
|
||||
let len = 1 + state.rand_mut().below(max_len);
|
||||
// sample from [1..upper + len]
|
||||
let mut offset2 = 1 + state.rand_mut().below((upper + len - 1) as u64) as usize;
|
||||
let mut offset2 = 1 + state.rand_mut().below(upper + len - 1);
|
||||
let offset1 = offset2.saturating_sub(len);
|
||||
if offset2 > upper {
|
||||
offset2 = upper;
|
||||
@ -77,7 +77,7 @@ pub fn rand_range<S: HasRand>(state: &mut S, upper: usize, max_len: usize) -> Ra
|
||||
}
|
||||
|
||||
/// The max value that will be added or subtracted during add mutations
|
||||
pub const ARITH_MAX: u64 = 35;
|
||||
pub const ARITH_MAX: usize = 35;
|
||||
|
||||
/// Interesting 8-bit values from AFL
|
||||
pub const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
|
||||
@ -413,8 +413,8 @@ macro_rules! interesting_mutator_impl {
|
||||
Ok(MutationResult::Skipped)
|
||||
} else {
|
||||
let bytes = input.bytes_mut();
|
||||
let upper_bound = (bytes.len() + 1 - size_of::<$size>()) as u64;
|
||||
let idx = state.rand_mut().below(upper_bound) as usize;
|
||||
let upper_bound = (bytes.len() + 1 - size_of::<$size>());
|
||||
let idx = state.rand_mut().below(upper_bound);
|
||||
let val = *state.rand_mut().choose(&$interesting) as $size;
|
||||
let new_bytes = match state.rand_mut().choose(&[0, 1]) {
|
||||
0 => val.to_be_bytes(),
|
||||
@ -548,8 +548,8 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let mut amount = 1 + state.rand_mut().below(16) as usize;
|
||||
let offset = state.rand_mut().below(size as u64 + 1) as usize;
|
||||
let mut amount = 1 + state.rand_mut().below(16);
|
||||
let offset = state.rand_mut().below(size + 1);
|
||||
|
||||
if size + amount > max_size {
|
||||
if max_size > size {
|
||||
@ -559,7 +559,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let val = input.bytes()[state.rand_mut().below(size as u64) as usize];
|
||||
let val = input.bytes()[state.rand_mut().below(size)];
|
||||
|
||||
input.bytes_mut().resize(size + amount, 0);
|
||||
unsafe {
|
||||
@ -602,8 +602,8 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let mut amount = 1 + state.rand_mut().below(16) as usize;
|
||||
let offset = state.rand_mut().below(size as u64 + 1) as usize;
|
||||
let mut amount = 1 + state.rand_mut().below(16);
|
||||
let offset = state.rand_mut().below(size + 1);
|
||||
|
||||
if size + amount > max_size {
|
||||
if max_size > size {
|
||||
@ -733,7 +733,7 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, size, size - target);
|
||||
|
||||
unsafe {
|
||||
@ -776,7 +776,7 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
// make sure that the sampled range is both in bounds and of an acceptable size
|
||||
let max_insert_len = min(size - target, state.max_size() - size);
|
||||
let range = rand_range(state, size, min(16, max_insert_len));
|
||||
@ -1091,7 +1091,7 @@ where
|
||||
}
|
||||
|
||||
let range = rand_range(state, other_size, min(other_size, max_size - size));
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
|
||||
let other_testcase = state.corpus().get_from_all(idx)?.borrow_mut();
|
||||
// No need to load the input again, it'll still be cached.
|
||||
@ -1172,7 +1172,7 @@ where
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
|
||||
let target = state.rand_mut().below(size as u64) as usize;
|
||||
let target = state.rand_mut().below(size);
|
||||
let range = rand_range(state, other_size, min(other_size, size - target));
|
||||
|
||||
let other_testcase = state.corpus().get_from_all(idx)?.borrow_mut();
|
||||
@ -1243,13 +1243,13 @@ where
|
||||
let (f, l) = locate_diffs(input.bytes(), other.bytes());
|
||||
|
||||
if f != l && f >= 0 && l >= 2 {
|
||||
(f as u64, l as u64)
|
||||
(f as usize, l as usize)
|
||||
} else {
|
||||
return Ok(MutationResult::Skipped);
|
||||
}
|
||||
};
|
||||
|
||||
let split_at = state.rand_mut().between(first_diff, last_diff) as usize;
|
||||
let split_at = state.rand_mut().between(first_diff, last_diff);
|
||||
|
||||
let other_testcase = state.corpus().get_from_all(idx)?.borrow_mut();
|
||||
// Input will already be loaded.
|
||||
|
@ -115,7 +115,7 @@ where
|
||||
{
|
||||
name: Cow<'static, str>,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
max_stack_pow: usize,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ where
|
||||
/// Get the next mutation to apply
|
||||
fn schedule(&self, state: &mut S, _: &I) -> MutationId {
|
||||
debug_assert!(self.mutations.len() != 0);
|
||||
state.rand_mut().below(self.mutations.len() as u64).into()
|
||||
state.rand_mut().below(self.mutations.len()).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ where
|
||||
}
|
||||
|
||||
/// Create a new [`StdScheduledMutator`] instance specifying mutations and the maximun number of iterations
|
||||
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: u64) -> Self {
|
||||
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: usize) -> Self {
|
||||
StdScheduledMutator {
|
||||
name: Cow::from(format!(
|
||||
"StdScheduledMutator[{}]",
|
||||
@ -437,7 +437,7 @@ where
|
||||
/// Get the next mutation to apply
|
||||
fn schedule(&self, state: &mut S, _: &I) -> MutationId {
|
||||
debug_assert!(MT::LEN != 0);
|
||||
state.rand_mut().below(MT::LEN as u64).into()
|
||||
state.rand_mut().below(MT::LEN).into()
|
||||
}
|
||||
|
||||
fn scheduled_mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||
|
@ -66,7 +66,7 @@ fn choose_start<R: Rand>(
|
||||
bytes: &[u8],
|
||||
meta: &StringIdentificationMetadata,
|
||||
) -> Option<(usize, usize)> {
|
||||
let idx = rand.below(bytes.len() as u64) as usize;
|
||||
let idx = rand.below(bytes.len());
|
||||
let mut options = Vec::new();
|
||||
for (start, range) in meta.ranges() {
|
||||
if idx
|
||||
@ -83,9 +83,9 @@ fn choose_start<R: Rand>(
|
||||
_ => {
|
||||
// bias towards longer strings
|
||||
options.sort_by_cached_key(|(_, entries)| entries.count_ones());
|
||||
let selected = libafl_bolts::math::integer_sqrt(
|
||||
rand.below((options.len() * options.len()) as u64),
|
||||
) as usize;
|
||||
let selected =
|
||||
libafl_bolts::math::integer_sqrt(rand.below(options.len() * options.len()) as u64)
|
||||
as usize;
|
||||
Some((options[selected].0, options[selected].1.len()))
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,7 @@ fn choose_category_range<R: Rand>(
|
||||
string: &str,
|
||||
) -> (Range<usize>, &'static [(u32, u32)]) {
|
||||
let chars = string.char_indices().collect::<Vec<_>>();
|
||||
let idx = rand.below(chars.len() as u64) as usize;
|
||||
let idx = rand.below(chars.len());
|
||||
let c = chars[idx].1;
|
||||
|
||||
// figure out the categories for this char
|
||||
@ -160,7 +160,7 @@ fn choose_category_range<R: Rand>(
|
||||
)
|
||||
});
|
||||
let options = categories.len() * categories.len();
|
||||
let selected_idx = libafl_bolts::math::integer_sqrt(rand.below(options as u64)) as usize;
|
||||
let selected_idx = libafl_bolts::math::integer_sqrt(rand.below(options) as u64) as usize;
|
||||
|
||||
let selected = categories[selected_idx];
|
||||
|
||||
@ -177,7 +177,7 @@ fn choose_category_range<R: Rand>(
|
||||
|
||||
fn choose_subcategory_range<R: Rand>(rand: &mut R, string: &str) -> (Range<usize>, (u32, u32)) {
|
||||
let chars = string.char_indices().collect::<Vec<_>>();
|
||||
let idx = rand.below(chars.len() as u64) as usize;
|
||||
let idx = rand.below(chars.len());
|
||||
let c = chars[idx].1;
|
||||
|
||||
// figure out the categories for this char
|
||||
@ -197,7 +197,7 @@ fn choose_subcategory_range<R: Rand>(rand: &mut R, string: &str) -> (Range<usize
|
||||
|
||||
subcategories.sort_by_key(|&(min, max)| Reverse(max - min + 1));
|
||||
let options = subcategories.len() * subcategories.len();
|
||||
let selected_idx = libafl_bolts::math::integer_sqrt(rand.below(options as u64)) as usize;
|
||||
let selected_idx = libafl_bolts::math::integer_sqrt(rand.below(options) as u64) as usize;
|
||||
let selected = subcategories[selected_idx];
|
||||
|
||||
#[cfg(test)]
|
||||
@ -238,7 +238,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
||||
return MutationResult::Skipped;
|
||||
}
|
||||
|
||||
let replace_len = state.rand_mut().below(MAX_CHARS as u64) as usize;
|
||||
let replace_len = state.rand_mut().below(MAX_CHARS);
|
||||
let orig_len = range.end - range.start;
|
||||
if input.0.len() - orig_len + replace_len > state.max_size() {
|
||||
return MutationResult::Skipped;
|
||||
@ -298,15 +298,15 @@ where
|
||||
core::str::from_utf8(&bytes[range.clone()])
|
||||
);
|
||||
|
||||
let options: u64 = category
|
||||
let options: usize = category
|
||||
.iter()
|
||||
.map(|&(start, end)| u64::from(end) - u64::from(start) + 1)
|
||||
.map(|&(start, end)| end as usize - start as usize + 1)
|
||||
.sum();
|
||||
let char_gen = |state: &mut S| loop {
|
||||
let mut selected = state.rand_mut().below(options);
|
||||
for &(min, max) in category {
|
||||
if let Some(next_selected) =
|
||||
selected.checked_sub(u64::from(max) - u64::from(min) + 1)
|
||||
selected.checked_sub(max as usize - min as usize + 1)
|
||||
{
|
||||
selected = next_selected;
|
||||
} else if let Some(new_c) = char::from_u32(selected as u32 + min) {
|
||||
@ -357,7 +357,7 @@ where
|
||||
core::str::from_utf8(&bytes[range.clone()])
|
||||
);
|
||||
|
||||
let options: u64 = u64::from(subcategory.1) - u64::from(subcategory.0) + 1;
|
||||
let options = subcategory.1 as usize - subcategory.0 as usize + 1;
|
||||
let char_gen = |state: &mut S| loop {
|
||||
let selected = state.rand_mut().below(options);
|
||||
if let Some(new_c) = char::from_u32(selected as u32 + subcategory.0) {
|
||||
@ -401,7 +401,7 @@ where
|
||||
}
|
||||
meta.tokens().len()
|
||||
};
|
||||
let token_idx = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let meta = &input.1;
|
||||
@ -461,7 +461,7 @@ where
|
||||
}
|
||||
meta.tokens().len()
|
||||
};
|
||||
let token_idx = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let bytes = input.0.bytes();
|
||||
let meta = &input.1;
|
||||
|
@ -318,10 +318,10 @@ where
|
||||
}
|
||||
meta.tokens().len()
|
||||
};
|
||||
let token_idx = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let size = input.bytes().len();
|
||||
let off = state.rand_mut().below((size + 1) as u64) as usize;
|
||||
let off = state.rand_mut().below(size + 1);
|
||||
|
||||
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
||||
let token = &meta.tokens()[token_idx];
|
||||
@ -385,9 +385,9 @@ where
|
||||
}
|
||||
meta.tokens().len()
|
||||
};
|
||||
let token_idx = state.rand_mut().below(tokens_len as u64) as usize;
|
||||
let token_idx = state.rand_mut().below(tokens_len);
|
||||
|
||||
let off = state.rand_mut().below(size as u64) as usize;
|
||||
let off = state.rand_mut().below(size);
|
||||
|
||||
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
||||
let token = &meta.tokens()[token_idx];
|
||||
@ -446,9 +446,9 @@ where
|
||||
}
|
||||
meta.list.len()
|
||||
};
|
||||
let idx = state.rand_mut().below(cmps_len as u64) as usize;
|
||||
let idx = state.rand_mut().below(cmps_len);
|
||||
|
||||
let off = state.rand_mut().below(size as u64) as usize;
|
||||
let off = state.rand_mut().below(size);
|
||||
let len = input.bytes().len();
|
||||
let bytes = input.bytes_mut();
|
||||
|
||||
|
@ -87,7 +87,7 @@ where
|
||||
{
|
||||
name: Cow<'static, str>,
|
||||
mutations: MT,
|
||||
max_stack_pow: u64,
|
||||
max_stack_pow: usize,
|
||||
phantom: PhantomData<(I, S)>,
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ where
|
||||
}
|
||||
|
||||
// fall back to random if no entries in either vec, the scheduling is not tuned.
|
||||
state.rand_mut().below(self.mutations.len() as u64).into()
|
||||
state.rand_mut().below(self.mutations.len()).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ where
|
||||
fn mutator_mut(&mut self) -> &mut M;
|
||||
|
||||
/// Gets the number of iterations this mutator should run for.
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<u64, Error>;
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<usize, Error>;
|
||||
|
||||
/// Gets the number of executions this mutator already did since it got first called in this fuzz round.
|
||||
fn execs_since_progress_start(&mut self, state: &mut Z::State) -> Result<u64, Error>;
|
||||
@ -150,7 +150,7 @@ where
|
||||
|
||||
/// Default value, how many iterations each stage gets, as an upper bound.
|
||||
/// It may randomly continue earlier.
|
||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
|
||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
||||
|
||||
/// The default mutational stage
|
||||
#[derive(Clone, Debug)]
|
||||
@ -158,7 +158,7 @@ pub struct StdMutationalStage<E, EM, I, M, Z> {
|
||||
/// The mutator(s) to use
|
||||
mutator: M,
|
||||
/// The maximum amount of iterations we should do each round
|
||||
max_iterations: u64,
|
||||
max_iterations: usize,
|
||||
/// The progress helper for this mutational stage
|
||||
restart_helper: ExecutionCountRestartHelper,
|
||||
#[allow(clippy::type_complexity)]
|
||||
@ -187,7 +187,7 @@ where
|
||||
}
|
||||
|
||||
/// Gets the number of iterations as a random number
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<u64, Error> {
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<usize, Error> {
|
||||
Ok(1 + state.rand_mut().below(self.max_iterations))
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ where
|
||||
}
|
||||
|
||||
/// Creates a new mutational stage with the given max iterations
|
||||
pub fn with_max_iterations(mutator: M, max_iterations: u64) -> Self {
|
||||
pub fn with_max_iterations(mutator: M, max_iterations: usize) -> Self {
|
||||
Self::transforming_with_max_iterations(mutator, max_iterations)
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ where
|
||||
}
|
||||
|
||||
/// Creates a new transforming mutational stage with the given max iterations
|
||||
pub fn transforming_with_max_iterations(mutator: M, max_iterations: u64) -> Self {
|
||||
pub fn transforming_with_max_iterations(mutator: M, max_iterations: usize) -> Self {
|
||||
Self {
|
||||
mutator,
|
||||
max_iterations,
|
||||
|
@ -54,10 +54,10 @@ where
|
||||
|
||||
/// Gets the number of iterations as a random number
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
fn iterations(&self, state: &mut E::State) -> Result<u64, Error> {
|
||||
fn iterations(&self, state: &mut E::State) -> Result<usize, Error> {
|
||||
// Update handicap
|
||||
let mut testcase = state.current_testcase_mut()?;
|
||||
let score = F::compute(state, &mut testcase)? as u64;
|
||||
let score = F::compute(state, &mut testcase)? as usize;
|
||||
|
||||
Ok(score)
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
||||
use crate::{monitors::PerfFeature, state::HasClientPerfMonitor};
|
||||
|
||||
/// The default maximum number of mutations to perform per input.
|
||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: u64 = 128;
|
||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
||||
/// A Mutational push stage is the stage in a fuzzing run that mutates inputs.
|
||||
/// Mutational push stages will usually have a range of mutations that are
|
||||
/// being applied to the input one by one, between executions.
|
||||
@ -72,7 +72,7 @@ where
|
||||
/// Gets the number of iterations as a random number
|
||||
#[allow(clippy::unused_self, clippy::unnecessary_wraps)] // TODO: we should put this function into a trait later
|
||||
fn iterations(&self, state: &mut CS::State, _corpus_idx: CorpusId) -> Result<usize, Error> {
|
||||
Ok(1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) as usize)
|
||||
Ok(1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS))
|
||||
}
|
||||
|
||||
/// Sets the current corpus index
|
||||
|
@ -169,7 +169,6 @@ where
|
||||
{
|
||||
/// Runs this (mutational) stage for the given `testcase`
|
||||
/// Exactly the same functionality as [`MutationalStage::perform_mutational`], but with added timeout support.
|
||||
#[allow(clippy::cast_possible_wrap)] // more than i32 stages on 32 bit system - highly unlikely...
|
||||
fn perform_mutational(
|
||||
&mut self,
|
||||
fuzzer: &mut Z,
|
||||
@ -221,7 +220,7 @@ where
|
||||
// fall back to random
|
||||
let iters = self
|
||||
.iterations(state)?
|
||||
.saturating_sub(self.execs_since_progress_start(state)?);
|
||||
.saturating_sub(self.execs_since_progress_start(state)? as usize);
|
||||
for _ in 1..=iters {
|
||||
self.perform_mutation(fuzzer, executor, state, manager, &input)?;
|
||||
}
|
||||
@ -243,8 +242,7 @@ where
|
||||
}
|
||||
|
||||
/// Gets the number of iterations as a random number
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<u64, Error> {
|
||||
fn iterations(&self, state: &mut Z::State) -> Result<usize, Error> {
|
||||
Ok(
|
||||
// fall back to random
|
||||
1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS),
|
||||
|
@ -30,7 +30,7 @@ where
|
||||
debug_assert!(iter.len() > 0, "choosing from an empty iterator");
|
||||
|
||||
// pick a random, valid index
|
||||
let index = fast_bound(rand, iter.len() as u64) as usize;
|
||||
let index = fast_bound(rand, iter.len());
|
||||
|
||||
// return the item chosen
|
||||
iter.nth(index).unwrap()
|
||||
@ -42,11 +42,12 @@ where
|
||||
/// At least 2^2*(64-N) samples are required to detect this amount of bias.
|
||||
///
|
||||
/// See: [An optimal algorithm for bounded random integers](https://github.com/apple/swift/pull/39143).
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn fast_bound(rand: u64, n: u64) -> u64 {
|
||||
pub fn fast_bound(rand: u64, n: usize) -> usize {
|
||||
debug_assert_ne!(n, 0);
|
||||
let mul = u128::from(rand).wrapping_mul(u128::from(n));
|
||||
(mul >> 64) as u64
|
||||
let mul = u128::from(rand).wrapping_mul(u128::from(n as u64));
|
||||
(mul >> 64) as usize
|
||||
}
|
||||
|
||||
/// Ways to get random around here.
|
||||
@ -60,6 +61,7 @@ pub trait Rand: Debug + Serialize + DeserializeOwned {
|
||||
fn next(&mut self) -> u64;
|
||||
|
||||
/// Gets a value between 0.0 (inclusive) and 1.0 (exclusive)
|
||||
#[inline]
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn next_float(&mut self) -> f64 {
|
||||
// both 2^53 and 2^-53 can be represented in f64 exactly
|
||||
@ -70,18 +72,21 @@ pub trait Rand: Debug + Serialize + DeserializeOwned {
|
||||
}
|
||||
|
||||
/// Returns true with specified probability
|
||||
#[inline]
|
||||
fn coinflip(&mut self, success_prob: f64) -> bool {
|
||||
debug_assert!((0.0..=1.0).contains(&success_prob));
|
||||
self.next_float() < success_prob
|
||||
}
|
||||
|
||||
/// Gets a value below the given 64 bit val (exclusive)
|
||||
fn below(&mut self, upper_bound_excl: u64) -> u64 {
|
||||
/// Gets a value below the given bound (exclusive)
|
||||
#[inline]
|
||||
fn below(&mut self, upper_bound_excl: usize) -> usize {
|
||||
fast_bound(self.next(), upper_bound_excl)
|
||||
}
|
||||
|
||||
/// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
|
||||
fn between(&mut self, lower_bound_incl: u64, upper_bound_incl: u64) -> u64 {
|
||||
#[inline]
|
||||
fn between(&mut self, lower_bound_incl: usize, upper_bound_incl: usize) -> usize {
|
||||
debug_assert!(lower_bound_incl <= upper_bound_incl);
|
||||
lower_bound_incl + self.below(upper_bound_incl - lower_bound_incl + 1)
|
||||
}
|
||||
@ -404,6 +409,7 @@ impl Rand for Sfc64Rand {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> u64 {
|
||||
let out = self.a.wrapping_add(self.b).wrapping_add(self.w);
|
||||
self.w = self.w.wrapping_add(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user