diff options
author | Dan Liew <dan@su-root.co.uk> | 2018-04-24 06:31:09 +0000 |
---|---|---|
committer | Dan Liew <dan@su-root.co.uk> | 2018-04-24 06:31:09 +0000 |
commit | a97c9c4c7b68718987d90c9e483be0afa65bea1f (patch) | |
tree | 1d2fe2d69a3fa897b760272f645aa822ee60e88b /lib/fuzzer | |
parent | 751fac1ff7dbff433b91becefe86c7b37b825607 (diff) |
[LibFuzzer] Tweak `MutationDispatcher::Mutate_CopyPart` mutation.
It doesn't make sense to non-deterministically choose between
`CopyPart(..)` and `InsertPart(..)` when it is known that
`InsertPart(..)` will fail.
This upstream's a change from JFS solver's fork of LibFuzzer.
Differential Revision: https://reviews.llvm.org/D45693
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@330687 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/fuzzer')
-rw-r--r-- | lib/fuzzer/FuzzerMutate.cpp | 4 | ||||
-rw-r--r-- | lib/fuzzer/tests/FuzzerUnittest.cpp | 15 |
2 files changed, 18 insertions, 1 deletions
diff --git a/lib/fuzzer/FuzzerMutate.cpp b/lib/fuzzer/FuzzerMutate.cpp index e0e457852..865e598fd 100644 --- a/lib/fuzzer/FuzzerMutate.cpp +++ b/lib/fuzzer/FuzzerMutate.cpp @@ -339,7 +339,9 @@ size_t MutationDispatcher::InsertPartOf(const uint8_t *From, size_t FromSize, size_t MutationDispatcher::Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize) { if (Size > MaxSize || Size == 0) return 0; - if (Rand.RandBool()) + // If Size == MaxSize, `InsertPartOf(...)` will + // fail so there's no point using it in this case. + if (Size == MaxSize || Rand.RandBool()) return CopyPartOf(Data, Size, Data, Size); else return InsertPartOf(Data, Size, Data, Size, MaxSize); diff --git a/lib/fuzzer/tests/FuzzerUnittest.cpp b/lib/fuzzer/tests/FuzzerUnittest.cpp index 3f57a5d60..c795eddc6 100644 --- a/lib/fuzzer/tests/FuzzerUnittest.cpp +++ b/lib/fuzzer/tests/FuzzerUnittest.cpp @@ -381,6 +381,21 @@ TEST(FuzzerMutate, CopyPart1) { TEST(FuzzerMutate, CopyPart2) { TestCopyPart(&MutationDispatcher::Mutate, 1 << 13); } +TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) { + // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an + // insert on an input of size `MaxSize`. Performing an insert in this case + // will lead to the mutation failing. + std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); + fuzzer::EF = t.get(); + Random Rand(0); + std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); + uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22}; + size_t MaxSize = sizeof(Data); + for (int count = 0; count < (1 << 18); ++count) { + size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize); + ASSERT_EQ(NewSize, MaxSize); + } +} void TestAddWordFromDictionary(Mutator M, int NumIter) { std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); |