xref: /llvm-project/compiler-rt/lib/fuzzer/tests/FuzzerUnittest.cpp (revision 5cda4dc7b4d28fcd11307d4234c513ff779a1c6f)
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 // Avoid ODR violations (LibFuzzer is built without ASan and this test is built
6 // with ASan) involving C++ standard library types when using libcxx.
7 #define _LIBCPP_HAS_NO_ASAN
8 
9 // Do not attempt to use LLVM ostream etc from gtest.
10 #define GTEST_NO_LLVM_SUPPORT 1
11 
12 #include "FuzzerCorpus.h"
13 #include "FuzzerDictionary.h"
14 #include "FuzzerInternal.h"
15 #include "FuzzerMerge.h"
16 #include "FuzzerMutate.h"
17 #include "FuzzerRandom.h"
18 #include "FuzzerTracePC.h"
19 #include "gtest/gtest.h"
20 #include <memory>
21 #include <set>
22 #include <sstream>
23 
24 using namespace fuzzer;
25 
26 // For now, have LLVMFuzzerTestOneInput just to make it link.
27 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
28 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
29   abort();
30 }
31 
32 TEST(Fuzzer, Basename) {
33   EXPECT_EQ(Basename("foo/bar"), "bar");
34   EXPECT_EQ(Basename("bar"), "bar");
35   EXPECT_EQ(Basename("/bar"), "bar");
36   EXPECT_EQ(Basename("foo/x"), "x");
37   EXPECT_EQ(Basename("foo/"), "");
38 #if LIBFUZZER_WINDOWS
39   EXPECT_EQ(Basename("foo\\bar"), "bar");
40   EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
41   EXPECT_EQ(Basename("\\bar"), "bar");
42   EXPECT_EQ(Basename("foo\\x"), "x");
43   EXPECT_EQ(Basename("foo\\"), "");
44 #endif
45 }
46 
47 TEST(Fuzzer, CrossOver) {
48   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
49   fuzzer::EF = t.get();
50   Random Rand(0);
51   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
52   Unit A({0, 1, 2}), B({5, 6, 7});
53   Unit C;
54   Unit Expected[] = {
55        { 0 },
56        { 0, 1 },
57        { 0, 5 },
58        { 0, 1, 2 },
59        { 0, 1, 5 },
60        { 0, 5, 1 },
61        { 0, 5, 6 },
62        { 0, 1, 2, 5 },
63        { 0, 1, 5, 2 },
64        { 0, 1, 5, 6 },
65        { 0, 5, 1, 2 },
66        { 0, 5, 1, 6 },
67        { 0, 5, 6, 1 },
68        { 0, 5, 6, 7 },
69        { 0, 1, 2, 5, 6 },
70        { 0, 1, 5, 2, 6 },
71        { 0, 1, 5, 6, 2 },
72        { 0, 1, 5, 6, 7 },
73        { 0, 5, 1, 2, 6 },
74        { 0, 5, 1, 6, 2 },
75        { 0, 5, 1, 6, 7 },
76        { 0, 5, 6, 1, 2 },
77        { 0, 5, 6, 1, 7 },
78        { 0, 5, 6, 7, 1 },
79        { 0, 1, 2, 5, 6, 7 },
80        { 0, 1, 5, 2, 6, 7 },
81        { 0, 1, 5, 6, 2, 7 },
82        { 0, 1, 5, 6, 7, 2 },
83        { 0, 5, 1, 2, 6, 7 },
84        { 0, 5, 1, 6, 2, 7 },
85        { 0, 5, 1, 6, 7, 2 },
86        { 0, 5, 6, 1, 2, 7 },
87        { 0, 5, 6, 1, 7, 2 },
88        { 0, 5, 6, 7, 1, 2 }
89   };
90   for (size_t Len = 1; Len < 8; Len++) {
91     Set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
92     for (int Iter = 0; Iter < 3000; Iter++) {
93       C.resize(Len);
94       size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
95                                      C.data(), C.size());
96       C.resize(NewSize);
97       FoundUnits.insert(C);
98     }
99     for (const Unit &U : Expected)
100       if (U.size() <= Len)
101         ExpectedUnitsWitThisLength.insert(U);
102     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
103   }
104 }
105 
106 TEST(Fuzzer, Hash) {
107   uint8_t A[] = {'a', 'b', 'c'};
108   fuzzer::Unit U(A, A + sizeof(A));
109   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
110   U.push_back('d');
111   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
112 }
113 
114 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
115                                               size_t MaxSize);
116 
117 void TestEraseBytes(Mutator M, int NumIter) {
118   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
119   fuzzer::EF = t.get();
120   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
121   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
122   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
123   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
124   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
125   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
126   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
127   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
128 
129   uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
130   uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
131   uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
132 
133   uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
134   uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
135   uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
136 
137 
138   Random Rand(0);
139   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
140   int FoundMask = 0;
141   for (int i = 0; i < NumIter; i++) {
142     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
143     size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
144     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
145     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
146     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
147     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
148     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
149     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
150     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
151     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
152 
153     if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
154     if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
155     if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
156 
157     if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
158     if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
159     if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
160   }
161   EXPECT_EQ(FoundMask, (1 << 14) - 1);
162 }
163 
164 TEST(FuzzerMutate, EraseBytes1) {
165   TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
166 }
167 TEST(FuzzerMutate, EraseBytes2) {
168   TestEraseBytes(&MutationDispatcher::Mutate, 2000);
169 }
170 
171 void TestInsertByte(Mutator M, int NumIter) {
172   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
173   fuzzer::EF = t.get();
174   Random Rand(0);
175   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
176   int FoundMask = 0;
177   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
178   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
179   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
180   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
181   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
182   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
183   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
184   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
185   for (int i = 0; i < NumIter; i++) {
186     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
187     size_t NewSize = (*MD.*M)(T, 7, 8);
188     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
189     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
190     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
191     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
192     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
193     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
194     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
195     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
196   }
197   EXPECT_EQ(FoundMask, 255);
198 }
199 
200 TEST(FuzzerMutate, InsertByte1) {
201   TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
202 }
203 TEST(FuzzerMutate, InsertByte2) {
204   TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
205 }
206 
207 void TestInsertRepeatedBytes(Mutator M, int NumIter) {
208   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
209   fuzzer::EF = t.get();
210   Random Rand(0);
211   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
212   int FoundMask = 0;
213   uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
214   uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
215   uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
216   uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
217   uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
218 
219   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
220   uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
221   uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
222   uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
223   uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
224 
225   for (int i = 0; i < NumIter; i++) {
226     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
227     size_t NewSize = (*MD.*M)(T, 4, 8);
228     if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
229     if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
230     if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
231     if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
232     if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
233 
234     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
235     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
236     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
237     if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
238     if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
239 
240   }
241   EXPECT_EQ(FoundMask, (1 << 10) - 1);
242 }
243 
244 TEST(FuzzerMutate, InsertRepeatedBytes1) {
245   TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
246 }
247 TEST(FuzzerMutate, InsertRepeatedBytes2) {
248   TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
249 }
250 
251 void TestChangeByte(Mutator M, int NumIter) {
252   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
253   fuzzer::EF = t.get();
254   Random Rand(0);
255   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
256   int FoundMask = 0;
257   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
258   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
259   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
260   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
261   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
262   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
263   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
264   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
265   for (int i = 0; i < NumIter; i++) {
266     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
267     size_t NewSize = (*MD.*M)(T, 8, 9);
268     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
269     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
270     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
271     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
272     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
273     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
274     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
275     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
276   }
277   EXPECT_EQ(FoundMask, 255);
278 }
279 
280 TEST(FuzzerMutate, ChangeByte1) {
281   TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
282 }
283 TEST(FuzzerMutate, ChangeByte2) {
284   TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
285 }
286 
287 void TestChangeBit(Mutator M, int NumIter) {
288   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
289   fuzzer::EF = t.get();
290   Random Rand(0);
291   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
292   int FoundMask = 0;
293   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
294   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
295   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
296   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
297   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
298   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
299   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
300   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
301   for (int i = 0; i < NumIter; i++) {
302     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
303     size_t NewSize = (*MD.*M)(T, 8, 9);
304     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
305     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
306     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
307     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
308     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
309     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
310     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
311     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
312   }
313   EXPECT_EQ(FoundMask, 255);
314 }
315 
316 TEST(FuzzerMutate, ChangeBit1) {
317   TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
318 }
319 TEST(FuzzerMutate, ChangeBit2) {
320   TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
321 }
322 
323 void TestShuffleBytes(Mutator M, int NumIter) {
324   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
325   fuzzer::EF = t.get();
326   Random Rand(0);
327   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
328   int FoundMask = 0;
329   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
330   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
331   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
332   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
333   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
334   for (int i = 0; i < NumIter; i++) {
335     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
336     size_t NewSize = (*MD.*M)(T, 7, 7);
337     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
338     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
339     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
340     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
341     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
342   }
343   EXPECT_EQ(FoundMask, 31);
344 }
345 
346 TEST(FuzzerMutate, ShuffleBytes1) {
347   TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
348 }
349 TEST(FuzzerMutate, ShuffleBytes2) {
350   TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
351 }
352 
353 void TestCopyPart(Mutator M, int NumIter) {
354   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
355   fuzzer::EF = t.get();
356   Random Rand(0);
357   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
358   int FoundMask = 0;
359   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
360   uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
361   uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
362   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
363   uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
364 
365   for (int i = 0; i < NumIter; i++) {
366     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
367     size_t NewSize = (*MD.*M)(T, 7, 7);
368     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
369     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
370     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
371     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
372     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
373   }
374 
375   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
376   uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
377   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
378   uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
379   uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
380 
381   for (int i = 0; i < NumIter; i++) {
382     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
383     size_t NewSize = (*MD.*M)(T, 5, 8);
384     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
385     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
386     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
387     if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
388     if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
389   }
390 
391   EXPECT_EQ(FoundMask, 1023);
392 }
393 
394 TEST(FuzzerMutate, CopyPart1) {
395   TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
396 }
397 TEST(FuzzerMutate, CopyPart2) {
398   TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
399 }
400 TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) {
401   // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an
402   // insert on an input of size `MaxSize`.  Performing an insert in this case
403   // will lead to the mutation failing.
404   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
405   fuzzer::EF = t.get();
406   Random Rand(0);
407   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
408   uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
409   size_t MaxSize = sizeof(Data);
410   for (int count = 0; count < (1 << 18); ++count) {
411     size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize);
412     ASSERT_EQ(NewSize, MaxSize);
413   }
414 }
415 
416 void TestAddWordFromDictionary(Mutator M, int NumIter) {
417   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
418   fuzzer::EF = t.get();
419   Random Rand(0);
420   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
421   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
422   uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
423   MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
424   MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
425   int FoundMask = 0;
426   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
427   uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
428   uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
429   uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
430   uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
431   uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
432   uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
433   uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
434   for (int i = 0; i < NumIter; i++) {
435     uint8_t T[7] = {0x00, 0x11, 0x22};
436     size_t NewSize = (*MD.*M)(T, 3, 7);
437     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
438     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
439     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
440     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
441     if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
442     if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
443     if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
444     if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
445   }
446   EXPECT_EQ(FoundMask, 255);
447 }
448 
449 TEST(FuzzerMutate, AddWordFromDictionary1) {
450   TestAddWordFromDictionary(
451       &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
452 }
453 
454 TEST(FuzzerMutate, AddWordFromDictionary2) {
455   TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
456 }
457 
458 void TestChangeASCIIInteger(Mutator M, int NumIter) {
459   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
460   fuzzer::EF = t.get();
461   Random Rand(0);
462   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
463 
464   uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
465   uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
466   uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
467   uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
468   int FoundMask = 0;
469   for (int i = 0; i < NumIter; i++) {
470     uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
471     size_t NewSize = (*MD.*M)(T, 8, 8);
472     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
473     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
474     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
475     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
476     else if (NewSize == 8)                       FoundMask |= 1 << 4;
477   }
478   EXPECT_EQ(FoundMask, 31);
479 }
480 
481 TEST(FuzzerMutate, ChangeASCIIInteger1) {
482   TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
483                          1 << 15);
484 }
485 
486 TEST(FuzzerMutate, ChangeASCIIInteger2) {
487   TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
488 }
489 
490 void TestChangeBinaryInteger(Mutator M, int NumIter) {
491   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
492   fuzzer::EF = t.get();
493   Random Rand(0);
494   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
495 
496   uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
497   uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
498   uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
499   uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
500   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
501   uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
502   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
503   uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
504 
505   int FoundMask = 0;
506   for (int i = 0; i < NumIter; i++) {
507     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
508     size_t NewSize = (*MD.*M)(T, 8, 8);
509     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
510     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
511     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
512     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
513     else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
514     else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
515     else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
516     else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
517   }
518   EXPECT_EQ(FoundMask, 255);
519 }
520 
521 TEST(FuzzerMutate, ChangeBinaryInteger1) {
522   TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
523                          1 << 12);
524 }
525 
526 TEST(FuzzerMutate, ChangeBinaryInteger2) {
527   TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
528 }
529 
530 
531 TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
532   Unit U;
533   EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
534   EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
535   EXPECT_FALSE(ParseOneDictionaryEntry("\t  ", &U));
536   EXPECT_FALSE(ParseOneDictionaryEntry("  \" ", &U));
537   EXPECT_FALSE(ParseOneDictionaryEntry("  zz\" ", &U));
538   EXPECT_FALSE(ParseOneDictionaryEntry("  \"zz ", &U));
539   EXPECT_FALSE(ParseOneDictionaryEntry("  \"\" ", &U));
540   EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
541   EXPECT_EQ(U, Unit({'a'}));
542   EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
543   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
544   EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
545   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
546   EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
547   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
548   EXPECT_EQ(U, Unit({'\\'}));
549   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
550   EXPECT_EQ(U, Unit({0xAB}));
551   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
552   EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
553   EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
554   EXPECT_EQ(U, Unit({'#'}));
555   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
556   EXPECT_EQ(U, Unit({'"'}));
557 }
558 
559 TEST(FuzzerDictionary, ParseDictionaryFile) {
560   Vector<Unit> Units;
561   EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
562   EXPECT_FALSE(ParseDictionaryFile("", &Units));
563   EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
564   EXPECT_EQ(Units.size(), 0U);
565   EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
566   EXPECT_EQ(Units.size(), 0U);
567   EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
568   EXPECT_EQ(Units.size(), 0U);
569   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\n", &Units));
570   EXPECT_EQ(Units.size(), 0U);
571   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\naaa=\"aa\"", &Units));
572   EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})}));
573   EXPECT_TRUE(
574       ParseDictionaryFile("  #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
575   EXPECT_EQ(Units,
576             Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
577 }
578 
579 TEST(FuzzerUtil, Base64) {
580   EXPECT_EQ("", Base64({}));
581   EXPECT_EQ("YQ==", Base64({'a'}));
582   EXPECT_EQ("eA==", Base64({'x'}));
583   EXPECT_EQ("YWI=", Base64({'a', 'b'}));
584   EXPECT_EQ("eHk=", Base64({'x', 'y'}));
585   EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
586   EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
587   EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
588   EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
589   EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
590 }
591 
592 TEST(Corpus, Distribution) {
593   DataFlowTrace DFT;
594   Random Rand(0);
595   struct EntropicOptions Entropic = {false, 0xFF, 100};
596   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
597   size_t N = 10;
598   size_t TriesPerUnit = 1<<16;
599   for (size_t i = 0; i < N; i++)
600     C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, /*NumFeatures*/ 1,
601                    /*MayDeleteFile*/ false, /*HasFocusFunction*/ false,
602                    /*ForceAddToCorpus*/ false,
603                    /*TimeOfUnit*/ std::chrono::microseconds(0),
604                    /*FeatureSet*/ {}, DFT,
605                    /*BaseII*/ nullptr);
606 
607   Vector<size_t> Hist(N);
608   for (size_t i = 0; i < N * TriesPerUnit; i++) {
609     Hist[C->ChooseUnitIdxToMutate(Rand)]++;
610   }
611   for (size_t i = 0; i < N; i++) {
612     // A weak sanity check that every unit gets invoked.
613     EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
614   }
615 }
616 
617 TEST(Merge, Bad) {
618   const char *kInvalidInputs[] = {
619     "",
620     "x",
621     "3\nx",
622     "2\n3",
623     "2\n2",
624     "2\n2\nA\n",
625     "2\n2\nA\nB\nC\n",
626     "0\n0\n",
627     "1\n1\nA\nFT 0",
628     "1\n1\nA\nSTARTED 1",
629   };
630   Merger M;
631   for (auto S : kInvalidInputs) {
632     // fprintf(stderr, "TESTING:\n%s\n", S);
633     EXPECT_FALSE(M.Parse(S, false));
634   }
635 }
636 
637 void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
638   EXPECT_EQ(A, B);
639 }
640 
641 void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
642   Set<std::string> a(A.begin(), A.end());
643   Set<std::string> b(B.begin(), B.end());
644   EXPECT_EQ(a, b);
645 }
646 
647 static void Merge(const std::string &Input,
648                   const Vector<std::string> Result,
649                   size_t NumNewFeatures) {
650   Merger M;
651   Vector<std::string> NewFiles;
652   Set<uint32_t> NewFeatures, NewCov;
653   EXPECT_TRUE(M.Parse(Input, true));
654   EXPECT_EQ(NumNewFeatures, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles));
655   EQ(NewFiles, Result);
656 }
657 
658 TEST(Merge, Good) {
659   Merger M;
660 
661   EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
662   EXPECT_EQ(M.Files.size(), 1U);
663   EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
664   EXPECT_EQ(M.Files[0].Name, "AA");
665   EXPECT_TRUE(M.LastFailure.empty());
666   EXPECT_EQ(M.FirstNotProcessedFile, 0U);
667 
668   EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
669   EXPECT_EQ(M.Files.size(), 2U);
670   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
671   EXPECT_EQ(M.Files[0].Name, "AA");
672   EXPECT_EQ(M.Files[1].Name, "BB");
673   EXPECT_EQ(M.LastFailure, "AA");
674   EXPECT_EQ(M.FirstNotProcessedFile, 1U);
675 
676   EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
677                         "STARTED 0 1000\n"
678                         "FT 0 1 2 3\n"
679                         "STARTED 1 1001\n"
680                         "FT 1 4 5 6 \n"
681                         "STARTED 2 1002\n"
682                         "", true));
683   EXPECT_EQ(M.Files.size(), 3U);
684   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
685   EXPECT_EQ(M.Files[0].Name, "AA");
686   EXPECT_EQ(M.Files[0].Size, 1000U);
687   EXPECT_EQ(M.Files[1].Name, "BB");
688   EXPECT_EQ(M.Files[1].Size, 1001U);
689   EXPECT_EQ(M.Files[2].Name, "C");
690   EXPECT_EQ(M.Files[2].Size, 1002U);
691   EXPECT_EQ(M.LastFailure, "C");
692   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
693   EQ(M.Files[0].Features, {1, 2, 3});
694   EQ(M.Files[1].Features, {4, 5, 6});
695 
696 
697   Vector<std::string> NewFiles;
698   Set<uint32_t> NewFeatures, NewCov;
699 
700   EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
701                         "STARTED 0 1000\nFT 0 1 2 3\n"
702                         "STARTED 1 1001\nFT 1 4 5 6 \n"
703                         "STARTED 2 1002\nFT 2 6 1 3 \n"
704                         "", true));
705   EXPECT_EQ(M.Files.size(), 3U);
706   EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
707   EXPECT_TRUE(M.LastFailure.empty());
708   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
709   EQ(M.Files[0].Features, {1, 2, 3});
710   EQ(M.Files[1].Features, {4, 5, 6});
711   EQ(M.Files[2].Features, {1, 3, 6});
712   EXPECT_EQ(0U, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles));
713   EQ(NewFiles, {});
714 
715   EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
716                         "STARTED 0 1000\nFT 0 1 2 3\n"
717                         "STARTED 1 1001\nFT 1 4 5 6 \n"
718                         "STARTED 2 1002\nFT 2 6 1 3\n"
719                         "", true));
720   EQ(M.Files[0].Features, {1, 2, 3});
721   EQ(M.Files[1].Features, {4, 5, 6});
722   EQ(M.Files[2].Features, {1, 3, 6});
723   EXPECT_EQ(3U, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles));
724   EQ(NewFiles, {"B"});
725 
726   // Same as the above, but with InitialFeatures.
727   EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
728                         "STARTED 0 1001\nFT 0 4 5 6 \n"
729                         "STARTED 1 1002\nFT 1 6 1 3\n"
730                         "", true));
731   EQ(M.Files[0].Features, {4, 5, 6});
732   EQ(M.Files[1].Features, {1, 3, 6});
733   Set<uint32_t> InitialFeatures;
734   InitialFeatures.insert(1);
735   InitialFeatures.insert(2);
736   InitialFeatures.insert(3);
737   EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFeatures, {}, &NewCov, &NewFiles));
738   EQ(NewFiles, {"B"});
739 }
740 
741 TEST(Merge, Merge) {
742 
743   Merge("3\n1\nA\nB\nC\n"
744         "STARTED 0 1000\nFT 0 1 2 3\n"
745         "STARTED 1 1001\nFT 1 4 5 6 \n"
746         "STARTED 2 1002\nFT 2 6 1 3 \n",
747         {"B"}, 3);
748 
749   Merge("3\n0\nA\nB\nC\n"
750         "STARTED 0 2000\nFT 0 1 2 3\n"
751         "STARTED 1 1001\nFT 1 4 5 6 \n"
752         "STARTED 2 1002\nFT 2 6 1 3 \n",
753         {"A", "B", "C"}, 6);
754 
755   Merge("4\n0\nA\nB\nC\nD\n"
756         "STARTED 0 2000\nFT 0 1 2 3\n"
757         "STARTED 1 1101\nFT 1 4 5 6 \n"
758         "STARTED 2 1102\nFT 2 6 1 3 100 \n"
759         "STARTED 3 1000\nFT 3 1  \n",
760         {"A", "B", "C", "D"}, 7);
761 
762   Merge("4\n1\nA\nB\nC\nD\n"
763         "STARTED 0 2000\nFT 0 4 5 6 7 8\n"
764         "STARTED 1 1100\nFT 1 1 2 3 \n"
765         "STARTED 2 1100\nFT 2 2 3 \n"
766         "STARTED 3 1000\nFT 3 1  \n",
767         {"B", "D"}, 3);
768 }
769 
770 TEST(DFT, BlockCoverage) {
771   BlockCoverage Cov;
772   // Assuming C0 has 5 instrumented blocks,
773   // C1: 7 blocks, C2: 4, C3: 9, C4 never covered, C5: 15,
774 
775   // Add C0
776   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
777   EXPECT_EQ(Cov.GetCounter(0, 0), 1U);
778   EXPECT_EQ(Cov.GetCounter(0, 1), 0U);  // not seen this BB yet.
779   EXPECT_EQ(Cov.GetCounter(0, 5), 0U);  // BB ID out of bounds.
780   EXPECT_EQ(Cov.GetCounter(1, 0), 0U);  // not seen this function yet.
781 
782   EXPECT_EQ(Cov.GetNumberOfBlocks(0), 5U);
783   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 1U);
784   EXPECT_EQ(Cov.GetNumberOfBlocks(1), 0U);
785 
786   // Various errors.
787   EXPECT_FALSE(Cov.AppendCoverage("C0\n"));  // No total number.
788   EXPECT_FALSE(Cov.AppendCoverage("C0 7\n"));  // No total number.
789   EXPECT_FALSE(Cov.AppendCoverage("CZ\n"));  // Wrong function number.
790   EXPECT_FALSE(Cov.AppendCoverage("C1 7 7"));  // BB ID is too big.
791   EXPECT_FALSE(Cov.AppendCoverage("C1 100 7")); // BB ID is too big.
792 
793   // Add C0 more times.
794   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
795   EXPECT_EQ(Cov.GetCounter(0, 0), 2U);
796   EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 5\n"));
797   EXPECT_EQ(Cov.GetCounter(0, 0), 3U);
798   EXPECT_EQ(Cov.GetCounter(0, 1), 1U);
799   EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
800   EXPECT_EQ(Cov.GetCounter(0, 3), 0U);
801   EXPECT_EQ(Cov.GetCounter(0, 4), 0U);
802   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 3U);
803   EXPECT_TRUE(Cov.AppendCoverage("C0 1 3 4 5\n"));
804   EXPECT_EQ(Cov.GetCounter(0, 0), 4U);
805   EXPECT_EQ(Cov.GetCounter(0, 1), 2U);
806   EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
807   EXPECT_EQ(Cov.GetCounter(0, 3), 1U);
808   EXPECT_EQ(Cov.GetCounter(0, 4), 1U);
809   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 5U);
810 
811   EXPECT_TRUE(Cov.AppendCoverage("C1 7\nC2 4\nC3 9\nC5 15\nC0 5\n"));
812   EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
813   EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
814   EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
815   EXPECT_EQ(Cov.GetCounter(3, 0), 1U);
816   EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
817   EXPECT_EQ(Cov.GetCounter(5, 0), 1U);
818 
819   EXPECT_TRUE(Cov.AppendCoverage("C3 4 5 9\nC5 11 12 15"));
820   EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
821   EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
822   EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
823   EXPECT_EQ(Cov.GetCounter(3, 0), 2U);
824   EXPECT_EQ(Cov.GetCounter(3, 4), 1U);
825   EXPECT_EQ(Cov.GetCounter(3, 5), 1U);
826   EXPECT_EQ(Cov.GetCounter(3, 6), 0U);
827   EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
828   EXPECT_EQ(Cov.GetCounter(5, 0), 2U);
829   EXPECT_EQ(Cov.GetCounter(5, 10), 0U);
830   EXPECT_EQ(Cov.GetCounter(5, 11), 1U);
831   EXPECT_EQ(Cov.GetCounter(5, 12), 1U);
832 }
833 
834 TEST(DFT, FunctionWeights) {
835   BlockCoverage Cov;
836   // unused function gets zero weight.
837   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
838   auto Weights = Cov.FunctionWeights(2);
839   EXPECT_GT(Weights[0], 0.);
840   EXPECT_EQ(Weights[1], 0.);
841 
842   // Less frequently used function gets less weight.
843   Cov.clear();
844   EXPECT_TRUE(Cov.AppendCoverage("C0 5\nC1 5\nC1 5\n"));
845   Weights = Cov.FunctionWeights(2);
846   EXPECT_GT(Weights[0], Weights[1]);
847 
848   // A function with more uncovered blocks gets more weight.
849   Cov.clear();
850   EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n"));
851   Weights = Cov.FunctionWeights(2);
852   EXPECT_GT(Weights[1], Weights[0]);
853 
854   // A function with DFT gets more weight than the function w/o DFT.
855   Cov.clear();
856   EXPECT_TRUE(Cov.AppendCoverage("F1 111\nC0 3\nC1 1 2 3\n"));
857   Weights = Cov.FunctionWeights(2);
858   EXPECT_GT(Weights[1], Weights[0]);
859 }
860 
861 
862 TEST(Fuzzer, ForEachNonZeroByte) {
863   const size_t N = 64;
864   alignas(64) uint8_t Ar[N + 8] = {
865     0, 0, 0, 0, 0, 0, 0, 0,
866     1, 2, 0, 0, 0, 0, 0, 0,
867     0, 0, 3, 0, 4, 0, 0, 0,
868     0, 0, 0, 0, 0, 0, 0, 0,
869     0, 0, 0, 5, 0, 6, 0, 0,
870     0, 0, 0, 0, 0, 0, 7, 0,
871     0, 0, 0, 0, 0, 0, 0, 0,
872     0, 0, 0, 0, 0, 0, 0, 8,
873     9, 9, 9, 9, 9, 9, 9, 9,
874   };
875   typedef Vector<std::pair<size_t, uint8_t> > Vec;
876   Vec Res, Expected;
877   auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
878     Res.push_back({FirstFeature + Idx, V});
879   };
880   ForEachNonZeroByte(Ar, Ar + N, 100, CB);
881   Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
882               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
883   EXPECT_EQ(Res, Expected);
884 
885   Res.clear();
886   ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
887   Expected = {          {109, 2}, {118, 3}, {120, 4},
888               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
889   EXPECT_EQ(Res, Expected);
890 
891   Res.clear();
892   ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
893   Expected = {          {109, 2}, {118, 3}, {120, 4},
894               {135, 5}, {137, 6}, {146, 7}};
895   EXPECT_EQ(Res, Expected);
896 }
897 
898 // FuzzerCommand unit tests. The arguments in the two helper methods below must
899 // match.
900 static void makeCommandArgs(Vector<std::string> *ArgsToAdd) {
901   assert(ArgsToAdd);
902   ArgsToAdd->clear();
903   ArgsToAdd->push_back("foo");
904   ArgsToAdd->push_back("-bar=baz");
905   ArgsToAdd->push_back("qux");
906   ArgsToAdd->push_back(Command::ignoreRemainingArgs());
907   ArgsToAdd->push_back("quux");
908   ArgsToAdd->push_back("-grault=garply");
909 }
910 
911 static std::string makeCmdLine(const char *separator, const char *suffix) {
912   std::string CmdLine("foo -bar=baz qux ");
913   if (strlen(separator) != 0) {
914     CmdLine += separator;
915     CmdLine += " ";
916   }
917   CmdLine += Command::ignoreRemainingArgs();
918   CmdLine += " quux -grault=garply";
919   if (strlen(suffix) != 0) {
920     CmdLine += " ";
921     CmdLine += suffix;
922   }
923   return CmdLine;
924 }
925 
926 TEST(FuzzerCommand, Create) {
927   std::string CmdLine;
928 
929   // Default constructor
930   Command DefaultCmd;
931 
932   CmdLine = DefaultCmd.toString();
933   EXPECT_EQ(CmdLine, "");
934 
935   // Explicit constructor
936   Vector<std::string> ArgsToAdd;
937   makeCommandArgs(&ArgsToAdd);
938   Command InitializedCmd(ArgsToAdd);
939 
940   CmdLine = InitializedCmd.toString();
941   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
942 
943   // Compare each argument
944   auto InitializedArgs = InitializedCmd.getArguments();
945   auto i = ArgsToAdd.begin();
946   auto j = InitializedArgs.begin();
947   while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
948     EXPECT_EQ(*i++, *j++);
949   }
950   EXPECT_EQ(i, ArgsToAdd.end());
951   EXPECT_EQ(j, InitializedArgs.end());
952 
953   // Copy constructor
954   Command CopiedCmd(InitializedCmd);
955 
956   CmdLine = CopiedCmd.toString();
957   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
958 
959   // Assignment operator
960   Command AssignedCmd;
961   AssignedCmd = CopiedCmd;
962 
963   CmdLine = AssignedCmd.toString();
964   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
965 }
966 
967 TEST(FuzzerCommand, ModifyArguments) {
968   Vector<std::string> ArgsToAdd;
969   makeCommandArgs(&ArgsToAdd);
970   Command Cmd;
971   std::string CmdLine;
972 
973   Cmd.addArguments(ArgsToAdd);
974   CmdLine = Cmd.toString();
975   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
976 
977   Cmd.addArgument("waldo");
978   EXPECT_TRUE(Cmd.hasArgument("waldo"));
979 
980   CmdLine = Cmd.toString();
981   EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
982 
983   Cmd.removeArgument("waldo");
984   EXPECT_FALSE(Cmd.hasArgument("waldo"));
985 
986   CmdLine = Cmd.toString();
987   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
988 }
989 
990 TEST(FuzzerCommand, ModifyFlags) {
991   Vector<std::string> ArgsToAdd;
992   makeCommandArgs(&ArgsToAdd);
993   Command Cmd(ArgsToAdd);
994   std::string Value, CmdLine;
995   ASSERT_FALSE(Cmd.hasFlag("fred"));
996 
997   Value = Cmd.getFlagValue("fred");
998   EXPECT_EQ(Value, "");
999 
1000   CmdLine = Cmd.toString();
1001   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1002 
1003   Cmd.addFlag("fred", "plugh");
1004   EXPECT_TRUE(Cmd.hasFlag("fred"));
1005 
1006   Value = Cmd.getFlagValue("fred");
1007   EXPECT_EQ(Value, "plugh");
1008 
1009   CmdLine = Cmd.toString();
1010   EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
1011 
1012   Cmd.removeFlag("fred");
1013   EXPECT_FALSE(Cmd.hasFlag("fred"));
1014 
1015   Value = Cmd.getFlagValue("fred");
1016   EXPECT_EQ(Value, "");
1017 
1018   CmdLine = Cmd.toString();
1019   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1020 }
1021 
1022 TEST(FuzzerCommand, SetOutput) {
1023   Vector<std::string> ArgsToAdd;
1024   makeCommandArgs(&ArgsToAdd);
1025   Command Cmd(ArgsToAdd);
1026   std::string CmdLine;
1027   ASSERT_FALSE(Cmd.hasOutputFile());
1028   ASSERT_FALSE(Cmd.isOutAndErrCombined());
1029 
1030   Cmd.combineOutAndErr(true);
1031   EXPECT_TRUE(Cmd.isOutAndErrCombined());
1032 
1033   CmdLine = Cmd.toString();
1034   EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
1035 
1036   Cmd.combineOutAndErr(false);
1037   EXPECT_FALSE(Cmd.isOutAndErrCombined());
1038 
1039   Cmd.setOutputFile("xyzzy");
1040   EXPECT_TRUE(Cmd.hasOutputFile());
1041 
1042   CmdLine = Cmd.toString();
1043   EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
1044 
1045   Cmd.setOutputFile("thud");
1046   EXPECT_TRUE(Cmd.hasOutputFile());
1047 
1048   CmdLine = Cmd.toString();
1049   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
1050 
1051   Cmd.combineOutAndErr();
1052   EXPECT_TRUE(Cmd.isOutAndErrCombined());
1053 
1054   CmdLine = Cmd.toString();
1055   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
1056 }
1057 
1058 TEST(Entropic, UpdateFrequency) {
1059   const size_t One = 1, Two = 2;
1060   const size_t FeatIdx1 = 0, FeatIdx2 = 42, FeatIdx3 = 12, FeatIdx4 = 26;
1061   size_t Index;
1062   // Create input corpus with default entropic configuration
1063   struct EntropicOptions Entropic = {true, 0xFF, 100};
1064   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
1065   std::unique_ptr<InputInfo> II(new InputInfo());
1066 
1067   C->AddRareFeature(FeatIdx1);
1068   C->UpdateFeatureFrequency(II.get(), FeatIdx1);
1069   EXPECT_EQ(II->FeatureFreqs.size(), One);
1070   C->AddRareFeature(FeatIdx2);
1071   C->UpdateFeatureFrequency(II.get(), FeatIdx1);
1072   C->UpdateFeatureFrequency(II.get(), FeatIdx2);
1073   EXPECT_EQ(II->FeatureFreqs.size(), Two);
1074   EXPECT_EQ(II->FeatureFreqs[0].second, 2);
1075   EXPECT_EQ(II->FeatureFreqs[1].second, 1);
1076 
1077   C->AddRareFeature(FeatIdx3);
1078   C->AddRareFeature(FeatIdx4);
1079   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1080   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1081   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1082   C->UpdateFeatureFrequency(II.get(), FeatIdx4);
1083 
1084   for (Index = 1; Index < II->FeatureFreqs.size(); Index++)
1085     EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first);
1086 
1087   II->DeleteFeatureFreq(FeatIdx3);
1088   for (Index = 1; Index < II->FeatureFreqs.size(); Index++)
1089     EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first);
1090 }
1091 
1092 double SubAndSquare(double X, double Y) {
1093   double R = X - Y;
1094   R = R * R;
1095   return R;
1096 }
1097 
1098 TEST(Entropic, ComputeEnergy) {
1099   const double Precision = 0.01;
1100   struct EntropicOptions Entropic = {true, 0xFF, 100};
1101   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
1102   std::unique_ptr<InputInfo> II(new InputInfo());
1103   Vector<std::pair<uint32_t, uint16_t>> FeatureFreqs = {{1, 3}, {2, 3}, {3, 3}};
1104   II->FeatureFreqs = FeatureFreqs;
1105   II->NumExecutedMutations = 0;
1106   II->UpdateEnergy(4, false, std::chrono::microseconds(0));
1107   EXPECT_LT(SubAndSquare(II->Energy, 1.450805), Precision);
1108 
1109   II->NumExecutedMutations = 9;
1110   II->UpdateEnergy(5, false, std::chrono::microseconds(0));
1111   EXPECT_LT(SubAndSquare(II->Energy, 1.525496), Precision);
1112 
1113   II->FeatureFreqs[0].second++;
1114   II->FeatureFreqs.push_back(std::pair<uint32_t, uint16_t>(42, 6));
1115   II->NumExecutedMutations = 20;
1116   II->UpdateEnergy(10, false, std::chrono::microseconds(0));
1117   EXPECT_LT(SubAndSquare(II->Energy, 1.792831), Precision);
1118 }
1119 
1120 int main(int argc, char **argv) {
1121   testing::InitGoogleTest(&argc, argv);
1122   return RUN_ALL_TESTS();
1123 }
1124