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