Fix misaligned ptr accesses and other clippy issues (#94)
* more docs * more docs: * more docu * more docu * finished docs * cleaned up markup * must_use tags added * more docs * swapped if/else, as per clippy * more docu, less clippy * more fixes * removed misaligned ptrs * fixed testcases * fixed arith mutators
This commit is contained in:
parent
7f06e36e2e
commit
cf23695773
@ -13,7 +13,9 @@ use crate::{
|
|||||||
use alloc::{borrow::ToOwned, vec::Vec};
|
use alloc::{borrow::ToOwned, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
cmp::{max, min},
|
cmp::{max, min},
|
||||||
|
convert::TryInto,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
mem::size_of,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Mem move in the own vec
|
/// Mem move in the own vec
|
||||||
@ -53,6 +55,7 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The max value that will be added or subtracted during add mutations
|
||||||
const ARITH_MAX: u64 = 35;
|
const ARITH_MAX: u64 = 35;
|
||||||
|
|
||||||
const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
|
const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
|
||||||
@ -531,6 +534,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Word add mutation for inputs with a bytes vector
|
/// Word add mutation for inputs with a bytes vector
|
||||||
|
/// adds or subtracts a random value up to [`ARITH_MAX`] to a [`u16`] at a random place in the [`Vec`].
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WordAddMutator<I, R, S>
|
pub struct WordAddMutator<I, R, S>
|
||||||
where
|
where
|
||||||
@ -553,21 +557,23 @@ where
|
|||||||
input: &mut I,
|
input: &mut I,
|
||||||
_stage_idx: i32,
|
_stage_idx: i32,
|
||||||
) -> Result<MutationResult, Error> {
|
) -> Result<MutationResult, Error> {
|
||||||
if input.bytes().len() < 2 {
|
if input.bytes().len() < size_of::<u16>() {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
|
let bytes = input.bytes_mut();
|
||||||
unsafe {
|
let idx = state
|
||||||
// Moar speed, no bounds checks
|
.rand_mut()
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
|
.below((bytes.len() - size_of::<u16>() + 1) as u64) as usize;
|
||||||
|
let val = u16::from_ne_bytes(bytes[idx..idx + size_of::<u16>()].try_into().unwrap());
|
||||||
let num = 1 + state.rand_mut().below(ARITH_MAX) as u16;
|
let num = 1 + state.rand_mut().below(ARITH_MAX) as u16;
|
||||||
match state.rand_mut().below(4) {
|
let new_bytes = match state.rand_mut().below(4) {
|
||||||
0 => *ptr = (*ptr).wrapping_add(num),
|
0 => val.wrapping_add(num),
|
||||||
1 => *ptr = (*ptr).wrapping_sub(num),
|
1 => val.wrapping_sub(num),
|
||||||
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
|
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
|
||||||
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
|
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
.to_ne_bytes();
|
||||||
|
bytes[idx..idx + size_of::<u16>()].copy_from_slice(&new_bytes);
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,7 +605,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dword add mutation for inputs with a bytes vector
|
/// Dword add mutation for inputs with a bytes vector.
|
||||||
|
/// Adds a random value up to `ARITH_MAX` to a [`u32`] at a random place in the [`Vec`], in random byte order.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DwordAddMutator<I, R, S>
|
pub struct DwordAddMutator<I, R, S>
|
||||||
where
|
where
|
||||||
@ -622,21 +629,23 @@ where
|
|||||||
input: &mut I,
|
input: &mut I,
|
||||||
_stage_idx: i32,
|
_stage_idx: i32,
|
||||||
) -> Result<MutationResult, Error> {
|
) -> Result<MutationResult, Error> {
|
||||||
if input.bytes().len() < 4 {
|
if input.bytes().len() < size_of::<u32>() {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
|
let bytes = input.bytes_mut();
|
||||||
unsafe {
|
let idx = state
|
||||||
// Moar speed, no bound check
|
.rand_mut()
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
|
.below((bytes.len() - size_of::<u32>() + 1) as u64) as usize;
|
||||||
|
let val = u32::from_ne_bytes(bytes[idx..idx + size_of::<u32>()].try_into().unwrap());
|
||||||
let num = 1 + state.rand_mut().below(ARITH_MAX) as u32;
|
let num = 1 + state.rand_mut().below(ARITH_MAX) as u32;
|
||||||
match state.rand_mut().below(4) {
|
let new_bytes = match state.rand_mut().below(4) {
|
||||||
0 => *ptr = (*ptr).wrapping_add(num),
|
0 => val.wrapping_add(num),
|
||||||
1 => *ptr = (*ptr).wrapping_sub(num),
|
1 => val.wrapping_sub(num),
|
||||||
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
|
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
|
||||||
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
|
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
.to_ne_bytes();
|
||||||
|
bytes[idx..idx + size_of::<u32>()].copy_from_slice(&new_bytes);
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -694,18 +703,20 @@ where
|
|||||||
if input.bytes().len() < 8 {
|
if input.bytes().len() < 8 {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 7) as usize;
|
let bytes = input.bytes_mut();
|
||||||
unsafe {
|
let idx = state
|
||||||
// Moar speed, no bounds checks
|
.rand_mut()
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u64;
|
.below((bytes.len() - size_of::<u64>() + 1) as u64) as usize;
|
||||||
|
let val = u64::from_ne_bytes(bytes[idx..idx + size_of::<u64>()].try_into().unwrap());
|
||||||
let num = 1 + state.rand_mut().below(ARITH_MAX) as u64;
|
let num = 1 + state.rand_mut().below(ARITH_MAX) as u64;
|
||||||
match state.rand_mut().below(4) {
|
let new_bytes = match state.rand_mut().below(4) {
|
||||||
0 => *ptr = (*ptr).wrapping_add(num),
|
0 => val.wrapping_add(num),
|
||||||
1 => *ptr = (*ptr).wrapping_sub(num),
|
1 => val.wrapping_sub(num),
|
||||||
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
|
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
|
||||||
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
|
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
.to_ne_bytes();
|
||||||
|
bytes[idx..idx + size_of::<u64>()].copy_from_slice(&new_bytes);
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -829,18 +840,16 @@ where
|
|||||||
if input.bytes().len() < 2 {
|
if input.bytes().len() < 2 {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
|
let bytes = input.bytes_mut();
|
||||||
|
let idx = state.rand_mut().below(bytes.len() as u64 - 1) as usize;
|
||||||
let val =
|
let val =
|
||||||
INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;
|
INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;
|
||||||
unsafe {
|
let new_bytes = if state.rand_mut().below(2) == 0 {
|
||||||
// Moar speed, no bounds checks
|
val.to_be_bytes()
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
|
|
||||||
if state.rand_mut().below(2) == 0 {
|
|
||||||
*ptr = val;
|
|
||||||
} else {
|
} else {
|
||||||
*ptr = val.swap_bytes();
|
val.to_le_bytes()
|
||||||
}
|
};
|
||||||
}
|
bytes[idx..idx + size_of::<u16>()].copy_from_slice(&new_bytes);
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -899,18 +908,16 @@ where
|
|||||||
if input.bytes().len() < 4 {
|
if input.bytes().len() < 4 {
|
||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
|
let bytes = input.bytes_mut();
|
||||||
|
let idx = state.rand_mut().below(bytes.len() as u64 - 3) as usize;
|
||||||
let val =
|
let val =
|
||||||
INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;
|
INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;
|
||||||
unsafe {
|
let new_bytes = if state.rand_mut().below(2) == 0 {
|
||||||
// Moar speed, no bounds checks
|
val.to_be_bytes()
|
||||||
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
|
|
||||||
if state.rand_mut().below(2) == 0 {
|
|
||||||
*ptr = val;
|
|
||||||
} else {
|
} else {
|
||||||
*ptr = val.swap_bytes();
|
val.to_le_bytes()
|
||||||
}
|
};
|
||||||
}
|
bytes[idx..idx + new_bytes.len()].copy_from_slice(&new_bytes);
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user