[lib/Fuzzer] extend the fuzzer interface to allow user-supplied mutators
[oota-llvm.git] / lib / Fuzzer / FuzzerMutate.cpp
index b28264ac8c1d2b6fe3d5d6db2bbcce043603ca67..f537fa90fd8506f13bdcab44f70fffd3ec78058b 100644 (file)
@@ -9,6 +9,8 @@
 // Mutate a test input.
 //===----------------------------------------------------------------------===//
 
+#include <cstring>
+
 #include "FuzzerInternal.h"
 
 namespace fuzzer {
@@ -31,40 +33,39 @@ static char RandCh() {
   return Special[rand() % (sizeof(Special) - 1)];
 }
 
-// Mutate U in place.
-void Mutate(Unit *U, size_t MaxLen) {
-  assert(MaxLen > 0);
-  assert(U->size() <= MaxLen);
-  if (U->empty()) {
-    for (size_t i = 0; i < MaxLen; i++)
-      U->push_back(RandCh());
-    return;
+// Mutates Data in place, returns new size.
+size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+  assert(MaxSize > 0);
+  assert(Size <= MaxSize);
+  if (Size == 0) {
+    for (size_t i = 0; i < MaxSize; i++)
+      Data[i] = RandCh();
+    return MaxSize;
   }
-  assert(!U->empty());
+  assert(Size > 0);
+  size_t Idx = rand() % Size;
   switch (rand() % 3) {
   case 0:
-    if (U->size() > 1) {
-      U->erase(U->begin() + rand() % U->size());
-      break;
+    if (Size > 1) {
+      // Erase Data[Idx].
+      memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
+      Size = Size - 1;
     }
     [[clang::fallthrough]];
   case 1:
-    if (U->size() < MaxLen) {
-      U->insert(U->begin() + rand() % U->size(), RandCh());
-    } else { // At MaxLen.
-      uint8_t Ch = RandCh();
-      size_t Idx = rand() % U->size();
-      (*U)[Idx] = Ch;
+    if (Size < MaxSize) {
+      // Insert new value at Data[Idx].
+      memmove(Data + Idx + 1, Data + Idx, Size - Idx);
+      Data[Idx] = RandCh();
     }
+    Data[Idx] = RandCh();
     break;
-  default:
-    {
-      size_t Idx = rand() % U->size();
-      (*U)[Idx] = FlipRandomBit((*U)[Idx]);
-    }
+  case 2:
+    Data[Idx] = FlipRandomBit(Data[Idx]);
     break;
   }
-  assert(!U->empty());
+  assert(Size > 0);
+  return Size;
 }
 
 }  // namespace fuzzer