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