aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Fuzzer/FuzzerMutate.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2015-09-04 00:40:29 +0000
committerKostya Serebryany <kcc@google.com>2015-09-04 00:40:29 +0000
commitb2e9897644383e7e535a3f4465706760b336ca49 (patch)
tree25637f26dccb8b55026ee4540b45a1383afa8be4 /llvm/lib/Fuzzer/FuzzerMutate.cpp
parent419d79189f56a4d819f7e958a7ea695efaef9875 (diff)
downloadllvm-b2e9897644383e7e535a3f4465706760b336ca49.zip
llvm-b2e9897644383e7e535a3f4465706760b336ca49.tar.gz
llvm-b2e9897644383e7e535a3f4465706760b336ca49.tar.bz2
[libFuzzer] when a single mutation fails try a few more times with other mutations before returning un-mutated data
llvm-svn: 246828
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerMutate.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerMutate.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp
index 70fa88d..9b2015b 100644
--- a/llvm/lib/Fuzzer/FuzzerMutate.cpp
+++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp
@@ -71,7 +71,7 @@ size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
size_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
size_t MaxSize) {
assert(Size);
- if (Size == 1) return Size;
+ if (Size == 1) return 0;
size_t Idx = Rand(Size);
// Erase Data[Idx].
memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
@@ -80,7 +80,7 @@ size_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
size_t MaxSize) {
- if (Size == MaxSize) return Size;
+ if (Size == MaxSize) return 0;
size_t Idx = Rand(Size + 1);
// Insert new value at Data[Idx].
memmove(Data + Idx + 1, Data + Idx, Size - Idx);
@@ -106,9 +106,10 @@ size_t MutationDispatcher::Mutate_AddWordFromDictionary(uint8_t *Data,
size_t Size,
size_t MaxSize) {
auto &D = MDImpl->Dictionary;
- if (D.empty()) return Size; // FIXME: indicate failure.
+ assert(!D.empty());
+ if (D.empty()) return 0;
const Unit &Word = D[Rand(D.size())];
- if (Size + Word.size() > MaxSize) return Size;
+ if (Size + Word.size() > MaxSize) return 0;
size_t Idx = Rand(Size + 1);
memmove(Data + Idx + Word.size(), Data + Idx, Size - Idx);
memcpy(Data + Idx, Word.data(), Word.size());
@@ -125,9 +126,15 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
return MaxSize;
}
assert(Size > 0);
- size_t MutatorIdx = Rand(MDImpl->Mutators.size());
- Size = (this->*(MDImpl->Mutators[MutatorIdx]))(Data, Size, MaxSize);
- assert(Size > 0);
+ // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize),
+ // in which case they will return 0.
+ // Try several times before returning un-mutated data.
+ for (int Iter = 0; Iter < 10; Iter++) {
+ size_t MutatorIdx = Rand(MDImpl->Mutators.size());
+ size_t NewSize =
+ (this->*(MDImpl->Mutators[MutatorIdx]))(Data, Size, MaxSize);
+ if (NewSize) return NewSize;
+ }
return Size;
}