@@ -193,6 +193,24 @@ pub trait HasLastReportTime {
193
193
fn last_report_time_mut ( & mut self ) -> & mut Option < Duration > ;
194
194
}
195
195
196
+ /// Struct that holds the options for input loading
197
+ #[ cfg( feature = "std" ) ]
198
+ pub struct LoadConfig < ' a , I , S , Z > {
199
+ /// Load Input even if it was deemed "uninteresting" by the fuzzer
200
+ forced : bool ,
201
+ /// Function to load input from a Path
202
+ loader : & ' a mut dyn FnMut ( & mut Z , & mut S , & Path ) -> Result < I , Error > ,
203
+ /// Error if Input leads to a Solution.
204
+ exit_on_solution : bool ,
205
+ }
206
+
207
+ #[ cfg( feature = "std" ) ]
208
+ impl < ' a , I , S , Z > Debug for LoadConfig < ' a , I , S , Z > {
209
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
210
+ write ! ( f, "LoadConfig {{}}" )
211
+ }
212
+ }
213
+
196
214
/// The state a fuzz run.
197
215
#[ derive( Serialize , Deserialize , Clone , Debug ) ]
198
216
#[ serde( bound = "
@@ -647,8 +665,7 @@ where
647
665
executor : & mut E ,
648
666
manager : & mut EM ,
649
667
file_list : & [ PathBuf ] ,
650
- forced : bool ,
651
- loader : & mut dyn FnMut ( & mut Z , & mut Self , & Path ) -> Result < I , Error > ,
668
+ load_config : LoadConfig < I , Self , Z > ,
652
669
) -> Result < ( ) , Error >
653
670
where
654
671
E : UsesState < State = Self > ,
@@ -664,45 +681,45 @@ where
664
681
self . remaining_initial_files = Some ( file_list. to_vec ( ) ) ;
665
682
}
666
683
667
- self . continue_loading_initial_inputs_custom ( fuzzer, executor, manager, forced , loader )
684
+ self . continue_loading_initial_inputs_custom ( fuzzer, executor, manager, load_config )
668
685
}
686
+
669
687
fn load_file < E , EM , Z > (
670
688
& mut self ,
671
689
path : & PathBuf ,
672
690
manager : & mut EM ,
673
691
fuzzer : & mut Z ,
674
692
executor : & mut E ,
675
- forced : bool ,
676
- loader : & mut dyn FnMut ( & mut Z , & mut Self , & Path ) -> Result < I , Error > ,
677
- ) -> Result < ( ) , Error >
693
+ config : & mut LoadConfig < I , Self , Z > ,
694
+ ) -> Result < ExecuteInputResult , Error >
678
695
where
679
696
E : UsesState < State = Self > ,
680
697
EM : EventFirer < State = Self > ,
681
698
Z : Evaluator < E , EM , State = Self > ,
682
699
{
683
700
log:: info!( "Loading file {:?} ..." , & path) ;
684
- let input = loader ( fuzzer, self , path) ?;
685
- if forced {
701
+ let input = ( config . loader ) ( fuzzer, self , path) ?;
702
+ if config . forced {
686
703
let _: CorpusId = fuzzer. add_input ( self , executor, manager, input) ?;
704
+ Ok ( ExecuteInputResult :: Corpus )
687
705
} else {
688
706
let ( res, _) = fuzzer. evaluate_input ( self , executor, manager, input. clone ( ) ) ?;
689
707
if res == ExecuteInputResult :: None {
690
708
fuzzer. add_disabled_input ( self , input) ?;
691
709
log:: warn!( "input {:?} was not interesting, adding as disabled." , & path) ;
692
710
}
711
+ Ok ( res)
693
712
}
694
- Ok ( ( ) )
695
713
}
696
714
/// Loads initial inputs from the passed-in `in_dirs`.
697
- /// If `forced` is true, will add all testcases, no matter what.
698
- /// This method takes a list of files.
715
+ /// This method takes a list of files and a `LoadConfig`
716
+ /// which specifies the special handling of initial inputs
699
717
fn continue_loading_initial_inputs_custom < E , EM , Z > (
700
718
& mut self ,
701
719
fuzzer : & mut Z ,
702
720
executor : & mut E ,
703
721
manager : & mut EM ,
704
- forced : bool ,
705
- loader : & mut dyn FnMut ( & mut Z , & mut Self , & Path ) -> Result < I , Error > ,
722
+ mut config : LoadConfig < I , Self , Z > ,
706
723
) -> Result < ( ) , Error >
707
724
where
708
725
E : UsesState < State = Self > ,
@@ -712,7 +729,13 @@ where
712
729
loop {
713
730
match self . next_file ( ) {
714
731
Ok ( path) => {
715
- self . load_file ( & path, manager, fuzzer, executor, forced, loader) ?;
732
+ let res = self . load_file ( & path, manager, fuzzer, executor, & mut config) ?;
733
+ if config. exit_on_solution && matches ! ( res, ExecuteInputResult :: Solution ) {
734
+ return Err ( Error :: invalid_corpus ( format ! (
735
+ "Input {} resulted in a solution." ,
736
+ path. display( )
737
+ ) ) ) ;
738
+ }
716
739
}
717
740
Err ( Error :: IteratorEnd ( _, _) ) => break ,
718
741
Err ( e) => return Err ( e) ,
@@ -751,8 +774,11 @@ where
751
774
executor,
752
775
manager,
753
776
file_list,
754
- false ,
755
- & mut |_, _, path| I :: from_file ( path) ,
777
+ LoadConfig {
778
+ loader : & mut |_, _, path| I :: from_file ( path) ,
779
+ forced : false ,
780
+ exit_on_solution : false ,
781
+ } ,
756
782
)
757
783
}
758
784
@@ -776,8 +802,11 @@ where
776
802
fuzzer,
777
803
executor,
778
804
manager,
779
- true ,
780
- & mut |_, _, path| I :: from_file ( path) ,
805
+ LoadConfig {
806
+ loader : & mut |_, _, path| I :: from_file ( path) ,
807
+ forced : true ,
808
+ exit_on_solution : false ,
809
+ } ,
781
810
)
782
811
}
783
812
/// Loads initial inputs from the passed-in `in_dirs`.
@@ -800,8 +829,11 @@ where
800
829
executor,
801
830
manager,
802
831
file_list,
803
- true ,
804
- & mut |_, _, path| I :: from_file ( path) ,
832
+ LoadConfig {
833
+ loader : & mut |_, _, path| I :: from_file ( path) ,
834
+ forced : true ,
835
+ exit_on_solution : false ,
836
+ } ,
805
837
)
806
838
}
807
839
@@ -823,8 +855,38 @@ where
823
855
fuzzer,
824
856
executor,
825
857
manager,
826
- false ,
827
- & mut |_, _, path| I :: from_file ( path) ,
858
+ LoadConfig {
859
+ loader : & mut |_, _, path| I :: from_file ( path) ,
860
+ forced : false ,
861
+ exit_on_solution : false ,
862
+ } ,
863
+ )
864
+ }
865
+
866
+ /// Loads initial inputs from the passed-in `in_dirs`.
867
+ /// Will return a `CorpusError` if a solution is found
868
+ pub fn load_initial_inputs_disallow_solution < E , EM , Z > (
869
+ & mut self ,
870
+ fuzzer : & mut Z ,
871
+ executor : & mut E ,
872
+ manager : & mut EM ,
873
+ in_dirs : & [ PathBuf ] ,
874
+ ) -> Result < ( ) , Error >
875
+ where
876
+ E : UsesState < State = Self > ,
877
+ EM : EventFirer < State = Self > ,
878
+ Z : Evaluator < E , EM , State = Self > ,
879
+ {
880
+ self . canonicalize_input_dirs ( in_dirs) ?;
881
+ self . continue_loading_initial_inputs_custom (
882
+ fuzzer,
883
+ executor,
884
+ manager,
885
+ LoadConfig {
886
+ loader : & mut |_, _, path| I :: from_file ( path) ,
887
+ forced : false ,
888
+ exit_on_solution : true ,
889
+ } ,
828
890
)
829
891
}
830
892
@@ -862,8 +924,11 @@ where
862
924
fuzzer,
863
925
executor,
864
926
manager,
865
- false ,
866
- & mut |_, _, path| I :: from_file ( path) ,
927
+ LoadConfig {
928
+ loader : & mut |_, _, path| I :: from_file ( path) ,
929
+ forced : false ,
930
+ exit_on_solution : false ,
931
+ } ,
867
932
) ?;
868
933
} else {
869
934
self . canonicalize_input_dirs ( in_dirs) ?;
0 commit comments