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