[PM/AA] Run clang-format over the ObjCARC Alias Analysis code to
[oota-llvm.git] / lib / Fuzzer / FuzzerMutate.cpp
index 66df98a66f5da71cfec7450097a0d978cea3e4b3..c425ae0c1cdd970f6316d0aa46dac7d41b89e062 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "FuzzerInternal.h"
 
+#include <algorithm>
+
 namespace fuzzer {
 
 static char FlipRandomBit(char X, FuzzerRandomBase &Rand) {
@@ -33,6 +35,51 @@ static char RandCh(FuzzerRandomBase &Rand) {
   return Special[Rand(sizeof(Special) - 1)];
 }
 
+size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize,
+                           FuzzerRandomBase &Rand) {
+  assert(Size);
+  size_t ShuffleAmount = Rand(std::min(Size, 8UL)) + 1;  // [1,8] and <= Size.
+  size_t ShuffleStart = Rand(Size - ShuffleAmount);
+  assert(ShuffleStart + ShuffleAmount <= Size);
+  std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount,
+                      Rand);
+  return Size;
+}
+
+size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize,
+                        FuzzerRandomBase &Rand) {
+  assert(Size);
+  if (Size == 1) return Size;
+  size_t Idx = Rand(Size);
+  // Erase Data[Idx].
+  memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
+  return Size - 1;
+}
+
+size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize,
+                         FuzzerRandomBase &Rand) {
+  if (Size == MaxSize) return Size;
+  size_t Idx = Rand(Size + 1);
+  // Insert new value at Data[Idx].
+  memmove(Data + Idx + 1, Data + Idx, Size - Idx);
+  Data[Idx] = RandCh(Rand);
+  return Size + 1;
+}
+
+size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize,
+                         FuzzerRandomBase &Rand) {
+  size_t Idx = Rand(Size);
+  Data[Idx] = RandCh(Rand);
+  return Size;
+}
+
+size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize,
+                        FuzzerRandomBase &Rand) {
+  size_t Idx = Rand(Size);
+  Data[Idx] = FlipRandomBit(Data[Idx], Rand);
+  return Size;
+}
+
 // Mutates Data in place, returns new size.
 size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
               FuzzerRandomBase &Rand) {
@@ -44,26 +91,12 @@ size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
     return MaxSize;
   }
   assert(Size > 0);
-  size_t Idx = Rand(Size);
-  switch (Rand(3)) {
-  case 0:
-    if (Size > 1) {
-      // Erase Data[Idx].
-      memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
-      Size = Size - 1;
-    }
-    [[clang::fallthrough]];
-  case 1:
-    if (Size < MaxSize) {
-      // Insert new value at Data[Idx].
-      memmove(Data + Idx + 1, Data + Idx, Size - Idx);
-      Data[Idx] = RandCh(Rand);
-    }
-    Data[Idx] = RandCh(Rand);
-    break;
-  case 2:
-    Data[Idx] = FlipRandomBit(Data[Idx], Rand);
-    break;
+  switch (Rand(5)) {
+  case 0: Size = Mutate_EraseByte(Data, Size, MaxSize, Rand); break;
+  case 1: Size = Mutate_InsertByte(Data, Size, MaxSize, Rand); break;
+  case 2: Size = Mutate_ChangeByte(Data, Size, MaxSize, Rand); break;
+  case 3: Size = Mutate_ChangeBit(Data, Size, MaxSize, Rand); break;
+  case 4: Size = Mutate_ShuffleBytes(Data, Size, MaxSize, Rand); break;
   }
   assert(Size > 0);
   return Size;