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