This commit is contained in:
Andrea Fioraldi 2020-12-07 16:21:59 +01:00
parent d7661ce9f8
commit e76323e3ca
2 changed files with 66 additions and 34 deletions

View File

@ -32,19 +32,45 @@ where
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];
const INTERESTING_16: [i16; 19] = [-128, -1, 0, 1, 16, 32, 64, 100, 127, -32768, -129, 128, 255, 256, 512, 1000, 1024, 4096, 32767]; const INTERESTING_16: [i16; 19] = [
const INTERESTING_32: [i32; 27] = [-128, -1, 0, 1, 16, 32, 64, 100, 127, -32768, -129, 128, 255, 256, 512, 1000, 1024, 4096, 32767, -2147483648, -100663046, -32769, 32768, 65535, 65536, 100663045, 2147483647]; -128, -1, 0, 1, 16, 32, 64, 100, 127, -32768, -129, 128, 255, 256, 512, 1000, 1024, 4096, 32767,
];
const INTERESTING_32: [i32; 27] = [
-128,
-1,
0,
1,
16,
32,
64,
100,
127,
-32768,
-129,
128,
255,
256,
512,
1000,
1024,
4096,
32767,
-2147483648,
-100663046,
-32769,
32768,
65535,
65536,
100663045,
2147483647,
];
fn self_mem_move(data: &mut [u8], from: usize, to: usize, len: usize) { fn self_mem_move(data: &mut [u8], from: usize, to: usize, len: usize) {
debug_assert!(from + len <= data.len()); debug_assert!(from + len <= data.len());
debug_assert!(to + len <= data.len()); debug_assert!(to + len <= data.len());
let ptr = data.as_mut_ptr(); let ptr = data.as_mut_ptr();
unsafe { unsafe { core::ptr::copy(ptr.offset(from as isize), ptr.offset(to as isize), len) }
core::ptr::copy(ptr.offset(from as isize),
ptr.offset(to as isize),
len)
}
} }
fn mem_move(dst: &mut [u8], src: &[u8], from: usize, to: usize, len: usize) { fn mem_move(dst: &mut [u8], src: &[u8], from: usize, to: usize, len: usize) {
@ -53,18 +79,18 @@ fn mem_move(dst: &mut [u8], src: &[u8], from: usize, to: usize, len: usize) {
let dst_ptr = dst.as_mut_ptr(); let dst_ptr = dst.as_mut_ptr();
let src_ptr = src.as_ptr(); let src_ptr = src.as_ptr();
unsafe { unsafe {
core::ptr::copy(src_ptr.offset(from as isize), core::ptr::copy(
dst_ptr.offset(to as isize), src_ptr.offset(from as isize),
len) dst_ptr.offset(to as isize),
len,
)
} }
} }
fn mem_set(data: &mut [u8], from: usize, len: usize, val: u8) { fn mem_set(data: &mut [u8], from: usize, len: usize, val: u8) {
debug_assert!(from + len <= data.len()); debug_assert!(from + len <= data.len());
let ptr = data.as_mut_ptr(); let ptr = data.as_mut_ptr();
unsafe { unsafe { core::ptr::write_bytes(ptr.offset(from as isize), val, len) }
core::ptr::write_bytes(ptr.offset(from as isize), val, len)
}
} }
/// Bitflip mutation for inputs with a bytes vector /// Bitflip mutation for inputs with a bytes vector
@ -227,7 +253,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut u8; let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut u8;
@ -256,7 +282,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16; let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
@ -287,7 +313,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32; let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
@ -318,7 +344,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u64; let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u64;
@ -349,7 +375,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
let val = INTERESTING_8[rand.below(INTERESTING_8.len() as u64) as usize] as u8; let val = INTERESTING_8[rand.below(INTERESTING_8.len() as u64) as usize] as u8;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
@ -374,7 +400,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
let val = INTERESTING_16[rand.below(INTERESTING_8.len() as u64) as usize] as u16; let val = INTERESTING_16[rand.below(INTERESTING_8.len() as u64) as usize] as u16;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
@ -404,7 +430,7 @@ where
if input.bytes().len() <= 1 { if input.bytes().len() <= 1 {
Ok(MutationResult::Skipped) Ok(MutationResult::Skipped)
} else { } else {
let idx = rand.below(input.bytes().len() as u64 -1) as usize; let idx = rand.below(input.bytes().len() as u64 - 1) as usize;
let val = INTERESTING_32[rand.below(INTERESTING_8.len() as u64) as usize] as u32; let val = INTERESTING_32[rand.below(INTERESTING_8.len() as u64) as usize] as u32;
unsafe { unsafe {
// moar speed, no bound check // moar speed, no bound check
@ -459,7 +485,7 @@ where
let off = if size == 0 { let off = if size == 0 {
0 0
} else { } else {
rand.below(size as u64 -1) rand.below(size as u64 - 1)
} as usize; } as usize;
let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize; let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize;
@ -484,7 +510,7 @@ where
let off = if size == 0 { let off = if size == 0 {
0 0
} else { } else {
rand.below(size as u64 -1) rand.below(size as u64 - 1)
} as usize; } as usize;
let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize; let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize;
@ -511,7 +537,7 @@ where
let off = if size == 0 { let off = if size == 0 {
0 0
} else { } else {
rand.below(size as u64 -1) rand.below(size as u64 - 1)
} as usize; } as usize;
let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize; let len = rand.below(core::cmp::min(16, mutator.max_size() as u64)) as usize;
@ -540,7 +566,11 @@ where
} }
let val = input.bytes()[rand.below(size as u64) as usize]; let val = input.bytes()[rand.below(size as u64) as usize];
let start = if size == 1 { 0 } else { rand.below(size as u64 -1) as usize }; let start = if size == 1 {
0
} else {
rand.below(size as u64 - 1) as usize
};
let end = rand.below((size - start) as u64) as usize; let end = rand.below((size - start) as u64) as usize;
mem_set(input.bytes_mut(), start, end - start, val); mem_set(input.bytes_mut(), start, end - start, val);
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
@ -564,7 +594,11 @@ where
} }
let val = rand.below(256) as u8; let val = rand.below(256) as u8;
let start = if size == 1 { 0 } else { rand.below(size as u64 -1) as usize }; let start = if size == 1 {
0
} else {
rand.below(size as u64 - 1) as usize
};
let end = rand.below((size - start) as u64) as usize; let end = rand.below((size - start) as u64) as usize;
mem_set(input.bytes_mut(), start, end - start, val); mem_set(input.bytes_mut(), start, end - start, val);
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
@ -587,8 +621,8 @@ where
return Ok(MutationResult::Skipped); return Ok(MutationResult::Skipped);
} }
let from = rand.below(input.bytes().len() as u64 -1) as usize; let from = rand.below(input.bytes().len() as u64 - 1) as usize;
let to = rand.below(input.bytes().len() as u64 -1) as usize; let to = rand.below(input.bytes().len() as u64 - 1) as usize;
let len = rand.below((size - core::cmp::max(from, to)) as u64) as usize; let len = rand.below((size - core::cmp::max(from, to)) as u64) as usize;
self_mem_move(input.bytes_mut(), from, to, len); self_mem_move(input.bytes_mut(), from, to, len);
@ -612,8 +646,8 @@ where
return Ok(MutationResult::Skipped); return Ok(MutationResult::Skipped);
} }
let first = rand.below(input.bytes().len() as u64 -1) as usize; let first = rand.below(input.bytes().len() as u64 - 1) as usize;
let second = rand.below(input.bytes().len() as u64 -1) as usize; let second = rand.below(input.bytes().len() as u64 - 1) as usize;
let len = rand.below((size - core::cmp::max(first, second)) as u64) as usize; let len = rand.below((size - core::cmp::max(first, second)) as u64) as usize;
let tmp = input.bytes()[first..len].to_vec(); let tmp = input.bytes()[first..len].to_vec();
@ -622,8 +656,6 @@ where
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
} }
/// Returns the first and last diff position between the given vectors, stopping at the min len /// Returns the first and last diff position between the given vectors, stopping at the min len
fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) { fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
let mut first_diff: i64 = -1; let mut first_diff: i64 = -1;