Home | History | Annotate | Line # | Download | only in fuzzer
      1 //===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 // Mutate a test input.
     10 //===----------------------------------------------------------------------===//
     11 
     12 #include "FuzzerMutate.h"
     13 #include "FuzzerCorpus.h"
     14 #include "FuzzerDefs.h"
     15 #include "FuzzerExtFunctions.h"
     16 #include "FuzzerIO.h"
     17 #include "FuzzerOptions.h"
     18 
     19 namespace fuzzer {
     20 
     21 const size_t Dictionary::kMaxDictSize;
     22 
     23 static void PrintASCII(const Word &W, const char *PrintAfter) {
     24   PrintASCII(W.data(), W.size(), PrintAfter);
     25 }
     26 
     27 MutationDispatcher::MutationDispatcher(Random &Rand,
     28                                        const FuzzingOptions &Options)
     29     : Rand(Rand), Options(Options) {
     30   DefaultMutators.insert(
     31       DefaultMutators.begin(),
     32       {
     33           {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"},
     34           {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
     35           {&MutationDispatcher::Mutate_InsertRepeatedBytes,
     36            "InsertRepeatedBytes"},
     37           {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
     38           {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
     39           {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
     40           {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
     41           {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"},
     42           {&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
     43           {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
     44           {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
     45            "ManualDict"},
     46           {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
     47            "PersAutoDict"},
     48       });
     49   if(Options.UseCmp)
     50     DefaultMutators.push_back(
     51         {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP"});
     52 
     53   if (EF->LLVMFuzzerCustomMutator)
     54     Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
     55   else
     56     Mutators = DefaultMutators;
     57 
     58   if (EF->LLVMFuzzerCustomCrossOver)
     59     Mutators.push_back(
     60         {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
     61 }
     62 
     63 static char RandCh(Random &Rand) {
     64   if (Rand.RandBool()) return Rand(256);
     65   const char Special[] = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
     66   return Special[Rand(sizeof(Special) - 1)];
     67 }
     68 
     69 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
     70                                          size_t MaxSize) {
     71   return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
     72 }
     73 
     74 size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
     75                                                   size_t MaxSize) {
     76   if (!Corpus || Corpus->size() < 2 || Size == 0)
     77     return 0;
     78   size_t Idx = Rand(Corpus->size());
     79   const Unit &Other = (*Corpus)[Idx];
     80   if (Other.empty())
     81     return 0;
     82   CustomCrossOverInPlaceHere.resize(MaxSize);
     83   auto &U = CustomCrossOverInPlaceHere;
     84   size_t NewSize = EF->LLVMFuzzerCustomCrossOver(
     85       Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());
     86   if (!NewSize)
     87     return 0;
     88   assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
     89   memcpy(Data, U.data(), NewSize);
     90   return NewSize;
     91 }
     92 
     93 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
     94                                                size_t MaxSize) {
     95   if (Size > MaxSize || Size == 0) return 0;
     96   size_t ShuffleAmount =
     97       Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
     98   size_t ShuffleStart = Rand(Size - ShuffleAmount);
     99   assert(ShuffleStart + ShuffleAmount <= Size);
    100   std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
    101   return Size;
    102 }
    103 
    104 size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,
    105                                              size_t MaxSize) {
    106   if (Size <= 1) return 0;
    107   size_t N = Rand(Size / 2) + 1;
    108   assert(N < Size);
    109   size_t Idx = Rand(Size - N + 1);
    110   // Erase Data[Idx:Idx+N].
    111   memmove(Data + Idx, Data + Idx + N, Size - Idx - N);
    112   // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
    113   return Size - N;
    114 }
    115 
    116 size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
    117                                              size_t MaxSize) {
    118   if (Size >= MaxSize) return 0;
    119   size_t Idx = Rand(Size + 1);
    120   // Insert new value at Data[Idx].
    121   memmove(Data + Idx + 1, Data + Idx, Size - Idx);
    122   Data[Idx] = RandCh(Rand);
    123   return Size + 1;
    124 }
    125 
    126 size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data,
    127                                                       size_t Size,
    128                                                       size_t MaxSize) {
    129   const size_t kMinBytesToInsert = 3;
    130   if (Size + kMinBytesToInsert >= MaxSize) return 0;
    131   size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);
    132   size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;
    133   assert(Size + N <= MaxSize && N);
    134   size_t Idx = Rand(Size + 1);
    135   // Insert new values at Data[Idx].
    136   memmove(Data + Idx + N, Data + Idx, Size - Idx);
    137   // Give preference to 0x00 and 0xff.
    138   uint8_t Byte = Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255);
    139   for (size_t i = 0; i < N; i++)
    140     Data[Idx + i] = Byte;
    141   return Size + N;
    142 }
    143 
    144 size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
    145                                              size_t MaxSize) {
    146   if (Size > MaxSize) return 0;
    147   size_t Idx = Rand(Size);
    148   Data[Idx] = RandCh(Rand);
    149   return Size;
    150 }
    151 
    152 size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
    153                                             size_t MaxSize) {
    154   if (Size > MaxSize) return 0;
    155   size_t Idx = Rand(Size);
    156   Data[Idx] ^= 1 << Rand(8);
    157   return Size;
    158 }
    159 
    160 size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,
    161                                                               size_t Size,
    162                                                               size_t MaxSize) {
    163   return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);
    164 }
    165 
    166 size_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data, size_t Size,
    167                                                 size_t MaxSize,
    168                                                 DictionaryEntry &DE) {
    169   const Word &W = DE.GetW();
    170   bool UsePositionHint = DE.HasPositionHint() &&
    171                          DE.GetPositionHint() + W.size() < Size &&
    172                          Rand.RandBool();
    173   if (Rand.RandBool()) {  // Insert W.
    174     if (Size + W.size() > MaxSize) return 0;
    175     size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1);
    176     memmove(Data + Idx + W.size(), Data + Idx, Size - Idx);
    177     memcpy(Data + Idx, W.data(), W.size());
    178     Size += W.size();
    179   } else {  // Overwrite some bytes with W.
    180     if (W.size() > Size) return 0;
    181     size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size - W.size());
    182     memcpy(Data + Idx, W.data(), W.size());
    183   }
    184   return Size;
    185 }
    186 
    187 // Somewhere in the past we have observed a comparison instructions
    188 // with arguments Arg1 Arg2. This function tries to guess a dictionary
    189 // entry that will satisfy that comparison.
    190 // It first tries to find one of the arguments (possibly swapped) in the
    191 // input and if it succeeds it creates a DE with a position hint.
    192 // Otherwise it creates a DE with one of the arguments w/o a position hint.
    193 DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
    194     const void *Arg1, const void *Arg2,
    195     const void *Arg1Mutation, const void *Arg2Mutation,
    196     size_t ArgSize, const uint8_t *Data,
    197     size_t Size) {
    198   bool HandleFirst = Rand.RandBool();
    199   const void *ExistingBytes, *DesiredBytes;
    200   Word W;
    201   const uint8_t *End = Data + Size;
    202   for (int Arg = 0; Arg < 2; Arg++) {
    203     ExistingBytes = HandleFirst ? Arg1 : Arg2;
    204     DesiredBytes = HandleFirst ? Arg2Mutation : Arg1Mutation;
    205     HandleFirst = !HandleFirst;
    206     W.Set(reinterpret_cast<const uint8_t*>(DesiredBytes), ArgSize);
    207     const size_t kMaxNumPositions = 8;
    208     size_t Positions[kMaxNumPositions];
    209     size_t NumPositions = 0;
    210     for (const uint8_t *Cur = Data;
    211          Cur < End && NumPositions < kMaxNumPositions; Cur++) {
    212       Cur =
    213           (const uint8_t *)SearchMemory(Cur, End - Cur, ExistingBytes, ArgSize);
    214       if (!Cur) break;
    215       Positions[NumPositions++] = Cur - Data;
    216     }
    217     if (!NumPositions) continue;
    218     return DictionaryEntry(W, Positions[Rand(NumPositions)]);
    219   }
    220   DictionaryEntry DE(W);
    221   return DE;
    222 }
    223 
    224 
    225 template <class T>
    226 DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
    227     T Arg1, T Arg2, const uint8_t *Data, size_t Size) {
    228   if (Rand.RandBool()) Arg1 = Bswap(Arg1);
    229   if (Rand.RandBool()) Arg2 = Bswap(Arg2);
    230   T Arg1Mutation = Arg1 + Rand(-1, 1);
    231   T Arg2Mutation = Arg2 + Rand(-1, 1);
    232   return MakeDictionaryEntryFromCMP(&Arg1, &Arg2, &Arg1Mutation, &Arg2Mutation,
    233                                     sizeof(Arg1), Data, Size);
    234 }
    235 
    236 DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
    237     const Word &Arg1, const Word &Arg2, const uint8_t *Data, size_t Size) {
    238   return MakeDictionaryEntryFromCMP(Arg1.data(), Arg2.data(), Arg1.data(),
    239                                     Arg2.data(), Arg1.size(), Data, Size);
    240 }
    241 
    242 size_t MutationDispatcher::Mutate_AddWordFromTORC(
    243     uint8_t *Data, size_t Size, size_t MaxSize) {
    244   Word W;
    245   DictionaryEntry DE;
    246   switch (Rand(4)) {
    247   case 0: {
    248     auto X = TPC.TORC8.Get(Rand.Rand());
    249     DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
    250   } break;
    251   case 1: {
    252     auto X = TPC.TORC4.Get(Rand.Rand());
    253     if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool())
    254       DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data, Size);
    255     else
    256       DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
    257   } break;
    258   case 2: {
    259     auto X = TPC.TORCW.Get(Rand.Rand());
    260     DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
    261   } break;
    262   case 3: if (Options.UseMemmem) {
    263     auto X = TPC.MMT.Get(Rand.Rand());
    264     DE = DictionaryEntry(X);
    265   } break;
    266   default:
    267     assert(0);
    268   }
    269   if (!DE.GetW().size()) return 0;
    270   Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
    271   if (!Size) return 0;
    272   DictionaryEntry &DERef =
    273       CmpDictionaryEntriesDeque[CmpDictionaryEntriesDequeIdx++ %
    274                                 kCmpDictionaryEntriesDequeSize];
    275   DERef = DE;
    276   CurrentDictionaryEntrySequence.push_back(&DERef);
    277   return Size;
    278 }
    279 
    280 size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
    281     uint8_t *Data, size_t Size, size_t MaxSize) {
    282   return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);
    283 }
    284 
    285 size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
    286                                                  size_t Size, size_t MaxSize) {
    287   if (Size > MaxSize) return 0;
    288   if (D.empty()) return 0;
    289   DictionaryEntry &DE = D[Rand(D.size())];
    290   Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
    291   if (!Size) return 0;
    292   DE.IncUseCount();
    293   CurrentDictionaryEntrySequence.push_back(&DE);
    294   return Size;
    295 }
    296 
    297 // Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
    298 // Returns ToSize.
    299 size_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,
    300                                       uint8_t *To, size_t ToSize) {
    301   // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
    302   size_t ToBeg = Rand(ToSize);
    303   size_t CopySize = Rand(ToSize - ToBeg) + 1;
    304   assert(ToBeg + CopySize <= ToSize);
    305   CopySize = std::min(CopySize, FromSize);
    306   size_t FromBeg = Rand(FromSize - CopySize + 1);
    307   assert(FromBeg + CopySize <= FromSize);
    308   memmove(To + ToBeg, From + FromBeg, CopySize);
    309   return ToSize;
    310 }
    311 
    312 // Inserts part of From[0,ToSize) into To.
    313 // Returns new size of To on success or 0 on failure.
    314 size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,
    315                                         uint8_t *To, size_t ToSize,
    316                                         size_t MaxToSize) {
    317   if (ToSize >= MaxToSize) return 0;
    318   size_t AvailableSpace = MaxToSize - ToSize;
    319   size_t MaxCopySize = std::min(AvailableSpace, FromSize);
    320   size_t CopySize = Rand(MaxCopySize) + 1;
    321   size_t FromBeg = Rand(FromSize - CopySize + 1);
    322   assert(FromBeg + CopySize <= FromSize);
    323   size_t ToInsertPos = Rand(ToSize + 1);
    324   assert(ToInsertPos + CopySize <= MaxToSize);
    325   size_t TailSize = ToSize - ToInsertPos;
    326   if (To == From) {
    327     MutateInPlaceHere.resize(MaxToSize);
    328     memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);
    329     memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
    330     memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);
    331   } else {
    332     memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
    333     memmove(To + ToInsertPos, From + FromBeg, CopySize);
    334   }
    335   return ToSize + CopySize;
    336 }
    337 
    338 size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,
    339                                            size_t MaxSize) {
    340   if (Size > MaxSize || Size == 0) return 0;
    341   // If Size == MaxSize, `InsertPartOf(...)` will
    342   // fail so there's no point using it in this case.
    343   if (Size == MaxSize || Rand.RandBool())
    344     return CopyPartOf(Data, Size, Data, Size);
    345   else
    346     return InsertPartOf(Data, Size, Data, Size, MaxSize);
    347 }
    348 
    349 size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
    350                                                      size_t MaxSize) {
    351   if (Size > MaxSize) return 0;
    352   size_t B = Rand(Size);
    353   while (B < Size && !isdigit(Data[B])) B++;
    354   if (B == Size) return 0;
    355   size_t E = B;
    356   while (E < Size && isdigit(Data[E])) E++;
    357   assert(B < E);
    358   // now we have digits in [B, E).
    359   // strtol and friends don't accept non-zero-teminated data, parse it manually.
    360   uint64_t Val = Data[B] - '0';
    361   for (size_t i = B + 1; i < E; i++)
    362     Val = Val * 10 + Data[i] - '0';
    363 
    364   // Mutate the integer value.
    365   switch(Rand(5)) {
    366     case 0: Val++; break;
    367     case 1: Val--; break;
    368     case 2: Val /= 2; break;
    369     case 3: Val *= 2; break;
    370     case 4: Val = Rand(Val * Val); break;
    371     default: assert(0);
    372   }
    373   // Just replace the bytes with the new ones, don't bother moving bytes.
    374   for (size_t i = B; i < E; i++) {
    375     size_t Idx = E + B - i - 1;
    376     assert(Idx >= B && Idx < E);
    377     Data[Idx] = (Val % 10) + '0';
    378     Val /= 10;
    379   }
    380   return Size;
    381 }
    382 
    383 template<class T>
    384 size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
    385   if (Size < sizeof(T)) return 0;
    386   size_t Off = Rand(Size - sizeof(T) + 1);
    387   assert(Off + sizeof(T) <= Size);
    388   T Val;
    389   if (Off < 64 && !Rand(4)) {
    390     Val = Size;
    391     if (Rand.RandBool())
    392       Val = Bswap(Val);
    393   } else {
    394     memcpy(&Val, Data + Off, sizeof(Val));
    395     T Add = Rand(21);
    396     Add -= 10;
    397     if (Rand.RandBool())
    398       Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
    399     else
    400       Val = Val + Add;               // Add assuming current endiannes.
    401     if (Add == 0 || Rand.RandBool()) // Maybe negate.
    402       Val = -Val;
    403   }
    404   memcpy(Data + Off, &Val, sizeof(Val));
    405   return Size;
    406 }
    407 
    408 size_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data,
    409                                                       size_t Size,
    410                                                       size_t MaxSize) {
    411   if (Size > MaxSize) return 0;
    412   switch (Rand(4)) {
    413     case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);
    414     case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);
    415     case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);
    416     case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);
    417     default: assert(0);
    418   }
    419   return 0;
    420 }
    421 
    422 size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
    423                                             size_t MaxSize) {
    424   if (Size > MaxSize) return 0;
    425   if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
    426   size_t Idx = Rand(Corpus->size());
    427   const Unit &O = (*Corpus)[Idx];
    428   if (O.empty()) return 0;
    429   MutateInPlaceHere.resize(MaxSize);
    430   auto &U = MutateInPlaceHere;
    431   size_t NewSize = 0;
    432   switch(Rand(3)) {
    433     case 0:
    434       NewSize = CrossOver(Data, Size, O.data(), O.size(), U.data(), U.size());
    435       break;
    436     case 1:
    437       NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize);
    438       if (!NewSize)
    439         NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());
    440       break;
    441     case 2:
    442       NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());
    443       break;
    444     default: assert(0);
    445   }
    446   assert(NewSize > 0 && "CrossOver returned empty unit");
    447   assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
    448   memcpy(Data, U.data(), NewSize);
    449   return NewSize;
    450 }
    451 
    452 void MutationDispatcher::StartMutationSequence() {
    453   CurrentMutatorSequence.clear();
    454   CurrentDictionaryEntrySequence.clear();
    455 }
    456 
    457 // Copy successful dictionary entries to PersistentAutoDictionary.
    458 void MutationDispatcher::RecordSuccessfulMutationSequence() {
    459   for (auto DE : CurrentDictionaryEntrySequence) {
    460     // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
    461     DE->IncSuccessCount();
    462     assert(DE->GetW().size());
    463     // Linear search is fine here as this happens seldom.
    464     if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
    465       PersistentAutoDictionary.push_back({DE->GetW(), 1});
    466   }
    467 }
    468 
    469 void MutationDispatcher::PrintRecommendedDictionary() {
    470   Vector<DictionaryEntry> V;
    471   for (auto &DE : PersistentAutoDictionary)
    472     if (!ManualDictionary.ContainsWord(DE.GetW()))
    473       V.push_back(DE);
    474   if (V.empty()) return;
    475   Printf("###### Recommended dictionary. ######\n");
    476   for (auto &DE: V) {
    477     assert(DE.GetW().size());
    478     Printf("\"");
    479     PrintASCII(DE.GetW(), "\"");
    480     Printf(" # Uses: %zd\n", DE.GetUseCount());
    481   }
    482   Printf("###### End of recommended dictionary. ######\n");
    483 }
    484 
    485 void MutationDispatcher::PrintMutationSequence() {
    486   Printf("MS: %zd ", CurrentMutatorSequence.size());
    487   for (auto M : CurrentMutatorSequence)
    488     Printf("%s-", M.Name);
    489   if (!CurrentDictionaryEntrySequence.empty()) {
    490     Printf(" DE: ");
    491     for (auto DE : CurrentDictionaryEntrySequence) {
    492       Printf("\"");
    493       PrintASCII(DE->GetW(), "\"-");
    494     }
    495   }
    496 }
    497 
    498 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
    499   return MutateImpl(Data, Size, MaxSize, Mutators);
    500 }
    501 
    502 size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
    503                                          size_t MaxSize) {
    504   return MutateImpl(Data, Size, MaxSize, DefaultMutators);
    505 }
    506 
    507 // Mutates Data in place, returns new size.
    508 size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
    509                                       size_t MaxSize,
    510                                       Vector<Mutator> &Mutators) {
    511   assert(MaxSize > 0);
    512   // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
    513   // in which case they will return 0.
    514   // Try several times before returning un-mutated data.
    515   for (int Iter = 0; Iter < 100; Iter++) {
    516     auto M = Mutators[Rand(Mutators.size())];
    517     size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
    518     if (NewSize && NewSize <= MaxSize) {
    519       if (Options.OnlyASCII)
    520         ToASCII(Data, NewSize);
    521       CurrentMutatorSequence.push_back(M);
    522       return NewSize;
    523     }
    524   }
    525   *Data = ' ';
    526   return 1;   // Fallback, should not happen frequently.
    527 }
    528 
    529 // Mask represents the set of Data bytes that are worth mutating.
    530 size_t MutationDispatcher::MutateWithMask(uint8_t *Data, size_t Size,
    531                                           size_t MaxSize,
    532                                           const Vector<uint8_t> &Mask) {
    533   assert(Size <= Mask.size());
    534   // * Copy the worthy bytes into a temporary array T
    535   // * Mutate T
    536   // * Copy T back.
    537   // This is totally unoptimized.
    538   auto &T = MutateWithMaskTemp;
    539   if (T.size() < Size)
    540     T.resize(Size);
    541   size_t OneBits = 0;
    542   for (size_t I = 0; I < Size; I++)
    543     if (Mask[I])
    544       T[OneBits++] = Data[I];
    545 
    546   assert(!T.empty());
    547   size_t NewSize = Mutate(T.data(), OneBits, OneBits);
    548   assert(NewSize <= OneBits);
    549   (void)NewSize;
    550   // Even if NewSize < OneBits we still use all OneBits bytes.
    551   for (size_t I = 0, J = 0; I < Size; I++)
    552     if (Mask[I])
    553       Data[I] = T[J++];
    554   return Size;
    555 }
    556 
    557 void MutationDispatcher::AddWordToManualDictionary(const Word &W) {
    558   ManualDictionary.push_back(
    559       {W, std::numeric_limits<size_t>::max()});
    560 }
    561 
    562 }  // namespace fuzzer
    563