diff options
author | Kostya Serebryany <kcc@google.com> | 2015-09-04 00:40:29 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2015-09-04 00:40:29 +0000 |
commit | b2e9897644383e7e535a3f4465706760b336ca49 (patch) | |
tree | 25637f26dccb8b55026ee4540b45a1383afa8be4 /llvm/lib/Fuzzer/FuzzerMutate.cpp | |
parent | 419d79189f56a4d819f7e958a7ea695efaef9875 (diff) | |
download | llvm-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.cpp | 21 |
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; } |