Libfuzzer: do not pass null into user function
[oota-llvm.git] / lib / Fuzzer / FuzzerLoop.cpp
index 455aa625337f847271fbd86e9fe6720810ced009..9c52a4dbe774e0cb9a63668e07c2bf747a10eff0 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "FuzzerInternal.h"
-#include <sanitizer/coverage_interface.h>
 #include <algorithm>
 
+#if defined(__has_include)
+# if __has_include(<sanitizer/coverage_interface.h>)
+#  include <sanitizer/coverage_interface.h>
+# endif
+#endif
+
 extern "C" {
 // Re-declare some of the sanitizer functions as "weak" so that
-// libFuzzer can be linked w/o the sanitizers and sanitizer-coveragte
+// libFuzzer can be linked w/o the sanitizers and sanitizer-coverage
 // (in which case it will complain at start-up time).
 __attribute__((weak)) void __sanitizer_print_stack_trace();
 __attribute__((weak)) void __sanitizer_reset_coverage();
@@ -233,7 +238,11 @@ void Fuzzer::RunOneAndUpdateCorpus(Unit &U) {
 }
 
 void Fuzzer::ExecuteCallback(const Unit &U) {
-  int Res = USF.TargetFunction(U.data(), U.size());
+  const uint8_t *Data = U.data();
+  uint8_t EmptyData;
+  if (!Data) 
+    Data = &EmptyData;
+  int Res = USF.TargetFunction(Data, U.size());
   (void)Res;
   assert(Res == 0);
 }
@@ -288,6 +297,8 @@ void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
   if (!Options.SaveArtifacts)
     return;
   std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
+  if (!Options.ExactArtifactPath.empty())
+    Path = Options.ExactArtifactPath;  // Overrides ArtifactPrefix.
   WriteToFile(U, Path);
   Printf("artifact_prefix='%s'; Test unit written to %s\n",
          Options.ArtifactPrefix.c_str(), Path.c_str());