1 //===- FuzzerMutate.cpp - Mutate a test input -----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 // Mutate a test input.
10 //===----------------------------------------------------------------------===//
14 #include "FuzzerInternal.h"
20 static char FlipRandomBit(char X, FuzzerRandomBase &Rand) {
32 static char RandCh(FuzzerRandomBase &Rand) {
33 if (Rand.RandBool()) return Rand(256);
34 const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~.";
35 return Special[Rand(sizeof(Special) - 1)];
38 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
41 size_t ShuffleAmount = Rand(std::min(Size, 8UL)) + 1; // [1,8] and <= Size.
42 size_t ShuffleStart = Rand(Size - ShuffleAmount);
43 assert(ShuffleStart + ShuffleAmount <= Size);
44 std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount,
49 size_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
52 if (Size == 1) return Size;
53 size_t Idx = Rand(Size);
55 memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
59 size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
61 if (Size == MaxSize) return Size;
62 size_t Idx = Rand(Size + 1);
63 // Insert new value at Data[Idx].
64 memmove(Data + Idx + 1, Data + Idx, Size - Idx);
65 Data[Idx] = RandCh(Rand);
69 size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
71 size_t Idx = Rand(Size);
72 Data[Idx] = RandCh(Rand);
76 size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
78 size_t Idx = Rand(Size);
79 Data[Idx] = FlipRandomBit(Data[Idx], Rand);
83 // Mutates Data in place, returns new size.
84 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
86 assert(Size <= MaxSize);
88 for (size_t i = 0; i < MaxSize; i++)
89 Data[i] = RandCh(Rand);
94 case 0: Size = Mutate_EraseByte(Data, Size, MaxSize); break;
95 case 1: Size = Mutate_InsertByte(Data, Size, MaxSize); break;
96 case 2: Size = Mutate_ChangeByte(Data, Size, MaxSize); break;
97 case 3: Size = Mutate_ChangeBit(Data, Size, MaxSize); break;
98 case 4: Size = Mutate_ShuffleBytes(Data, Size, MaxSize); break;
104 } // namespace fuzzer