@@ -13,7 +13,9 @@ use crate::{
1313use alloc:: { borrow:: ToOwned , vec:: Vec } ;
1414use core:: {
1515 cmp:: { max, min} ,
16+ convert:: TryInto ,
1617 marker:: PhantomData ,
18+ mem:: size_of,
1719} ;
1820
1921/// Mem move in the own vec
@@ -53,6 +55,7 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
5355 }
5456}
5557
58+ /// The max value that will be added or subtracted during add mutations
5659const ARITH_MAX : u64 = 35 ;
5760
5861const INTERESTING_8 : [ i8 ; 9 ] = [ -128 , -1 , 0 , 1 , 16 , 32 , 64 , 100 , 127 ] ;
@@ -531,6 +534,7 @@ where
531534}
532535
533536/// Word add mutation for inputs with a bytes vector
537+ /// adds or subtracts a random value up to [`ARITH_MAX`] to a [`u16`] at a random place in the [`Vec`].
534538#[ derive( Default ) ]
535539pub struct WordAddMutator < I , R , S >
536540where
@@ -553,21 +557,23 @@ where
553557 input : & mut I ,
554558 _stage_idx : i32 ,
555559 ) -> Result < MutationResult , Error > {
556- if input. bytes ( ) . len ( ) < 2 {
560+ if input. bytes ( ) . len ( ) < size_of :: < u16 > ( ) {
557561 Ok ( MutationResult :: Skipped )
558562 } else {
559- let idx = state . rand_mut ( ) . below ( input. bytes ( ) . len ( ) as u64 - 1 ) as usize ;
560- unsafe {
561- // Moar speed, no bounds checks
562- let ptr = input . bytes_mut ( ) . get_unchecked_mut ( idx ) as * mut _ as * mut u16 ;
563- let num = 1 + state . rand_mut ( ) . below ( ARITH_MAX ) as u16 ;
564- match state. rand_mut ( ) . below ( 4 ) {
565- 0 => * ptr = ( * ptr ) . wrapping_add ( num ) ,
566- 1 => * ptr = ( * ptr ) . wrapping_sub ( num) ,
567- 2 => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_add ( num) ) . swap_bytes ( ) ,
568- _ => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_sub ( num) ) . swap_bytes ( ) ,
569- } ;
563+ let bytes = input. bytes_mut ( ) ;
564+ let idx = state
565+ . rand_mut ( )
566+ . below ( ( bytes . len ( ) - size_of :: < u16 > ( ) + 1 ) as u64 ) as usize ;
567+ let val = u16 :: from_ne_bytes ( bytes [ idx..idx + size_of :: < u16 > ( ) ] . try_into ( ) . unwrap ( ) ) ;
568+ let num = 1 + state. rand_mut ( ) . below ( ARITH_MAX ) as u16 ;
569+ let new_bytes = match state . rand_mut ( ) . below ( 4 ) {
570+ 0 => val . wrapping_add ( num) ,
571+ 1 => val . wrapping_sub ( num) ,
572+ 2 => val . swap_bytes ( ) . wrapping_add ( num) . swap_bytes ( ) ,
573+ _ => val . swap_bytes ( ) . wrapping_sub ( num ) . swap_bytes ( ) ,
570574 }
575+ . to_ne_bytes ( ) ;
576+ bytes[ idx..idx + size_of :: < u16 > ( ) ] . copy_from_slice ( & new_bytes) ;
571577 Ok ( MutationResult :: Mutated )
572578 }
573579 }
@@ -599,7 +605,8 @@ where
599605 }
600606}
601607
602- /// Dword add mutation for inputs with a bytes vector
608+ /// Dword add mutation for inputs with a bytes vector.
609+ /// Adds a random value up to `ARITH_MAX` to a [`u32`] at a random place in the [`Vec`], in random byte order.
603610#[ derive( Default ) ]
604611pub struct DwordAddMutator < I , R , S >
605612where
@@ -622,21 +629,23 @@ where
622629 input : & mut I ,
623630 _stage_idx : i32 ,
624631 ) -> Result < MutationResult , Error > {
625- if input. bytes ( ) . len ( ) < 4 {
632+ if input. bytes ( ) . len ( ) < size_of :: < u32 > ( ) {
626633 Ok ( MutationResult :: Skipped )
627634 } else {
628- let idx = state . rand_mut ( ) . below ( input. bytes ( ) . len ( ) as u64 - 3 ) as usize ;
629- unsafe {
630- // Moar speed, no bound check
631- let ptr = input . bytes_mut ( ) . get_unchecked_mut ( idx ) as * mut _ as * mut u32 ;
632- let num = 1 + state . rand_mut ( ) . below ( ARITH_MAX ) as u32 ;
633- match state. rand_mut ( ) . below ( 4 ) {
634- 0 => * ptr = ( * ptr ) . wrapping_add ( num ) ,
635- 1 => * ptr = ( * ptr ) . wrapping_sub ( num) ,
636- 2 => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_add ( num) ) . swap_bytes ( ) ,
637- _ => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_sub ( num) ) . swap_bytes ( ) ,
638- } ;
635+ let bytes = input. bytes_mut ( ) ;
636+ let idx = state
637+ . rand_mut ( )
638+ . below ( ( bytes . len ( ) - size_of :: < u32 > ( ) + 1 ) as u64 ) as usize ;
639+ let val = u32 :: from_ne_bytes ( bytes [ idx..idx + size_of :: < u32 > ( ) ] . try_into ( ) . unwrap ( ) ) ;
640+ let num = 1 + state. rand_mut ( ) . below ( ARITH_MAX ) as u32 ;
641+ let new_bytes = match state . rand_mut ( ) . below ( 4 ) {
642+ 0 => val . wrapping_add ( num) ,
643+ 1 => val . wrapping_sub ( num) ,
644+ 2 => val . swap_bytes ( ) . wrapping_add ( num) . swap_bytes ( ) ,
645+ _ => val . swap_bytes ( ) . wrapping_sub ( num ) . swap_bytes ( ) ,
639646 }
647+ . to_ne_bytes ( ) ;
648+ bytes[ idx..idx + size_of :: < u32 > ( ) ] . copy_from_slice ( & new_bytes) ;
640649 Ok ( MutationResult :: Mutated )
641650 }
642651 }
@@ -694,18 +703,20 @@ where
694703 if input. bytes ( ) . len ( ) < 8 {
695704 Ok ( MutationResult :: Skipped )
696705 } else {
697- let idx = state . rand_mut ( ) . below ( input. bytes ( ) . len ( ) as u64 - 7 ) as usize ;
698- unsafe {
699- // Moar speed, no bounds checks
700- let ptr = input . bytes_mut ( ) . get_unchecked_mut ( idx ) as * mut _ as * mut u64 ;
701- let num = 1 + state . rand_mut ( ) . below ( ARITH_MAX ) as u64 ;
702- match state. rand_mut ( ) . below ( 4 ) {
703- 0 => * ptr = ( * ptr ) . wrapping_add ( num ) ,
704- 1 => * ptr = ( * ptr ) . wrapping_sub ( num) ,
705- 2 => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_add ( num) ) . swap_bytes ( ) ,
706- _ => * ptr = ( ( * ptr ) . swap_bytes ( ) . wrapping_sub ( num) ) . swap_bytes ( ) ,
707- } ;
706+ let bytes = input. bytes_mut ( ) ;
707+ let idx = state
708+ . rand_mut ( )
709+ . below ( ( bytes . len ( ) - size_of :: < u64 > ( ) + 1 ) as u64 ) as usize ;
710+ let val = u64 :: from_ne_bytes ( bytes [ idx..idx + size_of :: < u64 > ( ) ] . try_into ( ) . unwrap ( ) ) ;
711+ let num = 1 + state. rand_mut ( ) . below ( ARITH_MAX ) as u64 ;
712+ let new_bytes = match state . rand_mut ( ) . below ( 4 ) {
713+ 0 => val . wrapping_add ( num) ,
714+ 1 => val . wrapping_sub ( num) ,
715+ 2 => val . swap_bytes ( ) . wrapping_add ( num) . swap_bytes ( ) ,
716+ _ => val . swap_bytes ( ) . wrapping_sub ( num ) . swap_bytes ( ) ,
708717 }
718+ . to_ne_bytes ( ) ;
719+ bytes[ idx..idx + size_of :: < u64 > ( ) ] . copy_from_slice ( & new_bytes) ;
709720 Ok ( MutationResult :: Mutated )
710721 }
711722 }
@@ -829,18 +840,16 @@ where
829840 if input. bytes ( ) . len ( ) < 2 {
830841 Ok ( MutationResult :: Skipped )
831842 } else {
832- let idx = state. rand_mut ( ) . below ( input. bytes ( ) . len ( ) as u64 - 1 ) as usize ;
843+ let bytes = input. bytes_mut ( ) ;
844+ let idx = state. rand_mut ( ) . below ( bytes. len ( ) as u64 - 1 ) as usize ;
833845 let val =
834846 INTERESTING_16 [ state. rand_mut ( ) . below ( INTERESTING_8 . len ( ) as u64 ) as usize ] as u16 ;
835- unsafe {
836- // Moar speed, no bounds checks
837- let ptr = input. bytes_mut ( ) . get_unchecked_mut ( idx) as * mut _ as * mut u16 ;
838- if state. rand_mut ( ) . below ( 2 ) == 0 {
839- * ptr = val;
840- } else {
841- * ptr = val. swap_bytes ( ) ;
842- }
843- }
847+ let new_bytes = if state. rand_mut ( ) . below ( 2 ) == 0 {
848+ val. to_be_bytes ( )
849+ } else {
850+ val. to_le_bytes ( )
851+ } ;
852+ bytes[ idx..idx + size_of :: < u16 > ( ) ] . copy_from_slice ( & new_bytes) ;
844853 Ok ( MutationResult :: Mutated )
845854 }
846855 }
@@ -899,18 +908,16 @@ where
899908 if input. bytes ( ) . len ( ) < 4 {
900909 Ok ( MutationResult :: Skipped )
901910 } else {
902- let idx = state. rand_mut ( ) . below ( input. bytes ( ) . len ( ) as u64 - 3 ) as usize ;
911+ let bytes = input. bytes_mut ( ) ;
912+ let idx = state. rand_mut ( ) . below ( bytes. len ( ) as u64 - 3 ) as usize ;
903913 let val =
904914 INTERESTING_32 [ state. rand_mut ( ) . below ( INTERESTING_8 . len ( ) as u64 ) as usize ] as u32 ;
905- unsafe {
906- // Moar speed, no bounds checks
907- let ptr = input. bytes_mut ( ) . get_unchecked_mut ( idx) as * mut _ as * mut u32 ;
908- if state. rand_mut ( ) . below ( 2 ) == 0 {
909- * ptr = val;
910- } else {
911- * ptr = val. swap_bytes ( ) ;
912- }
913- }
915+ let new_bytes = if state. rand_mut ( ) . below ( 2 ) == 0 {
916+ val. to_be_bytes ( )
917+ } else {
918+ val. to_le_bytes ( )
919+ } ;
920+ bytes[ idx..idx + new_bytes. len ( ) ] . copy_from_slice ( & new_bytes) ;
914921 Ok ( MutationResult :: Mutated )
915922 }
916923 }
0 commit comments