xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerMutate.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric // Mutate a test input.
90b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "FuzzerDefs.h"
120b57cec5SDimitry Andric #include "FuzzerExtFunctions.h"
130b57cec5SDimitry Andric #include "FuzzerIO.h"
140b57cec5SDimitry Andric #include "FuzzerMutate.h"
150b57cec5SDimitry Andric #include "FuzzerOptions.h"
160b57cec5SDimitry Andric #include "FuzzerTracePC.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric namespace fuzzer {
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric const size_t Dictionary::kMaxDictSize;
21e8d8bef9SDimitry Andric static const size_t kMaxMutationsToPrint = 10;
220b57cec5SDimitry Andric 
PrintASCII(const Word & W,const char * PrintAfter)230b57cec5SDimitry Andric static void PrintASCII(const Word &W, const char *PrintAfter) {
240b57cec5SDimitry Andric   PrintASCII(W.data(), W.size(), PrintAfter);
250b57cec5SDimitry Andric }
260b57cec5SDimitry Andric 
MutationDispatcher(Random & Rand,const FuzzingOptions & Options)270b57cec5SDimitry Andric MutationDispatcher::MutationDispatcher(Random &Rand,
280b57cec5SDimitry Andric                                        const FuzzingOptions &Options)
290b57cec5SDimitry Andric     : Rand(Rand), Options(Options) {
300b57cec5SDimitry Andric   DefaultMutators.insert(
310b57cec5SDimitry Andric       DefaultMutators.begin(),
320b57cec5SDimitry Andric       {
330b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"},
340b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
350b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_InsertRepeatedBytes,
360b57cec5SDimitry Andric            "InsertRepeatedBytes"},
370b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
380b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
390b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
400b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
410b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"},
420b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
430b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
440b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
450b57cec5SDimitry Andric            "ManualDict"},
460b57cec5SDimitry Andric           {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
470b57cec5SDimitry Andric            "PersAutoDict"},
480b57cec5SDimitry Andric       });
490b57cec5SDimitry Andric   if(Options.UseCmp)
500b57cec5SDimitry Andric     DefaultMutators.push_back(
510b57cec5SDimitry Andric         {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP"});
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   if (EF->LLVMFuzzerCustomMutator)
540b57cec5SDimitry Andric     Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
550b57cec5SDimitry Andric   else
560b57cec5SDimitry Andric     Mutators = DefaultMutators;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   if (EF->LLVMFuzzerCustomCrossOver)
590b57cec5SDimitry Andric     Mutators.push_back(
600b57cec5SDimitry Andric         {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
RandCh(Random & Rand)630b57cec5SDimitry Andric static char RandCh(Random &Rand) {
64fe6060f1SDimitry Andric   if (Rand.RandBool())
65fe6060f1SDimitry Andric     return static_cast<char>(Rand(256));
660b57cec5SDimitry Andric   const char Special[] = "!*'();:@&=+$,/?%#[]012Az-`~.\xff\x00";
670b57cec5SDimitry Andric   return Special[Rand(sizeof(Special) - 1)];
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric 
Mutate_Custom(uint8_t * Data,size_t Size,size_t MaxSize)700b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
710b57cec5SDimitry Andric                                          size_t MaxSize) {
72fe6060f1SDimitry Andric   if (EF->__msan_unpoison)
73fe6060f1SDimitry Andric     EF->__msan_unpoison(Data, Size);
74fe6060f1SDimitry Andric   if (EF->__msan_unpoison_param)
75fe6060f1SDimitry Andric     EF->__msan_unpoison_param(4);
76fe6060f1SDimitry Andric   return EF->LLVMFuzzerCustomMutator(Data, Size, MaxSize,
77fe6060f1SDimitry Andric                                      Rand.Rand<unsigned int>());
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
Mutate_CustomCrossOver(uint8_t * Data,size_t Size,size_t MaxSize)800b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
810b57cec5SDimitry Andric                                                   size_t MaxSize) {
820b57cec5SDimitry Andric   if (Size == 0)
830b57cec5SDimitry Andric     return 0;
840b57cec5SDimitry Andric   if (!CrossOverWith) return 0;
850b57cec5SDimitry Andric   const Unit &Other = *CrossOverWith;
860b57cec5SDimitry Andric   if (Other.empty())
870b57cec5SDimitry Andric     return 0;
880b57cec5SDimitry Andric   CustomCrossOverInPlaceHere.resize(MaxSize);
890b57cec5SDimitry Andric   auto &U = CustomCrossOverInPlaceHere;
90fe6060f1SDimitry Andric 
91fe6060f1SDimitry Andric   if (EF->__msan_unpoison) {
92fe6060f1SDimitry Andric     EF->__msan_unpoison(Data, Size);
93fe6060f1SDimitry Andric     EF->__msan_unpoison(Other.data(), Other.size());
94fe6060f1SDimitry Andric     EF->__msan_unpoison(U.data(), U.size());
95fe6060f1SDimitry Andric   }
96fe6060f1SDimitry Andric   if (EF->__msan_unpoison_param)
97fe6060f1SDimitry Andric     EF->__msan_unpoison_param(7);
980b57cec5SDimitry Andric   size_t NewSize = EF->LLVMFuzzerCustomCrossOver(
99fe6060f1SDimitry Andric       Data, Size, Other.data(), Other.size(), U.data(), U.size(),
100fe6060f1SDimitry Andric       Rand.Rand<unsigned int>());
101fe6060f1SDimitry Andric 
1020b57cec5SDimitry Andric   if (!NewSize)
1030b57cec5SDimitry Andric     return 0;
1040b57cec5SDimitry Andric   assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
1050b57cec5SDimitry Andric   memcpy(Data, U.data(), NewSize);
1060b57cec5SDimitry Andric   return NewSize;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
Mutate_ShuffleBytes(uint8_t * Data,size_t Size,size_t MaxSize)1090b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
1100b57cec5SDimitry Andric                                                size_t MaxSize) {
1110b57cec5SDimitry Andric   if (Size > MaxSize || Size == 0) return 0;
1120b57cec5SDimitry Andric   size_t ShuffleAmount =
1130b57cec5SDimitry Andric       Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
1140b57cec5SDimitry Andric   size_t ShuffleStart = Rand(Size - ShuffleAmount);
1150b57cec5SDimitry Andric   assert(ShuffleStart + ShuffleAmount <= Size);
1160b57cec5SDimitry Andric   std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
1170b57cec5SDimitry Andric   return Size;
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
Mutate_EraseBytes(uint8_t * Data,size_t Size,size_t MaxSize)1200b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_EraseBytes(uint8_t *Data, size_t Size,
1210b57cec5SDimitry Andric                                              size_t MaxSize) {
1220b57cec5SDimitry Andric   if (Size <= 1) return 0;
1230b57cec5SDimitry Andric   size_t N = Rand(Size / 2) + 1;
1240b57cec5SDimitry Andric   assert(N < Size);
1250b57cec5SDimitry Andric   size_t Idx = Rand(Size - N + 1);
1260b57cec5SDimitry Andric   // Erase Data[Idx:Idx+N].
1270b57cec5SDimitry Andric   memmove(Data + Idx, Data + Idx + N, Size - Idx - N);
1280b57cec5SDimitry Andric   // Printf("Erase: %zd %zd => %zd; Idx %zd\n", N, Size, Size - N, Idx);
1290b57cec5SDimitry Andric   return Size - N;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
Mutate_InsertByte(uint8_t * Data,size_t Size,size_t MaxSize)1320b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
1330b57cec5SDimitry Andric                                              size_t MaxSize) {
1340b57cec5SDimitry Andric   if (Size >= MaxSize) return 0;
1350b57cec5SDimitry Andric   size_t Idx = Rand(Size + 1);
1360b57cec5SDimitry Andric   // Insert new value at Data[Idx].
1370b57cec5SDimitry Andric   memmove(Data + Idx + 1, Data + Idx, Size - Idx);
1380b57cec5SDimitry Andric   Data[Idx] = RandCh(Rand);
1390b57cec5SDimitry Andric   return Size + 1;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
Mutate_InsertRepeatedBytes(uint8_t * Data,size_t Size,size_t MaxSize)1420b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_InsertRepeatedBytes(uint8_t *Data,
1430b57cec5SDimitry Andric                                                       size_t Size,
1440b57cec5SDimitry Andric                                                       size_t MaxSize) {
1450b57cec5SDimitry Andric   const size_t kMinBytesToInsert = 3;
1460b57cec5SDimitry Andric   if (Size + kMinBytesToInsert >= MaxSize) return 0;
1470b57cec5SDimitry Andric   size_t MaxBytesToInsert = std::min(MaxSize - Size, (size_t)128);
1480b57cec5SDimitry Andric   size_t N = Rand(MaxBytesToInsert - kMinBytesToInsert + 1) + kMinBytesToInsert;
1490b57cec5SDimitry Andric   assert(Size + N <= MaxSize && N);
1500b57cec5SDimitry Andric   size_t Idx = Rand(Size + 1);
1510b57cec5SDimitry Andric   // Insert new values at Data[Idx].
1520b57cec5SDimitry Andric   memmove(Data + Idx + N, Data + Idx, Size - Idx);
1530b57cec5SDimitry Andric   // Give preference to 0x00 and 0xff.
154fe6060f1SDimitry Andric   uint8_t Byte = static_cast<uint8_t>(
155fe6060f1SDimitry Andric       Rand.RandBool() ? Rand(256) : (Rand.RandBool() ? 0 : 255));
1560b57cec5SDimitry Andric   for (size_t i = 0; i < N; i++)
1570b57cec5SDimitry Andric     Data[Idx + i] = Byte;
1580b57cec5SDimitry Andric   return Size + N;
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
Mutate_ChangeByte(uint8_t * Data,size_t Size,size_t MaxSize)1610b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
1620b57cec5SDimitry Andric                                              size_t MaxSize) {
1630b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
1640b57cec5SDimitry Andric   size_t Idx = Rand(Size);
1650b57cec5SDimitry Andric   Data[Idx] = RandCh(Rand);
1660b57cec5SDimitry Andric   return Size;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
Mutate_ChangeBit(uint8_t * Data,size_t Size,size_t MaxSize)1690b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
1700b57cec5SDimitry Andric                                             size_t MaxSize) {
1710b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
1720b57cec5SDimitry Andric   size_t Idx = Rand(Size);
1730b57cec5SDimitry Andric   Data[Idx] ^= 1 << Rand(8);
1740b57cec5SDimitry Andric   return Size;
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
Mutate_AddWordFromManualDictionary(uint8_t * Data,size_t Size,size_t MaxSize)1770b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_AddWordFromManualDictionary(uint8_t *Data,
1780b57cec5SDimitry Andric                                                               size_t Size,
1790b57cec5SDimitry Andric                                                               size_t MaxSize) {
1800b57cec5SDimitry Andric   return AddWordFromDictionary(ManualDictionary, Data, Size, MaxSize);
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
ApplyDictionaryEntry(uint8_t * Data,size_t Size,size_t MaxSize,DictionaryEntry & DE)1830b57cec5SDimitry Andric size_t MutationDispatcher::ApplyDictionaryEntry(uint8_t *Data, size_t Size,
1840b57cec5SDimitry Andric                                                 size_t MaxSize,
1850b57cec5SDimitry Andric                                                 DictionaryEntry &DE) {
1860b57cec5SDimitry Andric   const Word &W = DE.GetW();
1870b57cec5SDimitry Andric   bool UsePositionHint = DE.HasPositionHint() &&
1880b57cec5SDimitry Andric                          DE.GetPositionHint() + W.size() < Size &&
1890b57cec5SDimitry Andric                          Rand.RandBool();
1900b57cec5SDimitry Andric   if (Rand.RandBool()) {  // Insert W.
1910b57cec5SDimitry Andric     if (Size + W.size() > MaxSize) return 0;
1920b57cec5SDimitry Andric     size_t Idx = UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1);
1930b57cec5SDimitry Andric     memmove(Data + Idx + W.size(), Data + Idx, Size - Idx);
1940b57cec5SDimitry Andric     memcpy(Data + Idx, W.data(), W.size());
1950b57cec5SDimitry Andric     Size += W.size();
1960b57cec5SDimitry Andric   } else {  // Overwrite some bytes with W.
1970b57cec5SDimitry Andric     if (W.size() > Size) return 0;
198fe6060f1SDimitry Andric     size_t Idx =
199fe6060f1SDimitry Andric         UsePositionHint ? DE.GetPositionHint() : Rand(Size + 1 - W.size());
2000b57cec5SDimitry Andric     memcpy(Data + Idx, W.data(), W.size());
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric   return Size;
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric // Somewhere in the past we have observed a comparison instructions
2060b57cec5SDimitry Andric // with arguments Arg1 Arg2. This function tries to guess a dictionary
2070b57cec5SDimitry Andric // entry that will satisfy that comparison.
2080b57cec5SDimitry Andric // It first tries to find one of the arguments (possibly swapped) in the
2090b57cec5SDimitry Andric // input and if it succeeds it creates a DE with a position hint.
2100b57cec5SDimitry Andric // Otherwise it creates a DE with one of the arguments w/o a position hint.
MakeDictionaryEntryFromCMP(const void * Arg1,const void * Arg2,const void * Arg1Mutation,const void * Arg2Mutation,size_t ArgSize,const uint8_t * Data,size_t Size)2110b57cec5SDimitry Andric DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
2120b57cec5SDimitry Andric     const void *Arg1, const void *Arg2,
2130b57cec5SDimitry Andric     const void *Arg1Mutation, const void *Arg2Mutation,
2140b57cec5SDimitry Andric     size_t ArgSize, const uint8_t *Data,
2150b57cec5SDimitry Andric     size_t Size) {
2160b57cec5SDimitry Andric   bool HandleFirst = Rand.RandBool();
2170b57cec5SDimitry Andric   const void *ExistingBytes, *DesiredBytes;
2180b57cec5SDimitry Andric   Word W;
2190b57cec5SDimitry Andric   const uint8_t *End = Data + Size;
2200b57cec5SDimitry Andric   for (int Arg = 0; Arg < 2; Arg++) {
2210b57cec5SDimitry Andric     ExistingBytes = HandleFirst ? Arg1 : Arg2;
2220b57cec5SDimitry Andric     DesiredBytes = HandleFirst ? Arg2Mutation : Arg1Mutation;
2230b57cec5SDimitry Andric     HandleFirst = !HandleFirst;
2240b57cec5SDimitry Andric     W.Set(reinterpret_cast<const uint8_t*>(DesiredBytes), ArgSize);
2250b57cec5SDimitry Andric     const size_t kMaxNumPositions = 8;
2260b57cec5SDimitry Andric     size_t Positions[kMaxNumPositions];
2270b57cec5SDimitry Andric     size_t NumPositions = 0;
2280b57cec5SDimitry Andric     for (const uint8_t *Cur = Data;
2290b57cec5SDimitry Andric          Cur < End && NumPositions < kMaxNumPositions; Cur++) {
2300b57cec5SDimitry Andric       Cur =
2310b57cec5SDimitry Andric           (const uint8_t *)SearchMemory(Cur, End - Cur, ExistingBytes, ArgSize);
2320b57cec5SDimitry Andric       if (!Cur) break;
2330b57cec5SDimitry Andric       Positions[NumPositions++] = Cur - Data;
2340b57cec5SDimitry Andric     }
2350b57cec5SDimitry Andric     if (!NumPositions) continue;
2360b57cec5SDimitry Andric     return DictionaryEntry(W, Positions[Rand(NumPositions)]);
2370b57cec5SDimitry Andric   }
2380b57cec5SDimitry Andric   DictionaryEntry DE(W);
2390b57cec5SDimitry Andric   return DE;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric template <class T>
MakeDictionaryEntryFromCMP(T Arg1,T Arg2,const uint8_t * Data,size_t Size)2440b57cec5SDimitry Andric DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
2450b57cec5SDimitry Andric     T Arg1, T Arg2, const uint8_t *Data, size_t Size) {
2460b57cec5SDimitry Andric   if (Rand.RandBool()) Arg1 = Bswap(Arg1);
2470b57cec5SDimitry Andric   if (Rand.RandBool()) Arg2 = Bswap(Arg2);
248fe6060f1SDimitry Andric   T Arg1Mutation = static_cast<T>(Arg1 + Rand(-1, 1));
249fe6060f1SDimitry Andric   T Arg2Mutation = static_cast<T>(Arg2 + Rand(-1, 1));
2500b57cec5SDimitry Andric   return MakeDictionaryEntryFromCMP(&Arg1, &Arg2, &Arg1Mutation, &Arg2Mutation,
2510b57cec5SDimitry Andric                                     sizeof(Arg1), Data, Size);
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
MakeDictionaryEntryFromCMP(const Word & Arg1,const Word & Arg2,const uint8_t * Data,size_t Size)2540b57cec5SDimitry Andric DictionaryEntry MutationDispatcher::MakeDictionaryEntryFromCMP(
2550b57cec5SDimitry Andric     const Word &Arg1, const Word &Arg2, const uint8_t *Data, size_t Size) {
2560b57cec5SDimitry Andric   return MakeDictionaryEntryFromCMP(Arg1.data(), Arg2.data(), Arg1.data(),
2570b57cec5SDimitry Andric                                     Arg2.data(), Arg1.size(), Data, Size);
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
Mutate_AddWordFromTORC(uint8_t * Data,size_t Size,size_t MaxSize)2600b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_AddWordFromTORC(
2610b57cec5SDimitry Andric     uint8_t *Data, size_t Size, size_t MaxSize) {
2620b57cec5SDimitry Andric   Word W;
2630b57cec5SDimitry Andric   DictionaryEntry DE;
2640b57cec5SDimitry Andric   switch (Rand(4)) {
2650b57cec5SDimitry Andric   case 0: {
266fe6060f1SDimitry Andric     auto X = TPC.TORC8.Get(Rand.Rand<size_t>());
2670b57cec5SDimitry Andric     DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
2680b57cec5SDimitry Andric   } break;
2690b57cec5SDimitry Andric   case 1: {
270fe6060f1SDimitry Andric     auto X = TPC.TORC4.Get(Rand.Rand<size_t>());
2710b57cec5SDimitry Andric     if ((X.A >> 16) == 0 && (X.B >> 16) == 0 && Rand.RandBool())
2720b57cec5SDimitry Andric       DE = MakeDictionaryEntryFromCMP((uint16_t)X.A, (uint16_t)X.B, Data, Size);
2730b57cec5SDimitry Andric     else
2740b57cec5SDimitry Andric       DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
2750b57cec5SDimitry Andric   } break;
2760b57cec5SDimitry Andric   case 2: {
277fe6060f1SDimitry Andric     auto X = TPC.TORCW.Get(Rand.Rand<size_t>());
2780b57cec5SDimitry Andric     DE = MakeDictionaryEntryFromCMP(X.A, X.B, Data, Size);
2790b57cec5SDimitry Andric   } break;
2800b57cec5SDimitry Andric   case 3: if (Options.UseMemmem) {
281fe6060f1SDimitry Andric       auto X = TPC.MMT.Get(Rand.Rand<size_t>());
2820b57cec5SDimitry Andric       DE = DictionaryEntry(X);
2830b57cec5SDimitry Andric   } break;
2840b57cec5SDimitry Andric   default:
2850b57cec5SDimitry Andric     assert(0);
2860b57cec5SDimitry Andric   }
2870b57cec5SDimitry Andric   if (!DE.GetW().size()) return 0;
2880b57cec5SDimitry Andric   Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
2890b57cec5SDimitry Andric   if (!Size) return 0;
2900b57cec5SDimitry Andric   DictionaryEntry &DERef =
2910b57cec5SDimitry Andric       CmpDictionaryEntriesDeque[CmpDictionaryEntriesDequeIdx++ %
2920b57cec5SDimitry Andric                                 kCmpDictionaryEntriesDequeSize];
2930b57cec5SDimitry Andric   DERef = DE;
2940b57cec5SDimitry Andric   CurrentDictionaryEntrySequence.push_back(&DERef);
2950b57cec5SDimitry Andric   return Size;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
Mutate_AddWordFromPersistentAutoDictionary(uint8_t * Data,size_t Size,size_t MaxSize)2980b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary(
2990b57cec5SDimitry Andric     uint8_t *Data, size_t Size, size_t MaxSize) {
3000b57cec5SDimitry Andric   return AddWordFromDictionary(PersistentAutoDictionary, Data, Size, MaxSize);
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
AddWordFromDictionary(Dictionary & D,uint8_t * Data,size_t Size,size_t MaxSize)3030b57cec5SDimitry Andric size_t MutationDispatcher::AddWordFromDictionary(Dictionary &D, uint8_t *Data,
3040b57cec5SDimitry Andric                                                  size_t Size, size_t MaxSize) {
3050b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
3060b57cec5SDimitry Andric   if (D.empty()) return 0;
3070b57cec5SDimitry Andric   DictionaryEntry &DE = D[Rand(D.size())];
3080b57cec5SDimitry Andric   Size = ApplyDictionaryEntry(Data, Size, MaxSize, DE);
3090b57cec5SDimitry Andric   if (!Size) return 0;
3100b57cec5SDimitry Andric   DE.IncUseCount();
3110b57cec5SDimitry Andric   CurrentDictionaryEntrySequence.push_back(&DE);
3120b57cec5SDimitry Andric   return Size;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric // Overwrites part of To[0,ToSize) with a part of From[0,FromSize).
3160b57cec5SDimitry Andric // Returns ToSize.
CopyPartOf(const uint8_t * From,size_t FromSize,uint8_t * To,size_t ToSize)3170b57cec5SDimitry Andric size_t MutationDispatcher::CopyPartOf(const uint8_t *From, size_t FromSize,
3180b57cec5SDimitry Andric                                       uint8_t *To, size_t ToSize) {
3190b57cec5SDimitry Andric   // Copy From[FromBeg, FromBeg + CopySize) into To[ToBeg, ToBeg + CopySize).
3200b57cec5SDimitry Andric   size_t ToBeg = Rand(ToSize);
3210b57cec5SDimitry Andric   size_t CopySize = Rand(ToSize - ToBeg) + 1;
3220b57cec5SDimitry Andric   assert(ToBeg + CopySize <= ToSize);
3230b57cec5SDimitry Andric   CopySize = std::min(CopySize, FromSize);
3240b57cec5SDimitry Andric   size_t FromBeg = Rand(FromSize - CopySize + 1);
3250b57cec5SDimitry Andric   assert(FromBeg + CopySize <= FromSize);
3260b57cec5SDimitry Andric   memmove(To + ToBeg, From + FromBeg, CopySize);
3270b57cec5SDimitry Andric   return ToSize;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric // Inserts part of From[0,ToSize) into To.
3310b57cec5SDimitry Andric // Returns new size of To on success or 0 on failure.
InsertPartOf(const uint8_t * From,size_t FromSize,uint8_t * To,size_t ToSize,size_t MaxToSize)3320b57cec5SDimitry Andric size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize,
3330b57cec5SDimitry Andric                                         uint8_t *To, size_t ToSize,
3340b57cec5SDimitry Andric                                         size_t MaxToSize) {
3350b57cec5SDimitry Andric   if (ToSize >= MaxToSize) return 0;
3360b57cec5SDimitry Andric   size_t AvailableSpace = MaxToSize - ToSize;
3370b57cec5SDimitry Andric   size_t MaxCopySize = std::min(AvailableSpace, FromSize);
3380b57cec5SDimitry Andric   size_t CopySize = Rand(MaxCopySize) + 1;
3390b57cec5SDimitry Andric   size_t FromBeg = Rand(FromSize - CopySize + 1);
3400b57cec5SDimitry Andric   assert(FromBeg + CopySize <= FromSize);
3410b57cec5SDimitry Andric   size_t ToInsertPos = Rand(ToSize + 1);
3420b57cec5SDimitry Andric   assert(ToInsertPos + CopySize <= MaxToSize);
3430b57cec5SDimitry Andric   size_t TailSize = ToSize - ToInsertPos;
3440b57cec5SDimitry Andric   if (To == From) {
3450b57cec5SDimitry Andric     MutateInPlaceHere.resize(MaxToSize);
3460b57cec5SDimitry Andric     memcpy(MutateInPlaceHere.data(), From + FromBeg, CopySize);
3470b57cec5SDimitry Andric     memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
3480b57cec5SDimitry Andric     memmove(To + ToInsertPos, MutateInPlaceHere.data(), CopySize);
3490b57cec5SDimitry Andric   } else {
3500b57cec5SDimitry Andric     memmove(To + ToInsertPos + CopySize, To + ToInsertPos, TailSize);
3510b57cec5SDimitry Andric     memmove(To + ToInsertPos, From + FromBeg, CopySize);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric   return ToSize + CopySize;
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric 
Mutate_CopyPart(uint8_t * Data,size_t Size,size_t MaxSize)3560b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size,
3570b57cec5SDimitry Andric                                            size_t MaxSize) {
3580b57cec5SDimitry Andric   if (Size > MaxSize || Size == 0) return 0;
3590b57cec5SDimitry Andric   // If Size == MaxSize, `InsertPartOf(...)` will
3600b57cec5SDimitry Andric   // fail so there's no point using it in this case.
3610b57cec5SDimitry Andric   if (Size == MaxSize || Rand.RandBool())
3620b57cec5SDimitry Andric     return CopyPartOf(Data, Size, Data, Size);
3630b57cec5SDimitry Andric   else
3640b57cec5SDimitry Andric     return InsertPartOf(Data, Size, Data, Size, MaxSize);
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric 
Mutate_ChangeASCIIInteger(uint8_t * Data,size_t Size,size_t MaxSize)3670b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
3680b57cec5SDimitry Andric                                                      size_t MaxSize) {
3690b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
3700b57cec5SDimitry Andric   size_t B = Rand(Size);
3710b57cec5SDimitry Andric   while (B < Size && !isdigit(Data[B])) B++;
3720b57cec5SDimitry Andric   if (B == Size) return 0;
3730b57cec5SDimitry Andric   size_t E = B;
3740b57cec5SDimitry Andric   while (E < Size && isdigit(Data[E])) E++;
3750b57cec5SDimitry Andric   assert(B < E);
3760b57cec5SDimitry Andric   // now we have digits in [B, E).
3770b57cec5SDimitry Andric   // strtol and friends don't accept non-zero-teminated data, parse it manually.
3780b57cec5SDimitry Andric   uint64_t Val = Data[B] - '0';
3790b57cec5SDimitry Andric   for (size_t i = B + 1; i < E; i++)
3800b57cec5SDimitry Andric     Val = Val * 10 + Data[i] - '0';
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric   // Mutate the integer value.
3830b57cec5SDimitry Andric   switch(Rand(5)) {
3840b57cec5SDimitry Andric     case 0: Val++; break;
3850b57cec5SDimitry Andric     case 1: Val--; break;
3860b57cec5SDimitry Andric     case 2: Val /= 2; break;
3870b57cec5SDimitry Andric     case 3: Val *= 2; break;
3880b57cec5SDimitry Andric     case 4: Val = Rand(Val * Val); break;
3890b57cec5SDimitry Andric     default: assert(0);
3900b57cec5SDimitry Andric   }
3910b57cec5SDimitry Andric   // Just replace the bytes with the new ones, don't bother moving bytes.
3920b57cec5SDimitry Andric   for (size_t i = B; i < E; i++) {
3930b57cec5SDimitry Andric     size_t Idx = E + B - i - 1;
3940b57cec5SDimitry Andric     assert(Idx >= B && Idx < E);
3950b57cec5SDimitry Andric     Data[Idx] = (Val % 10) + '0';
3960b57cec5SDimitry Andric     Val /= 10;
3970b57cec5SDimitry Andric   }
3980b57cec5SDimitry Andric   return Size;
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric template<class T>
ChangeBinaryInteger(uint8_t * Data,size_t Size,Random & Rand)4020b57cec5SDimitry Andric size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
4030b57cec5SDimitry Andric   if (Size < sizeof(T)) return 0;
4040b57cec5SDimitry Andric   size_t Off = Rand(Size - sizeof(T) + 1);
4050b57cec5SDimitry Andric   assert(Off + sizeof(T) <= Size);
4060b57cec5SDimitry Andric   T Val;
4070b57cec5SDimitry Andric   if (Off < 64 && !Rand(4)) {
408fe6060f1SDimitry Andric     Val = static_cast<T>(Size);
4090b57cec5SDimitry Andric     if (Rand.RandBool())
4100b57cec5SDimitry Andric       Val = Bswap(Val);
4110b57cec5SDimitry Andric   } else {
4120b57cec5SDimitry Andric     memcpy(&Val, Data + Off, sizeof(Val));
413fe6060f1SDimitry Andric     T Add = static_cast<T>(Rand(21));
4140b57cec5SDimitry Andric     Add -= 10;
4150b57cec5SDimitry Andric     if (Rand.RandBool())
4160b57cec5SDimitry Andric       Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
4170b57cec5SDimitry Andric     else
4180b57cec5SDimitry Andric       Val = Val + Add;               // Add assuming current endiannes.
4190b57cec5SDimitry Andric     if (Add == 0 || Rand.RandBool()) // Maybe negate.
4200b57cec5SDimitry Andric       Val = -Val;
4210b57cec5SDimitry Andric   }
4220b57cec5SDimitry Andric   memcpy(Data + Off, &Val, sizeof(Val));
4230b57cec5SDimitry Andric   return Size;
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric 
Mutate_ChangeBinaryInteger(uint8_t * Data,size_t Size,size_t MaxSize)4260b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data,
4270b57cec5SDimitry Andric                                                       size_t Size,
4280b57cec5SDimitry Andric                                                       size_t MaxSize) {
4290b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
4300b57cec5SDimitry Andric   switch (Rand(4)) {
4310b57cec5SDimitry Andric     case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);
4320b57cec5SDimitry Andric     case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);
4330b57cec5SDimitry Andric     case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);
4340b57cec5SDimitry Andric     case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);
4350b57cec5SDimitry Andric     default: assert(0);
4360b57cec5SDimitry Andric   }
4370b57cec5SDimitry Andric   return 0;
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
Mutate_CrossOver(uint8_t * Data,size_t Size,size_t MaxSize)4400b57cec5SDimitry Andric size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
4410b57cec5SDimitry Andric                                             size_t MaxSize) {
4420b57cec5SDimitry Andric   if (Size > MaxSize) return 0;
4430b57cec5SDimitry Andric   if (Size == 0) return 0;
4440b57cec5SDimitry Andric   if (!CrossOverWith) return 0;
4450b57cec5SDimitry Andric   const Unit &O = *CrossOverWith;
4460b57cec5SDimitry Andric   if (O.empty()) return 0;
4470b57cec5SDimitry Andric   size_t NewSize = 0;
4480b57cec5SDimitry Andric   switch(Rand(3)) {
4490b57cec5SDimitry Andric     case 0:
450e8d8bef9SDimitry Andric       MutateInPlaceHere.resize(MaxSize);
451e8d8bef9SDimitry Andric       NewSize = CrossOver(Data, Size, O.data(), O.size(),
452e8d8bef9SDimitry Andric                           MutateInPlaceHere.data(), MaxSize);
453e8d8bef9SDimitry Andric       memcpy(Data, MutateInPlaceHere.data(), NewSize);
4540b57cec5SDimitry Andric       break;
4550b57cec5SDimitry Andric     case 1:
456e8d8bef9SDimitry Andric       NewSize = InsertPartOf(O.data(), O.size(), Data, Size, MaxSize);
4570b57cec5SDimitry Andric       if (!NewSize)
458e8d8bef9SDimitry Andric         NewSize = CopyPartOf(O.data(), O.size(), Data, Size);
4590b57cec5SDimitry Andric       break;
4600b57cec5SDimitry Andric     case 2:
461e8d8bef9SDimitry Andric       NewSize = CopyPartOf(O.data(), O.size(), Data, Size);
4620b57cec5SDimitry Andric       break;
4630b57cec5SDimitry Andric     default: assert(0);
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric   assert(NewSize > 0 && "CrossOver returned empty unit");
4660b57cec5SDimitry Andric   assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
4670b57cec5SDimitry Andric   return NewSize;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
StartMutationSequence()4700b57cec5SDimitry Andric void MutationDispatcher::StartMutationSequence() {
4710b57cec5SDimitry Andric   CurrentMutatorSequence.clear();
4720b57cec5SDimitry Andric   CurrentDictionaryEntrySequence.clear();
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric // Copy successful dictionary entries to PersistentAutoDictionary.
RecordSuccessfulMutationSequence()4760b57cec5SDimitry Andric void MutationDispatcher::RecordSuccessfulMutationSequence() {
4770b57cec5SDimitry Andric   for (auto DE : CurrentDictionaryEntrySequence) {
4780b57cec5SDimitry Andric     // PersistentAutoDictionary.AddWithSuccessCountOne(DE);
4790b57cec5SDimitry Andric     DE->IncSuccessCount();
4800b57cec5SDimitry Andric     assert(DE->GetW().size());
4810b57cec5SDimitry Andric     // Linear search is fine here as this happens seldom.
4820b57cec5SDimitry Andric     if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
483fe6060f1SDimitry Andric       PersistentAutoDictionary.push_back(*DE);
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric 
PrintRecommendedDictionary()4870b57cec5SDimitry Andric void MutationDispatcher::PrintRecommendedDictionary() {
488349cc55cSDimitry Andric   std::vector<DictionaryEntry> V;
4890b57cec5SDimitry Andric   for (auto &DE : PersistentAutoDictionary)
4900b57cec5SDimitry Andric     if (!ManualDictionary.ContainsWord(DE.GetW()))
4910b57cec5SDimitry Andric       V.push_back(DE);
4920b57cec5SDimitry Andric   if (V.empty()) return;
4930b57cec5SDimitry Andric   Printf("###### Recommended dictionary. ######\n");
4940b57cec5SDimitry Andric   for (auto &DE: V) {
4950b57cec5SDimitry Andric     assert(DE.GetW().size());
4960b57cec5SDimitry Andric     Printf("\"");
4970b57cec5SDimitry Andric     PrintASCII(DE.GetW(), "\"");
4980b57cec5SDimitry Andric     Printf(" # Uses: %zd\n", DE.GetUseCount());
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric   Printf("###### End of recommended dictionary. ######\n");
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
PrintMutationSequence(bool Verbose)503e8d8bef9SDimitry Andric void MutationDispatcher::PrintMutationSequence(bool Verbose) {
5040b57cec5SDimitry Andric   Printf("MS: %zd ", CurrentMutatorSequence.size());
505e8d8bef9SDimitry Andric   size_t EntriesToPrint =
506e8d8bef9SDimitry Andric       Verbose ? CurrentMutatorSequence.size()
507e8d8bef9SDimitry Andric               : std::min(kMaxMutationsToPrint, CurrentMutatorSequence.size());
508e8d8bef9SDimitry Andric   for (size_t i = 0; i < EntriesToPrint; i++)
509e8d8bef9SDimitry Andric     Printf("%s-", CurrentMutatorSequence[i].Name);
5100b57cec5SDimitry Andric   if (!CurrentDictionaryEntrySequence.empty()) {
5110b57cec5SDimitry Andric     Printf(" DE: ");
512e8d8bef9SDimitry Andric     EntriesToPrint = Verbose ? CurrentDictionaryEntrySequence.size()
513e8d8bef9SDimitry Andric                              : std::min(kMaxMutationsToPrint,
514e8d8bef9SDimitry Andric                                         CurrentDictionaryEntrySequence.size());
515e8d8bef9SDimitry Andric     for (size_t i = 0; i < EntriesToPrint; i++) {
5160b57cec5SDimitry Andric       Printf("\"");
517e8d8bef9SDimitry Andric       PrintASCII(CurrentDictionaryEntrySequence[i]->GetW(), "\"-");
5180b57cec5SDimitry Andric     }
5190b57cec5SDimitry Andric   }
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
MutationSequence()522e8d8bef9SDimitry Andric std::string MutationDispatcher::MutationSequence() {
523e8d8bef9SDimitry Andric   std::string MS;
524*06c3fb27SDimitry Andric   for (const auto &M : CurrentMutatorSequence) {
525e8d8bef9SDimitry Andric     MS += M.Name;
526e8d8bef9SDimitry Andric     MS += "-";
527e8d8bef9SDimitry Andric   }
528e8d8bef9SDimitry Andric   return MS;
529e8d8bef9SDimitry Andric }
530e8d8bef9SDimitry Andric 
Mutate(uint8_t * Data,size_t Size,size_t MaxSize)5310b57cec5SDimitry Andric size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
5320b57cec5SDimitry Andric   return MutateImpl(Data, Size, MaxSize, Mutators);
5330b57cec5SDimitry Andric }
5340b57cec5SDimitry Andric 
DefaultMutate(uint8_t * Data,size_t Size,size_t MaxSize)5350b57cec5SDimitry Andric size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
5360b57cec5SDimitry Andric                                          size_t MaxSize) {
5370b57cec5SDimitry Andric   return MutateImpl(Data, Size, MaxSize, DefaultMutators);
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric // Mutates Data in place, returns new size.
MutateImpl(uint8_t * Data,size_t Size,size_t MaxSize,std::vector<Mutator> & Mutators)5410b57cec5SDimitry Andric size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
5420b57cec5SDimitry Andric                                       size_t MaxSize,
543349cc55cSDimitry Andric                                       std::vector<Mutator> &Mutators) {
5440b57cec5SDimitry Andric   assert(MaxSize > 0);
5450b57cec5SDimitry Andric   // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
5460b57cec5SDimitry Andric   // in which case they will return 0.
5470b57cec5SDimitry Andric   // Try several times before returning un-mutated data.
5480b57cec5SDimitry Andric   for (int Iter = 0; Iter < 100; Iter++) {
5490b57cec5SDimitry Andric     auto M = Mutators[Rand(Mutators.size())];
5500b57cec5SDimitry Andric     size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
5510b57cec5SDimitry Andric     if (NewSize && NewSize <= MaxSize) {
5520b57cec5SDimitry Andric       if (Options.OnlyASCII)
5530b57cec5SDimitry Andric         ToASCII(Data, NewSize);
5540b57cec5SDimitry Andric       CurrentMutatorSequence.push_back(M);
5550b57cec5SDimitry Andric       return NewSize;
5560b57cec5SDimitry Andric     }
5570b57cec5SDimitry Andric   }
5580b57cec5SDimitry Andric   *Data = ' ';
5590b57cec5SDimitry Andric   return 1;   // Fallback, should not happen frequently.
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric // Mask represents the set of Data bytes that are worth mutating.
MutateWithMask(uint8_t * Data,size_t Size,size_t MaxSize,const std::vector<uint8_t> & Mask)5630b57cec5SDimitry Andric size_t MutationDispatcher::MutateWithMask(uint8_t *Data, size_t Size,
5640b57cec5SDimitry Andric                                           size_t MaxSize,
565349cc55cSDimitry Andric                                           const std::vector<uint8_t> &Mask) {
5660b57cec5SDimitry Andric   size_t MaskedSize = std::min(Size, Mask.size());
5670b57cec5SDimitry Andric   // * Copy the worthy bytes into a temporary array T
5680b57cec5SDimitry Andric   // * Mutate T
5690b57cec5SDimitry Andric   // * Copy T back.
5700b57cec5SDimitry Andric   // This is totally unoptimized.
5710b57cec5SDimitry Andric   auto &T = MutateWithMaskTemp;
5720b57cec5SDimitry Andric   if (T.size() < Size)
5730b57cec5SDimitry Andric     T.resize(Size);
5740b57cec5SDimitry Andric   size_t OneBits = 0;
5750b57cec5SDimitry Andric   for (size_t I = 0; I < MaskedSize; I++)
5760b57cec5SDimitry Andric     if (Mask[I])
5770b57cec5SDimitry Andric       T[OneBits++] = Data[I];
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   if (!OneBits) return 0;
5800b57cec5SDimitry Andric   assert(!T.empty());
5810b57cec5SDimitry Andric   size_t NewSize = Mutate(T.data(), OneBits, OneBits);
5820b57cec5SDimitry Andric   assert(NewSize <= OneBits);
5830b57cec5SDimitry Andric   (void)NewSize;
5840b57cec5SDimitry Andric   // Even if NewSize < OneBits we still use all OneBits bytes.
5850b57cec5SDimitry Andric   for (size_t I = 0, J = 0; I < MaskedSize; I++)
5860b57cec5SDimitry Andric     if (Mask[I])
5870b57cec5SDimitry Andric       Data[I] = T[J++];
5880b57cec5SDimitry Andric   return Size;
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric 
AddWordToManualDictionary(const Word & W)5910b57cec5SDimitry Andric void MutationDispatcher::AddWordToManualDictionary(const Word &W) {
5920b57cec5SDimitry Andric   ManualDictionary.push_back(
5930b57cec5SDimitry Andric       {W, std::numeric_limits<size_t>::max()});
5940b57cec5SDimitry Andric }
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric }  // namespace fuzzer
597