1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                     The LLVM Compiler Infrastructure
4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file is distributed under the University of Illinois Open Source
6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// License. See LICENSE.TXT for details.
7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//
8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Mutate a test input.
10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include <cstring>
136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "FuzzerInternal.h"
15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
16cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include <algorithm>
17cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace fuzzer {
19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
20cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstruct Mutator {
21cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
22cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const char *Name;
23cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar};
24cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
25cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstruct MutationDispatcher::Impl {
26cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::vector<Unit> Dictionary;
27cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::vector<Mutator> Mutators;
28cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::vector<Mutator> CurrentMutatorSequence;
29cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const std::vector<Unit> *Corpus = nullptr;
30cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
31cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void Add(Mutator M) { Mutators.push_back(M); }
32cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Impl() {
33cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"});
34cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"});
35cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"});
36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"});
37cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"});
38cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"});
39cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Add({&MutationDispatcher::Mutate_CrossOver, "CrossOver"});
40cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void AddWordToDictionary(const uint8_t *Word, size_t Size) {
42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (Dictionary.empty()) {
43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Add({&MutationDispatcher::Mutate_AddWordFromDictionary, "AddFromDict"});
44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
45cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Dictionary.push_back(Unit(Word, Word + Size));
46cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
47cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void SetCorpus(const std::vector<Unit> *Corpus) { this->Corpus = Corpus; }
48cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar};
49cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic char FlipRandomBit(char X, FuzzerRandomBase &Rand) {
51cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  int Bit = Rand(8);
52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  char Mask = 1 << Bit;
53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  char R;
54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (X & (1 << Bit))
55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    R = X & ~Mask;
56ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    R = X | Mask;
58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(R != X);
59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return R;
60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
62cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic char RandCh(FuzzerRandomBase &Rand) {
63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Rand.RandBool()) return Rand(256);
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~.";
65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Special[Rand(sizeof(Special) - 1)];
66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                               size_t MaxSize) {
70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(Size);
71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t ShuffleAmount = Rand(std::min(Size, (size_t)8)) + 1;  // [1,8] and <= Size.
72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t ShuffleStart = Rand(Size - ShuffleAmount);
73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(ShuffleStart + ShuffleAmount <= Size);
74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount,
75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                      Rand);
76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size;
77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                            size_t MaxSize) {
81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(Size);
82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Size == 1) return 0;
83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Size);
84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Erase Data[Idx].
85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size - 1;
87cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
88cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
89cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
90cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                             size_t MaxSize) {
91cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Size == MaxSize) return 0;
92cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Size + 1);
93cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Insert new value at Data[Idx].
94cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  memmove(Data + Idx + 1, Data + Idx, Size - Idx);
95cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Data[Idx] = RandCh(Rand);
96cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size + 1;
97cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
98cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
100cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                             size_t MaxSize) {
101cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Size);
102cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Data[Idx] = RandCh(Rand);
103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size;
104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
106cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
107cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                            size_t MaxSize) {
108cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Size);
109cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Data[Idx] = FlipRandomBit(Data[Idx], Rand);
110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size;
111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
113cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_AddWordFromDictionary(uint8_t *Data,
114cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                                        size_t Size,
115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                                        size_t MaxSize) {
116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto &D = MDImpl->Dictionary;
117cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(!D.empty());
118cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (D.empty()) return 0;
119cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const Unit &Word = D[Rand(D.size())];
120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Size + Word.size() > MaxSize) return 0;
121cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Size + 1);
122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  memmove(Data + Idx + Word.size(), Data + Idx, Size - Idx);
123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  memcpy(Data + Idx, Word.data(), Word.size());
124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size + Word.size();
125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
126cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                                     size_t MaxSize) {
129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t B = Rand(Size);
130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  while (B < Size && !isdigit(Data[B])) B++;
131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (B == Size) return 0;
132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t E = B;
133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  while (E < Size && isdigit(Data[E])) E++;
134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(B < E);
135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // now we have digits in [B, E).
136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // strtol and friends don't accept non-zero-teminated data, parse it manually.
137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  uint64_t Val = Data[B] - '0';
138cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (size_t i = B + 1; i < E; i++)
139cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Val = Val * 10 + Data[i] - '0';
140cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Mutate the integer value.
142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  switch(Rand(5)) {
143cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    case 0: Val++; break;
144cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    case 1: Val--; break;
145cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    case 2: Val /= 2; break;
146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    case 3: Val *= 2; break;
147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    case 4: Val = Rand(Val * Val); break;
148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    default: assert(0);
149cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Just replace the bytes with the new ones, don't bother moving bytes.
151cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (size_t i = B; i < E; i++) {
152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    size_t Idx = E + B - i - 1;
153cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(Idx >= B && Idx < E);
154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Data[Idx] = (Val % 10) + '0';
155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Val /= 10;
156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
157cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Size;
158cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
159cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
160cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
161cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                            size_t MaxSize) {
162cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto Corpus = MDImpl->Corpus;
163cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
164cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t Idx = Rand(Corpus->size());
165cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const Unit &Other = (*Corpus)[Idx];
166cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Other.empty()) return 0;
167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Unit U(MaxSize);
168cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  size_t NewSize =
169cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      CrossOver(Data, Size, Other.data(), Other.size(), U.data(), U.size());
170cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(NewSize > 0 && "CrossOver returned empty unit");
171cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
172cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  memcpy(Data, U.data(), NewSize);
173cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return NewSize;
174cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
175cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
176cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid MutationDispatcher::StartMutationSequence() {
177cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MDImpl->CurrentMutatorSequence.clear();
178cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
179cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
180cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid MutationDispatcher::PrintMutationSequence() {
181cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size());
182cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (auto M : MDImpl->CurrentMutatorSequence)
183cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Printf("%s-", M.Name);
184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
185ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Mutates Data in place, returns new size.
187cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarsize_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
1886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(MaxSize > 0);
1896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(Size <= MaxSize);
1906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Size == 0) {
1916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    for (size_t i = 0; i < MaxSize; i++)
192cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Data[i] = RandCh(Rand);
1936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return MaxSize;
194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(Size > 0);
196cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
197cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // in which case they will return 0.
198cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Try several times before returning un-mutated data.
199cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (int Iter = 0; Iter < 10; Iter++) {
200cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    size_t MutatorIdx = Rand(MDImpl->Mutators.size());
201cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto M = MDImpl->Mutators[MutatorIdx];
202cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
203cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (NewSize) {
204cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      MDImpl->CurrentMutatorSequence.push_back(M);
205cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return NewSize;
206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
2086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return Size;
209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid MutationDispatcher::SetCorpus(const std::vector<Unit> *Corpus) {
212cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MDImpl->SetCorpus(Corpus);
213cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
214cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
215cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarvoid MutationDispatcher::AddWordToDictionary(const uint8_t *Word, size_t Size) {
216cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MDImpl->AddWordToDictionary(Word, Size);
217cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
218cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
219cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarMutationDispatcher::MutationDispatcher(FuzzerRandomBase &Rand) : Rand(Rand) {
220cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MDImpl = new Impl;
221cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
222cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
223cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarMutationDispatcher::~MutationDispatcher() { delete MDImpl; }
224cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}  // namespace fuzzer
226