diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
commit | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch) | |
tree | a6140557876943cdd800ee997c9317283394b22c /lib/Fuzzer/FuzzerMutate.cpp | |
parent | f03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff) |
Diffstat (limited to 'lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r-- | lib/Fuzzer/FuzzerMutate.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp new file mode 100644 index 0000000000000..f537fa90fd850 --- /dev/null +++ b/lib/Fuzzer/FuzzerMutate.cpp @@ -0,0 +1,71 @@ +//===- FuzzerMutate.cpp - Mutate a test input -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Mutate a test input. +//===----------------------------------------------------------------------===// + +#include <cstring> + +#include "FuzzerInternal.h" + +namespace fuzzer { + +static char FlipRandomBit(char X) { + int Bit = rand() % 8; + char Mask = 1 << Bit; + char R; + if (X & (1 << Bit)) + R = X & ~Mask; + else + R = X | Mask; + assert(R != X); + return R; +} + +static char RandCh() { + if (rand() % 2) return rand(); + const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~."; + return Special[rand() % (sizeof(Special) - 1)]; +} + +// Mutates Data in place, returns new size. +size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { + assert(MaxSize > 0); + assert(Size <= MaxSize); + if (Size == 0) { + for (size_t i = 0; i < MaxSize; i++) + Data[i] = RandCh(); + return MaxSize; + } + assert(Size > 0); + size_t Idx = rand() % Size; + switch (rand() % 3) { + case 0: + if (Size > 1) { + // Erase Data[Idx]. + memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1); + Size = Size - 1; + } + [[clang::fallthrough]]; + case 1: + if (Size < MaxSize) { + // Insert new value at Data[Idx]. + memmove(Data + Idx + 1, Data + Idx, Size - Idx); + Data[Idx] = RandCh(); + } + Data[Idx] = RandCh(); + break; + case 2: + Data[Idx] = FlipRandomBit(Data[Idx]); + break; + } + assert(Size > 0); + return Size; +} + +} // namespace fuzzer |