14
14
* limitations under the License.
15
15
*/
16
16
17
- #import < Foundation/NSObject.h>
18
- #include < string>
17
+ #import < Foundation/Foundation.h>
19
18
20
- #include " LibFuzzer/FuzzerDefs.h"
19
+ #include < cstdlib>
20
+ #include < string>
21
+ #include < unordered_map>
22
+ #include < vector>
21
23
22
24
#include " Firestore/Example/FuzzTests/FuzzingTargets/FSTFuzzTestFieldPath.h"
23
25
#include " Firestore/Example/FuzzTests/FuzzingTargets/FSTFuzzTestSerializer.h"
24
-
25
26
#include " Firestore/core/src/firebase/firestore/util/log.h"
26
27
#include " Firestore/core/src/firebase/firestore/util/string_apple.h"
28
+ #include " LibFuzzer/FuzzerDefs.h"
29
+ #include " absl/strings/str_join.h"
27
30
28
31
namespace {
29
32
30
33
using firebase::firestore::util::MakeString;
31
34
namespace fuzzing = firebase::firestore::fuzzing;
32
35
33
- // A list of targets to fuzz test. Should be kept in sync with the method
34
- // GetFuzzingTarget().
36
+ // A list of targets to fuzz test. Should be kept in sync with
37
+ // GetFuzzingTarget() fuzzing_target_names map object .
35
38
enum class FuzzingTarget { kNone , kSerializer , kFieldPath };
36
39
37
40
// Directory to which crashing inputs are written. Must include the '/' at the
43
46
// Default target is kNone if the environment variable is empty, not set, or
44
47
// could not be interpreted. Should be kept in sync with FuzzingTarget.
45
48
FuzzingTarget GetFuzzingTarget () {
46
- char *fuzzing_target_env = std::getenv (" FUZZING_TARGET" );
49
+ std::unordered_map<std::string, FuzzingTarget> fuzzing_target_names;
50
+ fuzzing_target_names[" NONE" ] = FuzzingTarget::kNone ;
51
+ fuzzing_target_names[" SERIALIZER" ] = FuzzingTarget::kSerializer ;
52
+ fuzzing_target_names[" FIELDPATH" ] = FuzzingTarget::kFieldPath ;
53
+
54
+ const char *fuzzing_target_env = std::getenv (" FUZZING_TARGET" );
47
55
48
- if (fuzzing_target_env == nullptr ) {
56
+ if (! fuzzing_target_env) {
49
57
LOG_WARN (" No value provided for FUZZING_TARGET environment variable." );
50
58
return FuzzingTarget::kNone ;
51
59
}
@@ -56,19 +64,39 @@ FuzzingTarget GetFuzzingTarget() {
56
64
LOG_WARN (" No value provided for FUZZING_TARGET environment variable." );
57
65
return FuzzingTarget::kNone ;
58
66
}
59
- if (fuzzing_target == " NONE " ) {
60
- return FuzzingTarget:: kNone ;
61
- }
62
- if (fuzzing_target == " SERIALIZER " ) {
63
- return FuzzingTarget:: kSerializer ;
67
+
68
+ // Return the value of the fuzzing_target key if it exists in the
69
+ // fuzzing_target_names map.
70
+ if (fuzzing_target_names. find ( fuzzing_target) != fuzzing_target_names. end () ) {
71
+ return fuzzing_target_names[fuzzing_target] ;
64
72
}
65
- if (fuzzing_target == " FIELDPATH" ) {
66
- return FuzzingTarget::kFieldPath ;
73
+
74
+ // If the target is not found, print an error message with all available targets.
75
+ // The targets must be enclosed in curly brackets and separated by spaces. This format
76
+ // is needed by the script /firebase-ios-sdk/script/fuzzing_travis.sh, which parses
77
+ // this message to retrieve a list of the available targets.
78
+ std::vector<std::string> all_keys;
79
+ for (const auto &kv : fuzzing_target_names) {
80
+ all_keys.push_back (kv.first );
67
81
}
68
- LOG_WARN (" Invalid fuzzing target: %s" , fuzzing_target);
82
+ const std::string all_keys_str = absl::StrJoin (all_keys, " " );
83
+ LOG_WARN (" Invalid fuzzing target: %s. Available targets: { %s }." , fuzzing_target, all_keys_str);
69
84
return FuzzingTarget::kNone ;
70
85
}
71
86
87
+ // Retrieves fuzzing duration from the FUZZING_DURATION environment variable.
88
+ // Defaults to "0" if the environment variable is empty, which corresponds to
89
+ // running indefinitely.
90
+ std::string GetFuzzingDuration () {
91
+ const char *fuzzing_duration_env = std::getenv (" FUZZING_DURATION" );
92
+
93
+ if (!fuzzing_duration_env) {
94
+ return " 0" ;
95
+ }
96
+
97
+ return std::string{fuzzing_duration_env};
98
+ }
99
+
72
100
// Simulates calling the main() function of libFuzzer (FuzzerMain.cpp).
73
101
// Uses GetFuzzingTarget() to get the fuzzing target and sets libFuzzer's args
74
102
// accordingly. It also calls an appropriate LLVMFuzzerTestOneInput-like method
@@ -121,13 +149,17 @@ int RunFuzzTestingMain() {
121
149
// The directory in which libFuzzer writes crashing inputs.
122
150
std::string prefix_arg = std::string (" -artifact_prefix=" ) + MakeString (kCrashingInputsDirectory );
123
151
152
+ // Run fuzzing for the defined fuzzing duration.
153
+ std::string time_arg = " -max_total_time=" + GetFuzzingDuration ();
154
+
124
155
// Arguments to libFuzzer main() function should be added to this array,
125
156
// e.g., dictionaries, corpus, number of runs, jobs, etc. The FuzzerDriver of
126
157
// libFuzzer expects the non-const argument 'char ***argv' and it does not
127
158
// modify it throughout the method.
128
159
char *program_args[] = {
129
160
const_cast <char *>(" RunFuzzTestingMain" ), // First arg is program name.
130
161
const_cast <char *>(prefix_arg.c_str ()), // Crashing inputs directory.
162
+ const_cast <char *>(time_arg.c_str ()), // Maximum total time.
131
163
const_cast <char *>(dict_arg.c_str ()), // Dictionary arg.
132
164
const_cast <char *>(corpus_arg.c_str ()) // Corpus must be the last arg.
133
165
};
0 commit comments