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