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
28 // LLVMFuzzerTestOneInput.
29 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
30   abort();
31 }
32 
33 TEST(Fuzzer, Basename) {
34   EXPECT_EQ(Basename("foo/bar"), "bar");
35   EXPECT_EQ(Basename("bar"), "bar");
36   EXPECT_EQ(Basename("/bar"), "bar");
37   EXPECT_EQ(Basename("foo/x"), "x");
38   EXPECT_EQ(Basename("foo/"), "");
39 #if LIBFUZZER_WINDOWS
40   EXPECT_EQ(Basename("foo\\bar"), "bar");
41   EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
42   EXPECT_EQ(Basename("\\bar"), "bar");
43   EXPECT_EQ(Basename("foo\\x"), "x");
44   EXPECT_EQ(Basename("foo\\"), "");
45 #endif
46 }
47 
48 TEST(Fuzzer, CrossOver) {
49   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
50   fuzzer::EF = t.get();
51   Random Rand(0);
52   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
53   Unit A({0, 1, 2}), B({5, 6, 7});
54   Unit C;
55   Unit Expected[] = {
56        { 0 },
57        { 0, 1 },
58        { 0, 5 },
59        { 0, 1, 2 },
60        { 0, 1, 5 },
61        { 0, 5, 1 },
62        { 0, 5, 6 },
63        { 0, 1, 2, 5 },
64        { 0, 1, 5, 2 },
65        { 0, 1, 5, 6 },
66        { 0, 5, 1, 2 },
67        { 0, 5, 1, 6 },
68        { 0, 5, 6, 1 },
69        { 0, 5, 6, 7 },
70        { 0, 1, 2, 5, 6 },
71        { 0, 1, 5, 2, 6 },
72        { 0, 1, 5, 6, 2 },
73        { 0, 1, 5, 6, 7 },
74        { 0, 5, 1, 2, 6 },
75        { 0, 5, 1, 6, 2 },
76        { 0, 5, 1, 6, 7 },
77        { 0, 5, 6, 1, 2 },
78        { 0, 5, 6, 1, 7 },
79        { 0, 5, 6, 7, 1 },
80        { 0, 1, 2, 5, 6, 7 },
81        { 0, 1, 5, 2, 6, 7 },
82        { 0, 1, 5, 6, 2, 7 },
83        { 0, 1, 5, 6, 7, 2 },
84        { 0, 5, 1, 2, 6, 7 },
85        { 0, 5, 1, 6, 2, 7 },
86        { 0, 5, 1, 6, 7, 2 },
87        { 0, 5, 6, 1, 2, 7 },
88        { 0, 5, 6, 1, 7, 2 },
89        { 0, 5, 6, 7, 1, 2 }
90   };
91   for (size_t Len = 1; Len < 8; Len++) {
92     std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
93     for (int Iter = 0; Iter < 3000; Iter++) {
94       C.resize(Len);
95       size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
96                                      C.data(), C.size());
97       C.resize(NewSize);
98       FoundUnits.insert(C);
99     }
100     for (const Unit &U : Expected)
101       if (U.size() <= Len)
102         ExpectedUnitsWitThisLength.insert(U);
103     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
104   }
105 }
106 
107 TEST(Fuzzer, Hash) {
108   uint8_t A[] = {'a', 'b', 'c'};
109   fuzzer::Unit U(A, A + sizeof(A));
110   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
111   U.push_back('d');
112   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
113 }
114 
115 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
116                                               size_t MaxSize);
117 
118 void TestEraseBytes(Mutator M, int NumIter) {
119   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
120   fuzzer::EF = t.get();
121   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
122   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
123   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
124   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
125   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
126   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
127   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
128   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
129 
130   uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
131   uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
132   uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
133 
134   uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
135   uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
136   uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
137 
138 
139   Random Rand(0);
140   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
141   int FoundMask = 0;
142   for (int i = 0; i < NumIter; i++) {
143     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
144     size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
145     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
146     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
147     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
148     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
149     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
150     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
151     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
152     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
153 
154     if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
155     if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
156     if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
157 
158     if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
159     if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
160     if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
161   }
162   EXPECT_EQ(FoundMask, (1 << 14) - 1);
163 }
164 
165 TEST(FuzzerMutate, EraseBytes1) {
166   TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
167 }
168 TEST(FuzzerMutate, EraseBytes2) {
169   TestEraseBytes(&MutationDispatcher::Mutate, 2000);
170 }
171 
172 void TestInsertByte(Mutator M, int NumIter) {
173   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
174   fuzzer::EF = t.get();
175   Random Rand(0);
176   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
177   int FoundMask = 0;
178   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
179   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
180   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
181   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
182   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
183   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
184   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
185   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
186   for (int i = 0; i < NumIter; i++) {
187     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
188     size_t NewSize = (*MD.*M)(T, 7, 8);
189     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
190     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
191     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
192     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
193     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
194     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
195     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
196     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
197   }
198   EXPECT_EQ(FoundMask, 255);
199 }
200 
201 TEST(FuzzerMutate, InsertByte1) {
202   TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
203 }
204 TEST(FuzzerMutate, InsertByte2) {
205   TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
206 }
207 
208 void TestInsertRepeatedBytes(Mutator M, int NumIter) {
209   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
210   fuzzer::EF = t.get();
211   Random Rand(0);
212   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
213   int FoundMask = 0;
214   uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
215   uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
216   uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
217   uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
218   uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
219 
220   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
221   uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
222   uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
223   uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
224   uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
225 
226   for (int i = 0; i < NumIter; i++) {
227     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
228     size_t NewSize = (*MD.*M)(T, 4, 8);
229     if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
230     if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
231     if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
232     if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
233     if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
234 
235     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
236     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
237     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
238     if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
239     if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
240 
241   }
242   EXPECT_EQ(FoundMask, (1 << 10) - 1);
243 }
244 
245 TEST(FuzzerMutate, InsertRepeatedBytes1) {
246   TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes,
247                           10000);
248 }
249 TEST(FuzzerMutate, InsertRepeatedBytes2) {
250   TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
251 }
252 
253 void TestChangeByte(Mutator M, int NumIter) {
254   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
255   fuzzer::EF = t.get();
256   Random Rand(0);
257   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
258   int FoundMask = 0;
259   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
260   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
261   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
262   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
263   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
264   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
265   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
266   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
267   for (int i = 0; i < NumIter; i++) {
268     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
269     size_t NewSize = (*MD.*M)(T, 8, 9);
270     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
271     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
272     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
273     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
274     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
275     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
276     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
277     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
278   }
279   EXPECT_EQ(FoundMask, 255);
280 }
281 
282 TEST(FuzzerMutate, ChangeByte1) {
283   TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
284 }
285 TEST(FuzzerMutate, ChangeByte2) {
286   TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
287 }
288 
289 void TestChangeBit(Mutator M, int NumIter) {
290   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
291   fuzzer::EF = t.get();
292   Random Rand(0);
293   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
294   int FoundMask = 0;
295   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
296   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
297   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
298   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
299   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
300   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
301   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
302   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
303   for (int i = 0; i < NumIter; i++) {
304     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
305     size_t NewSize = (*MD.*M)(T, 8, 9);
306     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
307     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
308     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
309     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
310     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
311     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
312     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
313     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
314   }
315   EXPECT_EQ(FoundMask, 255);
316 }
317 
318 TEST(FuzzerMutate, ChangeBit1) {
319   TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
320 }
321 TEST(FuzzerMutate, ChangeBit2) {
322   TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
323 }
324 
325 void TestShuffleBytes(Mutator M, int NumIter) {
326   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
327   fuzzer::EF = t.get();
328   Random Rand(0);
329   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
330   int FoundMask = 0;
331   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
332   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
333   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
334   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
335   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
336   for (int i = 0; i < NumIter; i++) {
337     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
338     size_t NewSize = (*MD.*M)(T, 7, 7);
339     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
340     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
341     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
342     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
343     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
344   }
345   EXPECT_EQ(FoundMask, 31);
346 }
347 
348 TEST(FuzzerMutate, ShuffleBytes1) {
349   TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
350 }
351 TEST(FuzzerMutate, ShuffleBytes2) {
352   TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
353 }
354 
355 void TestCopyPart(Mutator M, int NumIter) {
356   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
357   fuzzer::EF = t.get();
358   Random Rand(0);
359   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
360   int FoundMask = 0;
361   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
362   uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
363   uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
364   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
365   uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
366 
367   for (int i = 0; i < NumIter; i++) {
368     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
369     size_t NewSize = (*MD.*M)(T, 7, 7);
370     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
371     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
372     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
373     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
374     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
375   }
376 
377   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
378   uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
379   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
380   uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
381   uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
382 
383   for (int i = 0; i < NumIter; i++) {
384     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
385     size_t NewSize = (*MD.*M)(T, 5, 8);
386     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
387     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
388     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
389     if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
390     if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
391   }
392 
393   EXPECT_EQ(FoundMask, 1023);
394 }
395 
396 TEST(FuzzerMutate, CopyPart1) {
397   TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
398 }
399 TEST(FuzzerMutate, CopyPart2) {
400   TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
401 }
402 TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) {
403   // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an
404   // insert on an input of size `MaxSize`.  Performing an insert in this case
405   // will lead to the mutation failing.
406   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
407   fuzzer::EF = t.get();
408   Random Rand(0);
409   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
410   uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
411   size_t MaxSize = sizeof(Data);
412   for (int count = 0; count < (1 << 18); ++count) {
413     size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize);
414     ASSERT_EQ(NewSize, MaxSize);
415   }
416 }
417 
418 void TestAddWordFromDictionary(Mutator M, int NumIter) {
419   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
420   fuzzer::EF = t.get();
421   Random Rand(0);
422   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
423   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
424   uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
425   MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
426   MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
427   int FoundMask = 0;
428   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
429   uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
430   uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
431   uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
432   uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
433   uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
434   uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
435   uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
436   for (int i = 0; i < NumIter; i++) {
437     uint8_t T[7] = {0x00, 0x11, 0x22};
438     size_t NewSize = (*MD.*M)(T, 3, 7);
439     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
440     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
441     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
442     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
443     if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
444     if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
445     if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
446     if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
447   }
448   EXPECT_EQ(FoundMask, 255);
449 }
450 
451 TEST(FuzzerMutate, AddWordFromDictionary1) {
452   TestAddWordFromDictionary(
453       &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
454 }
455 
456 TEST(FuzzerMutate, AddWordFromDictionary2) {
457   TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
458 }
459 
460 void TestChangeASCIIInteger(Mutator M, int NumIter) {
461   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
462   fuzzer::EF = t.get();
463   Random Rand(0);
464   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
465 
466   uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
467   uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
468   uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
469   uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
470   int FoundMask = 0;
471   for (int i = 0; i < NumIter; i++) {
472     uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
473     size_t NewSize = (*MD.*M)(T, 8, 8);
474     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
475     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
476     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
477     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
478     else if (NewSize == 8)                       FoundMask |= 1 << 4;
479   }
480   EXPECT_EQ(FoundMask, 31);
481 }
482 
483 TEST(FuzzerMutate, ChangeASCIIInteger1) {
484   TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
485                          1 << 15);
486 }
487 
488 TEST(FuzzerMutate, ChangeASCIIInteger2) {
489   TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
490 }
491 
492 void TestChangeBinaryInteger(Mutator M, int NumIter) {
493   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
494   fuzzer::EF = t.get();
495   Random Rand(0);
496   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
497 
498   uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
499   uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
500   uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
501   uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
502   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
503   uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
504   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
505   uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
506 
507   int FoundMask = 0;
508   for (int i = 0; i < NumIter; i++) {
509     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
510     size_t NewSize = (*MD.*M)(T, 8, 8);
511     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
512     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
513     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
514     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
515     else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
516     else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
517     else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
518     else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
519   }
520   EXPECT_EQ(FoundMask, 255);
521 }
522 
523 TEST(FuzzerMutate, ChangeBinaryInteger1) {
524   TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
525                          1 << 12);
526 }
527 
528 TEST(FuzzerMutate, ChangeBinaryInteger2) {
529   TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
530 }
531 
532 
533 TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
534   Unit U;
535   EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
536   EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
537   EXPECT_FALSE(ParseOneDictionaryEntry("\t  ", &U));
538   EXPECT_FALSE(ParseOneDictionaryEntry("  \" ", &U));
539   EXPECT_FALSE(ParseOneDictionaryEntry("  zz\" ", &U));
540   EXPECT_FALSE(ParseOneDictionaryEntry("  \"zz ", &U));
541   EXPECT_FALSE(ParseOneDictionaryEntry("  \"\" ", &U));
542   EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
543   EXPECT_EQ(U, Unit({'a'}));
544   EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
545   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
546   EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
547   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
548   EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
549   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
550   EXPECT_EQ(U, Unit({'\\'}));
551   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
552   EXPECT_EQ(U, Unit({0xAB}));
553   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
554   EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
555   EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
556   EXPECT_EQ(U, Unit({'#'}));
557   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
558   EXPECT_EQ(U, Unit({'"'}));
559 }
560 
561 TEST(FuzzerDictionary, ParseDictionaryFile) {
562   std::vector<Unit> Units;
563   EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
564   EXPECT_FALSE(ParseDictionaryFile("", &Units));
565   EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
566   EXPECT_EQ(Units.size(), 0U);
567   EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\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\n", &Units));
572   EXPECT_EQ(Units.size(), 0U);
573   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\naaa=\"aa\"", &Units));
574   EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
575   EXPECT_TRUE(
576       ParseDictionaryFile("  #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
577   EXPECT_EQ(Units,
578             std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
579 }
580 
581 TEST(FuzzerUtil, Base64) {
582   EXPECT_EQ("", Base64({}));
583   EXPECT_EQ("YQ==", Base64({'a'}));
584   EXPECT_EQ("eA==", Base64({'x'}));
585   EXPECT_EQ("YWI=", Base64({'a', 'b'}));
586   EXPECT_EQ("eHk=", Base64({'x', 'y'}));
587   EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
588   EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
589   EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
590   EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
591   EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
592 }
593 
594 #ifdef __GLIBC__
595 class PrintfCapture {
596  public:
597   PrintfCapture() {
598     OldOutputFile = GetOutputFile();
599     SetOutputFile(open_memstream(&Buffer, &Size));
600   }
601   ~PrintfCapture() {
602     fclose(GetOutputFile());
603     SetOutputFile(OldOutputFile);
604     free(Buffer);
605   }
606   std::string str() { return std::string(Buffer, Size); }
607 
608  private:
609   char *Buffer;
610   size_t Size;
611   FILE *OldOutputFile;
612 };
613 
614 TEST(FuzzerUtil, PrintASCII) {
615   auto f = [](const char *Str, const char *PrintAfter = "") {
616     PrintfCapture Capture;
617     PrintASCII(reinterpret_cast<const uint8_t*>(Str), strlen(Str), PrintAfter);
618     return Capture.str();
619   };
620   EXPECT_EQ("hello", f("hello"));
621   EXPECT_EQ("c:\\\\", f("c:\\"));
622   EXPECT_EQ("\\\"hi\\\"", f("\"hi\""));
623   EXPECT_EQ("\\011a", f("\ta"));
624   EXPECT_EQ("\\0111", f("\t1"));
625   EXPECT_EQ("hello\\012", f("hello\n"));
626   EXPECT_EQ("hello\n", f("hello", "\n"));
627 }
628 #endif
629 
630 TEST(Corpus, Distribution) {
631   DataFlowTrace DFT;
632   Random Rand(0);
633   struct EntropicOptions Entropic = {false, 0xFF, 100, false};
634   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
635   size_t N = 10;
636   size_t TriesPerUnit = 1<<16;
637   for (size_t i = 0; i < N; i++)
638     C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, /*NumFeatures*/ 1,
639                    /*MayDeleteFile*/ false, /*HasFocusFunction*/ false,
640                    /*ForceAddToCorpus*/ false,
641                    /*TimeOfUnit*/ std::chrono::microseconds(0),
642                    /*FeatureSet*/ {}, DFT,
643                    /*BaseII*/ nullptr);
644 
645   std::vector<size_t> Hist(N);
646   for (size_t i = 0; i < N * TriesPerUnit; i++) {
647     Hist[C->ChooseUnitIdxToMutate(Rand)]++;
648   }
649   for (size_t i = 0; i < N; i++) {
650     // A weak sanity check that every unit gets invoked.
651     EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
652   }
653 }
654 
655 TEST(Corpus, Replace) {
656   DataFlowTrace DFT;
657   struct EntropicOptions Entropic = {false, 0xFF, 100, false};
658   std::unique_ptr<InputCorpus> C(
659       new InputCorpus(/*OutputCorpus*/ "", Entropic));
660   InputInfo *FirstII =
661       C->AddToCorpus(Unit{0x01, 0x00}, /*NumFeatures*/ 1,
662                      /*MayDeleteFile*/ false, /*HasFocusFunction*/ false,
663                      /*ForceAddToCorpus*/ false,
664                      /*TimeOfUnit*/ std::chrono::microseconds(1234),
665                      /*FeatureSet*/ {}, DFT,
666                      /*BaseII*/ nullptr);
667   InputInfo *SecondII =
668       C->AddToCorpus(Unit{0x02}, /*NumFeatures*/ 1,
669                      /*MayDeleteFile*/ false, /*HasFocusFunction*/ false,
670                      /*ForceAddToCorpus*/ false,
671                      /*TimeOfUnit*/ std::chrono::microseconds(5678),
672                      /*FeatureSet*/ {}, DFT,
673                      /*BaseII*/ nullptr);
674   (void) SecondII;
675   Unit ReplacedU = Unit{0x03};
676 
677   C->Replace(FirstII, ReplacedU,
678              /*TimeOfUnit*/ std::chrono::microseconds(321));
679 
680   EXPECT_EQ(FirstII->U, Unit{0x03});
681   EXPECT_EQ(FirstII->Reduced, true);
682   EXPECT_EQ(FirstII->TimeOfUnit, std::chrono::microseconds(321));
683   std::vector<uint8_t> ExpectedSha1(kSHA1NumBytes);
684   ComputeSHA1(ReplacedU.data(), ReplacedU.size(), ExpectedSha1.data());
685   std::vector<uint8_t> IISha1(FirstII->Sha1, FirstII->Sha1 + kSHA1NumBytes);
686   EXPECT_EQ(IISha1, ExpectedSha1);
687 }
688 
689 template <typename T>
690 void EQ(const std::vector<T> &A, const std::vector<T> &B) {
691   EXPECT_EQ(A, B);
692 }
693 
694 template <typename T> void EQ(const std::set<T> &A, const std::vector<T> &B) {
695   EXPECT_EQ(A, std::set<T>(B.begin(), B.end()));
696 }
697 
698 void EQ(const std::vector<MergeFileInfo> &A,
699         const std::vector<std::string> &B) {
700   std::set<std::string> a;
701   for (const auto &File : A)
702     a.insert(File.Name);
703   std::set<std::string> b(B.begin(), B.end());
704   EXPECT_EQ(a, b);
705 }
706 
707 #define TRACED_EQ(A, ...)                                                      \
708   {                                                                            \
709     SCOPED_TRACE(#A);                                                          \
710     EQ(A, __VA_ARGS__);                                                        \
711   }
712 
713 TEST(Merger, Parse) {
714   Merger M;
715 
716   const char *kInvalidInputs[] = {
717       // Bad file numbers
718       "",
719       "x",
720       "0\n0",
721       "3\nx",
722       "2\n3",
723       "2\n2",
724       // Bad file names
725       "2\n2\nA\n",
726       "2\n2\nA\nB\nC\n",
727       // Unknown markers
728       "2\n1\nA\nSTARTED 0\nBAD 0 0x0",
729       // Bad file IDs
730       "1\n1\nA\nSTARTED 1",
731       "2\n1\nA\nSTARTED 0\nFT 1 0x0",
732   };
733   for (auto S : kInvalidInputs) {
734     SCOPED_TRACE(S);
735     EXPECT_FALSE(M.Parse(S, false));
736   }
737 
738   // Parse initial control file
739   EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
740   ASSERT_EQ(M.Files.size(), 1U);
741   EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
742   EXPECT_EQ(M.Files[0].Name, "AA");
743   EXPECT_TRUE(M.LastFailure.empty());
744   EXPECT_EQ(M.FirstNotProcessedFile, 0U);
745 
746   // Parse control file that failed on first attempt
747   EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
748   ASSERT_EQ(M.Files.size(), 2U);
749   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
750   EXPECT_EQ(M.Files[0].Name, "AA");
751   EXPECT_EQ(M.Files[1].Name, "BB");
752   EXPECT_EQ(M.LastFailure, "AA");
753   EXPECT_EQ(M.FirstNotProcessedFile, 1U);
754 
755   // Parse control file that failed on later attempt
756   EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
757                       "STARTED 0 1000\n"
758                       "FT 0 1 2 3\n"
759                       "STARTED 1 1001\n"
760                       "FT 1 4 5 6 \n"
761                       "STARTED 2 1002\n"
762                       "",
763                       true));
764   ASSERT_EQ(M.Files.size(), 3U);
765   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
766   EXPECT_EQ(M.Files[0].Name, "AA");
767   EXPECT_EQ(M.Files[0].Size, 1000U);
768   EXPECT_EQ(M.Files[1].Name, "BB");
769   EXPECT_EQ(M.Files[1].Size, 1001U);
770   EXPECT_EQ(M.Files[2].Name, "C");
771   EXPECT_EQ(M.Files[2].Size, 1002U);
772   EXPECT_EQ(M.LastFailure, "C");
773   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
774   TRACED_EQ(M.Files[0].Features, {1, 2, 3});
775   TRACED_EQ(M.Files[1].Features, {4, 5, 6});
776 
777   // Parse control file without features or PCs
778   EXPECT_TRUE(M.Parse("2\n0\nAA\nBB\n"
779                       "STARTED 0 1000\n"
780                       "FT 0\n"
781                       "COV 0\n"
782                       "STARTED 1 1001\n"
783                       "FT 1\n"
784                       "COV 1\n"
785                       "",
786                       true));
787   ASSERT_EQ(M.Files.size(), 2U);
788   EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
789   EXPECT_TRUE(M.LastFailure.empty());
790   EXPECT_EQ(M.FirstNotProcessedFile, 2U);
791   EXPECT_TRUE(M.Files[0].Features.empty());
792   EXPECT_TRUE(M.Files[0].Cov.empty());
793   EXPECT_TRUE(M.Files[1].Features.empty());
794   EXPECT_TRUE(M.Files[1].Cov.empty());
795 
796   // Parse features and PCs
797   EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
798                       "STARTED 0 1000\n"
799                       "FT 0 1 2 3\n"
800                       "COV 0 11 12 13\n"
801                       "STARTED 1 1001\n"
802                       "FT 1 4 5 6\n"
803                       "COV 1 7 8 9\n"
804                       "STARTED 2 1002\n"
805                       "FT 2 6 1 3\n"
806                       "COV 2 16 11 13\n"
807                       "",
808                       true));
809   ASSERT_EQ(M.Files.size(), 3U);
810   EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
811   EXPECT_TRUE(M.LastFailure.empty());
812   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
813   TRACED_EQ(M.Files[0].Features, {1, 2, 3});
814   TRACED_EQ(M.Files[0].Cov, {11, 12, 13});
815   TRACED_EQ(M.Files[1].Features, {4, 5, 6});
816   TRACED_EQ(M.Files[1].Cov, {7, 8, 9});
817   TRACED_EQ(M.Files[2].Features, {1, 3, 6});
818   TRACED_EQ(M.Files[2].Cov, {16});
819 }
820 
821 TEST(Merger, Merge) {
822   Merger M;
823   std::set<uint32_t> Features, NewFeatures;
824   std::set<uint32_t> Cov, NewCov;
825   std::vector<std::string> NewFiles;
826 
827   // Adds new files and features
828   EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n"
829                       "STARTED 0 1000\n"
830                       "FT 0 1 2 3\n"
831                       "STARTED 1 1001\n"
832                       "FT 1 4 5 6 \n"
833                       "STARTED 2 1002\n"
834                       "FT 2 6 1 3\n"
835                       "",
836                       true));
837   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 6U);
838   TRACED_EQ(M.Files, {"A", "B", "C"});
839   TRACED_EQ(NewFiles, {"A", "B"});
840   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6});
841 
842   // Doesn't return features or files in the initial corpus.
843   EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
844                       "STARTED 0 1000\n"
845                       "FT 0 1 2 3\n"
846                       "STARTED 1 1001\n"
847                       "FT 1 4 5 6 \n"
848                       "STARTED 2 1002\n"
849                       "FT 2 6 1 3\n"
850                       "",
851                       true));
852   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U);
853   TRACED_EQ(M.Files, {"A", "B", "C"});
854   TRACED_EQ(NewFiles, {"B"});
855   TRACED_EQ(NewFeatures, {4, 5, 6});
856 
857   // No new features, so no new files
858   EXPECT_TRUE(M.Parse("3\n2\nA\nB\nC\n"
859                       "STARTED 0 1000\n"
860                       "FT 0 1 2 3\n"
861                       "STARTED 1 1001\n"
862                       "FT 1 4 5 6 \n"
863                       "STARTED 2 1002\n"
864                       "FT 2 6 1 3\n"
865                       "",
866                       true));
867   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 0U);
868   TRACED_EQ(M.Files, {"A", "B", "C"});
869   TRACED_EQ(NewFiles, {});
870   TRACED_EQ(NewFeatures, {});
871 
872   // Can pass initial features and coverage.
873   Features = {1, 2, 3};
874   Cov = {};
875   EXPECT_TRUE(M.Parse("2\n0\nA\nB\n"
876                       "STARTED 0 1000\n"
877                       "FT 0 1 2 3\n"
878                       "STARTED 1 1001\n"
879                       "FT 1 4 5 6\n"
880                       "",
881                       true));
882   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U);
883   TRACED_EQ(M.Files, {"A", "B"});
884   TRACED_EQ(NewFiles, {"B"});
885   TRACED_EQ(NewFeatures, {4, 5, 6});
886   Features.clear();
887   Cov.clear();
888 
889   // Parse smaller files first
890   EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n"
891                       "STARTED 0 2000\n"
892                       "FT 0 1 2 3\n"
893                       "STARTED 1 1001\n"
894                       "FT 1 4 5 6 \n"
895                       "STARTED 2 1002\n"
896                       "FT 2 6 1 3 \n"
897                       "",
898                       true));
899   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 6U);
900   TRACED_EQ(M.Files, {"B", "C", "A"});
901   TRACED_EQ(NewFiles, {"B", "C", "A"});
902   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6});
903 
904   EXPECT_TRUE(M.Parse("4\n0\nA\nB\nC\nD\n"
905                       "STARTED 0 2000\n"
906                       "FT 0 1 2 3\n"
907                       "STARTED 1 1101\n"
908                       "FT 1 4 5 6 \n"
909                       "STARTED 2 1102\n"
910                       "FT 2 6 1 3 100 \n"
911                       "STARTED 3 1000\n"
912                       "FT 3 1  \n"
913                       "",
914                       true));
915   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 7U);
916   TRACED_EQ(M.Files, {"A", "B", "C", "D"});
917   TRACED_EQ(NewFiles, {"D", "B", "C", "A"});
918   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6, 100});
919 
920   // For same sized file, parse more features first
921   EXPECT_TRUE(M.Parse("4\n1\nA\nB\nC\nD\n"
922                       "STARTED 0 2000\n"
923                       "FT 0 4 5 6 7 8\n"
924                       "STARTED 1 1100\n"
925                       "FT 1 1 2 3 \n"
926                       "STARTED 2 1100\n"
927                       "FT 2 2 3 \n"
928                       "STARTED 3 1000\n"
929                       "FT 3 1  \n"
930                       "",
931                       true));
932   EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U);
933   TRACED_EQ(M.Files, {"A", "B", "C", "D"});
934   TRACED_EQ(NewFiles, {"D", "B"});
935   TRACED_EQ(NewFeatures, {1, 2, 3});
936 }
937 
938 TEST(Merger, SetCoverMerge) {
939   Merger M;
940   std::set<uint32_t> Features, NewFeatures;
941   std::set<uint32_t> Cov, NewCov;
942   std::vector<std::string> NewFiles;
943 
944   // Adds new files and features
945   EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n"
946                       "STARTED 0 1000\n"
947                       "FT 0 1 2 3\n"
948                       "STARTED 1 1001\n"
949                       "FT 1 4 5 6 \n"
950                       "STARTED 2 1002\n"
951                       "FT 2 6 1 3\n"
952                       "",
953                       true));
954   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
955             6U);
956   TRACED_EQ(M.Files, {"A", "B", "C"});
957   TRACED_EQ(NewFiles, {"A", "B"});
958   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6});
959 
960   // Doesn't return features or files in the initial corpus.
961   EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
962                       "STARTED 0 1000\n"
963                       "FT 0 1 2 3\n"
964                       "STARTED 1 1001\n"
965                       "FT 1 4 5 6 \n"
966                       "STARTED 2 1002\n"
967                       "FT 2 6 1 3\n"
968                       "",
969                       true));
970   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
971             3U);
972   TRACED_EQ(M.Files, {"A", "B", "C"});
973   TRACED_EQ(NewFiles, {"B"});
974   TRACED_EQ(NewFeatures, {4, 5, 6});
975 
976   // No new features, so no new files
977   EXPECT_TRUE(M.Parse("3\n2\nA\nB\nC\n"
978                       "STARTED 0 1000\n"
979                       "FT 0 1 2 3\n"
980                       "STARTED 1 1001\n"
981                       "FT 1 4 5 6 \n"
982                       "STARTED 2 1002\n"
983                       "FT 2 6 1 3\n"
984                       "",
985                       true));
986   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
987             0U);
988   TRACED_EQ(M.Files, {"A", "B", "C"});
989   TRACED_EQ(NewFiles, {});
990   TRACED_EQ(NewFeatures, {});
991 
992   // Can pass initial features and coverage.
993   Features = {1, 2, 3};
994   Cov = {};
995   EXPECT_TRUE(M.Parse("2\n0\nA\nB\n"
996                       "STARTED 0 1000\n"
997                       "FT 0 1 2 3\n"
998                       "STARTED 1 1001\n"
999                       "FT 1 4 5 6\n"
1000                       "",
1001                       true));
1002   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
1003             3U);
1004   TRACED_EQ(M.Files, {"A", "B"});
1005   TRACED_EQ(NewFiles, {"B"});
1006   TRACED_EQ(NewFeatures, {4, 5, 6});
1007   Features.clear();
1008   Cov.clear();
1009 
1010   // Prefer files with a lot of features first (C has 4 features)
1011   // Then prefer B over A due to the smaller size. After choosing C and B,
1012   // A and D have no new features to contribute.
1013   EXPECT_TRUE(M.Parse("4\n0\nA\nB\nC\nD\n"
1014                       "STARTED 0 2000\n"
1015                       "FT 0 3 5 6\n"
1016                       "STARTED 1 1000\n"
1017                       "FT 1 4 5 6 \n"
1018                       "STARTED 2 1000\n"
1019                       "FT 2 1 2 3 4 \n"
1020                       "STARTED 3 500\n"
1021                       "FT 3 1  \n"
1022                       "",
1023                       true));
1024   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
1025             6U);
1026   TRACED_EQ(M.Files, {"A", "B", "C", "D"});
1027   TRACED_EQ(NewFiles, {"C", "B"});
1028   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6});
1029 
1030   // Only 1 file covers all features.
1031   EXPECT_TRUE(M.Parse("4\n1\nA\nB\nC\nD\n"
1032                       "STARTED 0 2000\n"
1033                       "FT 0 4 5 6 7 8\n"
1034                       "STARTED 1 1100\n"
1035                       "FT 1 1 2 3 \n"
1036                       "STARTED 2 1100\n"
1037                       "FT 2 2 3 \n"
1038                       "STARTED 3 1000\n"
1039                       "FT 3 1  \n"
1040                       "",
1041                       true));
1042   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
1043             3U);
1044   TRACED_EQ(M.Files, {"A", "B", "C", "D"});
1045   TRACED_EQ(NewFiles, {"B"});
1046   TRACED_EQ(NewFeatures, {1, 2, 3});
1047 
1048   // A Feature has a value greater than (1 << 21) and hence
1049   // there are collisions in the underlying `covered features`
1050   // bitvector.
1051   EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n"
1052                       "STARTED 0 2000\n"
1053                       "FT 0 1 2 3\n"
1054                       "STARTED 1 1000\n"
1055                       "FT 1 3 4 5 \n"
1056                       "STARTED 2 1000\n"
1057                       "FT 2 3 2097153 \n" // Last feature is (2^21 + 1).
1058                       "",
1059                       true));
1060   EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles),
1061             5U);
1062   TRACED_EQ(M.Files, {"A", "B", "C"});
1063   // File 'C' is not added because it's last feature is considered
1064   // covered due to collision with feature 1.
1065   TRACED_EQ(NewFiles, {"B", "A"});
1066   TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5});
1067 }
1068 
1069 #undef TRACED_EQ
1070 
1071 TEST(DFT, BlockCoverage) {
1072   BlockCoverage Cov;
1073   // Assuming C0 has 5 instrumented blocks,
1074   // C1: 7 blocks, C2: 4, C3: 9, C4 never covered, C5: 15,
1075 
1076   // Add C0
1077   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
1078   EXPECT_EQ(Cov.GetCounter(0, 0), 1U);
1079   EXPECT_EQ(Cov.GetCounter(0, 1), 0U);  // not seen this BB yet.
1080   EXPECT_EQ(Cov.GetCounter(0, 5), 0U);  // BB ID out of bounds.
1081   EXPECT_EQ(Cov.GetCounter(1, 0), 0U);  // not seen this function yet.
1082 
1083   EXPECT_EQ(Cov.GetNumberOfBlocks(0), 5U);
1084   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 1U);
1085   EXPECT_EQ(Cov.GetNumberOfBlocks(1), 0U);
1086 
1087   // Various errors.
1088   EXPECT_FALSE(Cov.AppendCoverage("C0\n"));  // No total number.
1089   EXPECT_FALSE(Cov.AppendCoverage("C0 7\n"));  // No total number.
1090   EXPECT_FALSE(Cov.AppendCoverage("CZ\n"));  // Wrong function number.
1091   EXPECT_FALSE(Cov.AppendCoverage("C1 7 7"));  // BB ID is too big.
1092   EXPECT_FALSE(Cov.AppendCoverage("C1 100 7")); // BB ID is too big.
1093 
1094   // Add C0 more times.
1095   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
1096   EXPECT_EQ(Cov.GetCounter(0, 0), 2U);
1097   EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 5\n"));
1098   EXPECT_EQ(Cov.GetCounter(0, 0), 3U);
1099   EXPECT_EQ(Cov.GetCounter(0, 1), 1U);
1100   EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
1101   EXPECT_EQ(Cov.GetCounter(0, 3), 0U);
1102   EXPECT_EQ(Cov.GetCounter(0, 4), 0U);
1103   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 3U);
1104   EXPECT_TRUE(Cov.AppendCoverage("C0 1 3 4 5\n"));
1105   EXPECT_EQ(Cov.GetCounter(0, 0), 4U);
1106   EXPECT_EQ(Cov.GetCounter(0, 1), 2U);
1107   EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
1108   EXPECT_EQ(Cov.GetCounter(0, 3), 1U);
1109   EXPECT_EQ(Cov.GetCounter(0, 4), 1U);
1110   EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 5U);
1111 
1112   EXPECT_TRUE(Cov.AppendCoverage("C1 7\nC2 4\nC3 9\nC5 15\nC0 5\n"));
1113   EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
1114   EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
1115   EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
1116   EXPECT_EQ(Cov.GetCounter(3, 0), 1U);
1117   EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
1118   EXPECT_EQ(Cov.GetCounter(5, 0), 1U);
1119 
1120   EXPECT_TRUE(Cov.AppendCoverage("C3 4 5 9\nC5 11 12 15"));
1121   EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
1122   EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
1123   EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
1124   EXPECT_EQ(Cov.GetCounter(3, 0), 2U);
1125   EXPECT_EQ(Cov.GetCounter(3, 4), 1U);
1126   EXPECT_EQ(Cov.GetCounter(3, 5), 1U);
1127   EXPECT_EQ(Cov.GetCounter(3, 6), 0U);
1128   EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
1129   EXPECT_EQ(Cov.GetCounter(5, 0), 2U);
1130   EXPECT_EQ(Cov.GetCounter(5, 10), 0U);
1131   EXPECT_EQ(Cov.GetCounter(5, 11), 1U);
1132   EXPECT_EQ(Cov.GetCounter(5, 12), 1U);
1133 }
1134 
1135 TEST(DFT, FunctionWeights) {
1136   BlockCoverage Cov;
1137   // unused function gets zero weight.
1138   EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
1139   auto Weights = Cov.FunctionWeights(2);
1140   EXPECT_GT(Weights[0], 0.);
1141   EXPECT_EQ(Weights[1], 0.);
1142 
1143   // Less frequently used function gets less weight.
1144   Cov.clear();
1145   EXPECT_TRUE(Cov.AppendCoverage("C0 5\nC1 5\nC1 5\n"));
1146   Weights = Cov.FunctionWeights(2);
1147   EXPECT_GT(Weights[0], Weights[1]);
1148 
1149   // A function with more uncovered blocks gets more weight.
1150   Cov.clear();
1151   EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n"));
1152   Weights = Cov.FunctionWeights(2);
1153   EXPECT_GT(Weights[1], Weights[0]);
1154 
1155   // A function with DFT gets more weight than the function w/o DFT.
1156   Cov.clear();
1157   EXPECT_TRUE(Cov.AppendCoverage("F1 111\nC0 3\nC1 1 2 3\n"));
1158   Weights = Cov.FunctionWeights(2);
1159   EXPECT_GT(Weights[1], Weights[0]);
1160 }
1161 
1162 
1163 TEST(Fuzzer, ForEachNonZeroByte) {
1164   const size_t N = 64;
1165   alignas(64) uint8_t Ar[N + 8] = {
1166     0, 0, 0, 0, 0, 0, 0, 0,
1167     1, 2, 0, 0, 0, 0, 0, 0,
1168     0, 0, 3, 0, 4, 0, 0, 0,
1169     0, 0, 0, 0, 0, 0, 0, 0,
1170     0, 0, 0, 5, 0, 6, 0, 0,
1171     0, 0, 0, 0, 0, 0, 7, 0,
1172     0, 0, 0, 0, 0, 0, 0, 0,
1173     0, 0, 0, 0, 0, 0, 0, 8,
1174     9, 9, 9, 9, 9, 9, 9, 9,
1175   };
1176   typedef std::vector<std::pair<size_t, uint8_t>> Vec;
1177   Vec Res, Expected;
1178   auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
1179     Res.push_back({FirstFeature + Idx, V});
1180   };
1181   ForEachNonZeroByte(Ar, Ar + N, 100, CB);
1182   Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
1183               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
1184   EXPECT_EQ(Res, Expected);
1185 
1186   Res.clear();
1187   ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
1188   Expected = {          {109, 2}, {118, 3}, {120, 4},
1189               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
1190   EXPECT_EQ(Res, Expected);
1191 
1192   Res.clear();
1193   ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
1194   Expected = {          {109, 2}, {118, 3}, {120, 4},
1195               {135, 5}, {137, 6}, {146, 7}};
1196   EXPECT_EQ(Res, Expected);
1197 }
1198 
1199 // FuzzerCommand unit tests. The arguments in the two helper methods below must
1200 // match.
1201 static void makeCommandArgs(std::vector<std::string> *ArgsToAdd) {
1202   assert(ArgsToAdd);
1203   ArgsToAdd->clear();
1204   ArgsToAdd->push_back("foo");
1205   ArgsToAdd->push_back("-bar=baz");
1206   ArgsToAdd->push_back("qux");
1207   ArgsToAdd->push_back(Command::ignoreRemainingArgs());
1208   ArgsToAdd->push_back("quux");
1209   ArgsToAdd->push_back("-grault=garply");
1210 }
1211 
1212 static std::string makeCmdLine(const char *separator, const char *suffix) {
1213   std::string CmdLine("foo -bar=baz qux ");
1214   if (strlen(separator) != 0) {
1215     CmdLine += separator;
1216     CmdLine += " ";
1217   }
1218   CmdLine += Command::ignoreRemainingArgs();
1219   CmdLine += " quux -grault=garply";
1220   if (strlen(suffix) != 0) {
1221     CmdLine += " ";
1222     CmdLine += suffix;
1223   }
1224   return CmdLine;
1225 }
1226 
1227 TEST(FuzzerCommand, Create) {
1228   std::string CmdLine;
1229 
1230   // Default constructor
1231   Command DefaultCmd;
1232 
1233   CmdLine = DefaultCmd.toString();
1234   EXPECT_EQ(CmdLine, "");
1235 
1236   // Explicit constructor
1237   std::vector<std::string> ArgsToAdd;
1238   makeCommandArgs(&ArgsToAdd);
1239   Command InitializedCmd(ArgsToAdd);
1240 
1241   CmdLine = InitializedCmd.toString();
1242   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1243 
1244   // Compare each argument
1245   auto InitializedArgs = InitializedCmd.getArguments();
1246   auto i = ArgsToAdd.begin();
1247   auto j = InitializedArgs.begin();
1248   while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
1249     EXPECT_EQ(*i++, *j++);
1250   }
1251   EXPECT_EQ(i, ArgsToAdd.end());
1252   EXPECT_EQ(j, InitializedArgs.end());
1253 
1254   // Copy constructor
1255   Command CopiedCmd(InitializedCmd);
1256 
1257   CmdLine = CopiedCmd.toString();
1258   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1259 
1260   // Assignment operator
1261   Command AssignedCmd;
1262   AssignedCmd = CopiedCmd;
1263 
1264   CmdLine = AssignedCmd.toString();
1265   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1266 }
1267 
1268 TEST(FuzzerCommand, ModifyArguments) {
1269   std::vector<std::string> ArgsToAdd;
1270   makeCommandArgs(&ArgsToAdd);
1271   Command Cmd;
1272   std::string CmdLine;
1273 
1274   Cmd.addArguments(ArgsToAdd);
1275   CmdLine = Cmd.toString();
1276   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1277 
1278   Cmd.addArgument("waldo");
1279   EXPECT_TRUE(Cmd.hasArgument("waldo"));
1280 
1281   CmdLine = Cmd.toString();
1282   EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
1283 
1284   Cmd.removeArgument("waldo");
1285   EXPECT_FALSE(Cmd.hasArgument("waldo"));
1286 
1287   CmdLine = Cmd.toString();
1288   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1289 }
1290 
1291 TEST(FuzzerCommand, ModifyFlags) {
1292   std::vector<std::string> ArgsToAdd;
1293   makeCommandArgs(&ArgsToAdd);
1294   Command Cmd(ArgsToAdd);
1295   std::string Value, CmdLine;
1296   ASSERT_FALSE(Cmd.hasFlag("fred"));
1297 
1298   Value = Cmd.getFlagValue("fred");
1299   EXPECT_EQ(Value, "");
1300 
1301   CmdLine = Cmd.toString();
1302   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1303 
1304   Cmd.addFlag("fred", "plugh");
1305   EXPECT_TRUE(Cmd.hasFlag("fred"));
1306 
1307   Value = Cmd.getFlagValue("fred");
1308   EXPECT_EQ(Value, "plugh");
1309 
1310   CmdLine = Cmd.toString();
1311   EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
1312 
1313   Cmd.removeFlag("fred");
1314   EXPECT_FALSE(Cmd.hasFlag("fred"));
1315 
1316   Value = Cmd.getFlagValue("fred");
1317   EXPECT_EQ(Value, "");
1318 
1319   CmdLine = Cmd.toString();
1320   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
1321 }
1322 
1323 TEST(FuzzerCommand, SetOutput) {
1324   std::vector<std::string> ArgsToAdd;
1325   makeCommandArgs(&ArgsToAdd);
1326   Command Cmd(ArgsToAdd);
1327   std::string CmdLine;
1328   ASSERT_FALSE(Cmd.hasOutputFile());
1329   ASSERT_FALSE(Cmd.isOutAndErrCombined());
1330 
1331   Cmd.combineOutAndErr(true);
1332   EXPECT_TRUE(Cmd.isOutAndErrCombined());
1333 
1334   CmdLine = Cmd.toString();
1335   EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
1336 
1337   Cmd.combineOutAndErr(false);
1338   EXPECT_FALSE(Cmd.isOutAndErrCombined());
1339 
1340   Cmd.setOutputFile("xyzzy");
1341   EXPECT_TRUE(Cmd.hasOutputFile());
1342 
1343   CmdLine = Cmd.toString();
1344   EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
1345 
1346   Cmd.setOutputFile("thud");
1347   EXPECT_TRUE(Cmd.hasOutputFile());
1348 
1349   CmdLine = Cmd.toString();
1350   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
1351 
1352   Cmd.combineOutAndErr();
1353   EXPECT_TRUE(Cmd.isOutAndErrCombined());
1354 
1355   CmdLine = Cmd.toString();
1356   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
1357 }
1358 
1359 TEST(Entropic, UpdateFrequency) {
1360   const size_t One = 1, Two = 2;
1361   const size_t FeatIdx1 = 0, FeatIdx2 = 42, FeatIdx3 = 12, FeatIdx4 = 26;
1362   size_t Index;
1363   // Create input corpus with default entropic configuration
1364   struct EntropicOptions Entropic = {true, 0xFF, 100, false};
1365   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
1366   std::unique_ptr<InputInfo> II(new InputInfo());
1367 
1368   C->AddRareFeature(FeatIdx1);
1369   C->UpdateFeatureFrequency(II.get(), FeatIdx1);
1370   EXPECT_EQ(II->FeatureFreqs.size(), One);
1371   C->AddRareFeature(FeatIdx2);
1372   C->UpdateFeatureFrequency(II.get(), FeatIdx1);
1373   C->UpdateFeatureFrequency(II.get(), FeatIdx2);
1374   EXPECT_EQ(II->FeatureFreqs.size(), Two);
1375   EXPECT_EQ(II->FeatureFreqs[0].second, 2);
1376   EXPECT_EQ(II->FeatureFreqs[1].second, 1);
1377 
1378   C->AddRareFeature(FeatIdx3);
1379   C->AddRareFeature(FeatIdx4);
1380   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1381   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1382   C->UpdateFeatureFrequency(II.get(), FeatIdx3);
1383   C->UpdateFeatureFrequency(II.get(), FeatIdx4);
1384 
1385   for (Index = 1; Index < II->FeatureFreqs.size(); Index++)
1386     EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first);
1387 
1388   II->DeleteFeatureFreq(FeatIdx3);
1389   for (Index = 1; Index < II->FeatureFreqs.size(); Index++)
1390     EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first);
1391 }
1392 
1393 double SubAndSquare(double X, double Y) {
1394   double R = X - Y;
1395   R = R * R;
1396   return R;
1397 }
1398 
1399 TEST(Entropic, ComputeEnergy) {
1400   const double Precision = 0.01;
1401   struct EntropicOptions Entropic = {true, 0xFF, 100, false};
1402   std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic));
1403   std::unique_ptr<InputInfo> II(new InputInfo());
1404   std::vector<std::pair<uint32_t, uint16_t>> FeatureFreqs = {
1405       {1, 3}, {2, 3}, {3, 3}};
1406   II->FeatureFreqs = FeatureFreqs;
1407   II->NumExecutedMutations = 0;
1408   II->UpdateEnergy(4, false, std::chrono::microseconds(0));
1409   EXPECT_LT(SubAndSquare(II->Energy, 1.450805), Precision);
1410 
1411   II->NumExecutedMutations = 9;
1412   II->UpdateEnergy(5, false, std::chrono::microseconds(0));
1413   EXPECT_LT(SubAndSquare(II->Energy, 1.525496), Precision);
1414 
1415   II->FeatureFreqs[0].second++;
1416   II->FeatureFreqs.push_back(std::pair<uint32_t, uint16_t>(42, 6));
1417   II->NumExecutedMutations = 20;
1418   II->UpdateEnergy(10, false, std::chrono::microseconds(0));
1419   EXPECT_LT(SubAndSquare(II->Energy, 1.792831), Precision);
1420 }
1421 
1422 int main(int argc, char **argv) {
1423   testing::InitGoogleTest(&argc, argv);
1424   return RUN_ALL_TESTS();
1425 }
1426