diff --git a/compiler-rt/lib/fuzzer/FuzzerMutate.cpp b/compiler-rt/lib/fuzzer/FuzzerMutate.cpp --- a/compiler-rt/lib/fuzzer/FuzzerMutate.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMutate.cpp @@ -425,26 +425,26 @@ if (!CrossOverWith) return 0; const Unit &O = *CrossOverWith; if (O.empty()) return 0; - MutateInPlaceHere.resize(MaxSize); - auto &U = MutateInPlaceHere; size_t NewSize = 0; switch(Rand(3)) { case 0: - NewSize = CrossOver(Data, Size, O.data(), O.size(), U.data(), U.size()); + MutateInPlaceHere.resize(MaxSize); + NewSize = CrossOver(Data, Size, O.data(), O.size(), + MutateInPlaceHere.data(), MaxSize); + memcpy(Data, MutateInPlaceHere.data(), NewSize); break; case 1: - NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize); + NewSize = InsertPartOf(O.data(), O.size(), Data, Size, MaxSize); if (!NewSize) - NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size()); + NewSize = CopyPartOf(O.data(), O.size(), Data, Size); break; case 2: - NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size()); + NewSize = CopyPartOf(O.data(), O.size(), Data, Size); break; default: assert(0); } assert(NewSize > 0 && "CrossOver returned empty unit"); assert(NewSize <= MaxSize && "CrossOver returned overisized unit"); - memcpy(Data, U.data(), NewSize); return NewSize; } diff --git a/compiler-rt/test/fuzzer/CrossOverTest.cpp b/compiler-rt/test/fuzzer/CrossOverTest.cpp --- a/compiler-rt/test/fuzzer/CrossOverTest.cpp +++ b/compiler-rt/test/fuzzer/CrossOverTest.cpp @@ -4,10 +4,11 @@ // Test for a fuzzer. The fuzzer must find the string // ABCDEFGHIJ -// We use it as a test for CrossOver functionality -// by passing two inputs to it: -// ABCDE00000 -// ZZZZZFGHIJ +// We use it as a test for each of CrossOver functionalities +// by passing the following sets of two inputs to it: +// {ABCDE00000, ZZZZZFGHIJ} +// {ABCDEHIJ, ZFG} to specifically test InsertPartOf +// {ABCDE00HIJ, ZFG} to specifically test CopyPartOf // #include #include @@ -42,13 +43,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { // fprintf(stderr, "ExpectedHash: %x\n", ExpectedHash); - if (Size != 10) return 0; + if (Size == 10 && ExpectedHash == simple_hash(Data, Size)) + *NullPtr = 0; if (*Data == 'A') Sink++; if (*Data == 'Z') Sink--; - if (ExpectedHash == simple_hash(Data, Size)) - *NullPtr = 0; return 0; } - diff --git a/compiler-rt/test/fuzzer/cross_over.test b/compiler-rt/test/fuzzer/cross_over.test --- a/compiler-rt/test/fuzzer/cross_over.test +++ b/compiler-rt/test/fuzzer/cross_over.test @@ -12,7 +12,7 @@ RUN: echo -n ZZZZZFGHIJ > %t-corpus/B -RUN: not %run %t-CrossOverTest -max_len=10 -seed=1 -runs=10000000 %t-corpus +RUN: not %run %t-CrossOverTest -max_len=10 -reduce_inputs=0 -seed=1 -runs=10000000 %t-corpus # Test the same thing but using -seed_inputs instead of passing the corpus dir. -RUN: not %run %t-CrossOverTest -max_len=10 -seed=1 -runs=10000000 -seed_inputs=%t-corpus/A,%t-corpus/B +RUN: not %run %t-CrossOverTest -max_len=10 -reduce_inputs=0 -seed=1 -runs=10000000 -seed_inputs=%t-corpus/A,%t-corpus/B diff --git a/compiler-rt/test/fuzzer/cross_over_copy.test b/compiler-rt/test/fuzzer/cross_over_copy.test new file mode 100644 --- /dev/null +++ b/compiler-rt/test/fuzzer/cross_over_copy.test @@ -0,0 +1,20 @@ +# Tests CrossOver CopyPartOf. +# We want to make sure that the test can find the input +# ABCDEFGHIJ when given two other inputs in the seed corpus: +# ABCDE00HIJ and +# (Z) FG +# +RUN: %cpp_compiler %S/CrossOverTest.cpp -o %t-CrossOverTest + +RUN: rm -rf %t-corpus +RUN: mkdir %t-corpus +RUN: echo -n ABCDE00HIJ > %t-corpus/A +RUN: echo -n ZFG > %t-corpus/B + + +RUN: not %run %t-CrossOverTest -mutate_depth=1 -max_len=1024 -reduce_inputs=0 -seed=1 -runs=10000000 %t-corpus 2>&1 | FileCheck %s + +# Test the same thing but using -seed_inputs instead of passing the corpus dir. +RUN: not %run %t-CrossOverTest -mutate_depth=1 -max_len=1024 -reduce_inputs=0 -seed=1 -runs=10000000 -seed_inputs=%t-corpus/A,%t-corpus/B 2>&1 | FileCheck %s + +CHECK: MS: 1 CrossOver- diff --git a/compiler-rt/test/fuzzer/cross_over_insert.test b/compiler-rt/test/fuzzer/cross_over_insert.test new file mode 100644 --- /dev/null +++ b/compiler-rt/test/fuzzer/cross_over_insert.test @@ -0,0 +1,20 @@ +# Tests CrossOver InsertPartOf. +# We want to make sure that the test can find the input +# ABCDEFGHIJ when given two other inputs in the seed corpus: +# ABCDE HIJ and +# (Z) FG +# +RUN: %cpp_compiler %S/CrossOverTest.cpp -o %t-CrossOverTest + +RUN: rm -rf %t-corpus +RUN: mkdir %t-corpus +RUN: echo -n ABCDEHIJ > %t-corpus/A +RUN: echo -n ZFG > %t-corpus/B + + +RUN: not %run %t-CrossOverTest -mutate_depth=1 -max_len=1024 -reduce_inputs=0 -seed=1 -runs=10000000 %t-corpus 2>&1 | FileCheck %s + +# Test the same thing but using -seed_inputs instead of passing the corpus dir. +RUN: not %run %t-CrossOverTest -mutate_depth=1 -max_len=1024 -reduce_inputs=0 -seed=1 -runs=10000000 -seed_inputs=%t-corpus/A,%t-corpus/B 2>&1 | FileCheck %s + +CHECK: MS: 1 CrossOver-