@@ -13,7 +13,9 @@ use crate::{
13
13
use alloc:: { borrow:: ToOwned , vec:: Vec } ;
14
14
use core:: {
15
15
cmp:: { max, min} ,
16
+ convert:: TryInto ,
16
17
marker:: PhantomData ,
18
+ mem:: size_of,
17
19
} ;
18
20
19
21
/// Mem move in the own vec
@@ -53,6 +55,7 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
53
55
}
54
56
}
55
57
58
+ /// The max value that will be added or subtracted during add mutations
56
59
const ARITH_MAX : u64 = 35 ;
57
60
58
61
const INTERESTING_8 : [ i8 ; 9 ] = [ -128 , -1 , 0 , 1 , 16 , 32 , 64 , 100 , 127 ] ;
@@ -531,6 +534,7 @@ where
531
534
}
532
535
533
536
/// 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`].
534
538
#[ derive( Default ) ]
535
539
pub struct WordAddMutator < I , R , S >
536
540
where
@@ -553,21 +557,23 @@ where
553
557
input : & mut I ,
554
558
_stage_idx : i32 ,
555
559
) -> Result < MutationResult , Error > {
556
- if input. bytes ( ) . len ( ) < 2 {
560
+ if input. bytes ( ) . len ( ) < size_of :: < u16 > ( ) {
557
561
Ok ( MutationResult :: Skipped )
558
562
} 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 ( ) ,
570
574
}
575
+ . to_ne_bytes ( ) ;
576
+ bytes[ idx..idx + size_of :: < u16 > ( ) ] . copy_from_slice ( & new_bytes) ;
571
577
Ok ( MutationResult :: Mutated )
572
578
}
573
579
}
@@ -599,7 +605,8 @@ where
599
605
}
600
606
}
601
607
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.
603
610
#[ derive( Default ) ]
604
611
pub struct DwordAddMutator < I , R , S >
605
612
where
@@ -622,21 +629,23 @@ where
622
629
input : & mut I ,
623
630
_stage_idx : i32 ,
624
631
) -> Result < MutationResult , Error > {
625
- if input. bytes ( ) . len ( ) < 4 {
632
+ if input. bytes ( ) . len ( ) < size_of :: < u32 > ( ) {
626
633
Ok ( MutationResult :: Skipped )
627
634
} 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 ( ) ,
639
646
}
647
+ . to_ne_bytes ( ) ;
648
+ bytes[ idx..idx + size_of :: < u32 > ( ) ] . copy_from_slice ( & new_bytes) ;
640
649
Ok ( MutationResult :: Mutated )
641
650
}
642
651
}
@@ -694,18 +703,20 @@ where
694
703
if input. bytes ( ) . len ( ) < 8 {
695
704
Ok ( MutationResult :: Skipped )
696
705
} 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 ( ) ,
708
717
}
718
+ . to_ne_bytes ( ) ;
719
+ bytes[ idx..idx + size_of :: < u64 > ( ) ] . copy_from_slice ( & new_bytes) ;
709
720
Ok ( MutationResult :: Mutated )
710
721
}
711
722
}
@@ -829,18 +840,16 @@ where
829
840
if input. bytes ( ) . len ( ) < 2 {
830
841
Ok ( MutationResult :: Skipped )
831
842
} 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 ;
833
845
let val =
834
846
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) ;
844
853
Ok ( MutationResult :: Mutated )
845
854
}
846
855
}
@@ -899,18 +908,16 @@ where
899
908
if input. bytes ( ) . len ( ) < 4 {
900
909
Ok ( MutationResult :: Skipped )
901
910
} 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 ;
903
913
let val =
904
914
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) ;
914
921
Ok ( MutationResult :: Mutated )
915
922
}
916
923
}
0 commit comments