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 "FuzzerInternal.h" 13 14 namespace fuzzer { 15 FlipRandomBit(char X)16static char FlipRandomBit(char X) { 17 int Bit = rand() % 8; 18 char Mask = 1 << Bit; 19 char R; 20 if (X & (1 << Bit)) 21 R = X & ~Mask; 22 else 23 R = X | Mask; 24 assert(R != X); 25 return R; 26 } 27 RandCh()28static char RandCh() { 29 if (rand() % 2) return rand(); 30 const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~."; 31 return Special[rand() % (sizeof(Special) - 1)]; 32 } 33 34 // Mutate U in place. Mutate(Unit * U,size_t MaxLen)35void Mutate(Unit *U, size_t MaxLen) { 36 assert(MaxLen > 0); 37 assert(U->size() <= MaxLen); 38 if (U->empty()) { 39 for (size_t i = 0; i < MaxLen; i++) 40 U->push_back(RandCh()); 41 return; 42 } 43 assert(!U->empty()); 44 switch (rand() % 3) { 45 case 0: 46 if (U->size() > 1) { 47 U->erase(U->begin() + rand() % U->size()); 48 break; 49 } 50 [[clang::fallthrough]]; 51 case 1: 52 if (U->size() < MaxLen) { 53 U->insert(U->begin() + rand() % U->size(), RandCh()); 54 } else { // At MaxLen. 55 uint8_t Ch = RandCh(); 56 size_t Idx = rand() % U->size(); 57 (*U)[Idx] = Ch; 58 } 59 break; 60 default: 61 { 62 size_t Idx = rand() % U->size(); 63 (*U)[Idx] = FlipRandomBit((*U)[Idx]); 64 } 65 break; 66 } 67 assert(!U->empty()); 68 } 69 70 } // namespace fuzzer 71