xref: /llvm-project/compiler-rt/test/fuzzer/CustomCrossOverTest.cpp (revision a1e7e401d2af002af26e1512a31e09eb2d0cf1dc)
1 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2 // See https://llvm.org/LICENSE.txt for license information.
3 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4 
5 // Simple test for a custom crossover.
6 #include <assert.h>
7 #include <cstddef>
8 #include <cstdint>
9 #include <cstdlib>
10 #include <iostream>
11 #include <ostream>
12 #include <random>
13 #include <string.h>
14 #include <functional>
15 
16 static const char *Separator = "-########-";
17 static const char *Target = "A-########-B";
18 
19 static volatile int sink;
20 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)21 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
22   assert(Data);
23   std::string Str(reinterpret_cast<const char *>(Data), Size);
24   static const size_t TargetHash = std::hash<std::string>{}(std::string(Target));
25   size_t StrHash = std::hash<std::string>{}(Str);
26 
27   // Ensure we have 'A' and 'B' in the corpus.
28   if (Size == 1 && *Data == 'A')
29     sink++;
30   if (Size == 1 && *Data == 'B')
31     sink--;
32 
33   if (TargetHash == StrHash) {
34     std::cout << "BINGO; Found the target, exiting\n" << std::flush;
35     exit(1);
36   }
37   return 0;
38 }
39 
LLVMFuzzerCustomCrossOver(const uint8_t * Data1,size_t Size1,const uint8_t * Data2,size_t Size2,uint8_t * Out,size_t MaxOutSize,unsigned int Seed)40 extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
41                                             const uint8_t *Data2, size_t Size2,
42                                             uint8_t *Out, size_t MaxOutSize,
43                                             unsigned int Seed) {
44   static size_t Printed;
45   static size_t SeparatorLen = strlen(Separator);
46 
47   if (Printed++ < 32)
48     std::cerr << "In LLVMFuzzerCustomCrossover " << Size1 << " " << Size2 << "\n";
49 
50   size_t Size = Size1 + Size2 + SeparatorLen;
51 
52   if (Size > MaxOutSize)
53     return 0;
54 
55   memcpy(Out, Data1, Size1);
56   memcpy(Out + Size1, Separator, SeparatorLen);
57   memcpy(Out + Size1 + SeparatorLen, Data2, Size2);
58 
59   return Size;
60 }
61