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 #include "FuzzerInternal.h"
9 #include "gtest/gtest.h"
10 #include <memory>
11 #include <set>
12 
13 using namespace fuzzer;
14 
15 // For now, have LLVMFuzzerTestOneInput just to make it link.
16 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)17 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
18   abort();
19 }
20 
TEST(Fuzzer,CrossOver)21 TEST(Fuzzer, CrossOver) {
22   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
23   fuzzer::EF = t.get();
24   Random Rand(0);
25   MutationDispatcher MD(Rand, {});
26   Unit A({0, 1, 2}), B({5, 6, 7});
27   Unit C;
28   Unit Expected[] = {
29        { 0 },
30        { 0, 1 },
31        { 0, 5 },
32        { 0, 1, 2 },
33        { 0, 1, 5 },
34        { 0, 5, 1 },
35        { 0, 5, 6 },
36        { 0, 1, 2, 5 },
37        { 0, 1, 5, 2 },
38        { 0, 1, 5, 6 },
39        { 0, 5, 1, 2 },
40        { 0, 5, 1, 6 },
41        { 0, 5, 6, 1 },
42        { 0, 5, 6, 7 },
43        { 0, 1, 2, 5, 6 },
44        { 0, 1, 5, 2, 6 },
45        { 0, 1, 5, 6, 2 },
46        { 0, 1, 5, 6, 7 },
47        { 0, 5, 1, 2, 6 },
48        { 0, 5, 1, 6, 2 },
49        { 0, 5, 1, 6, 7 },
50        { 0, 5, 6, 1, 2 },
51        { 0, 5, 6, 1, 7 },
52        { 0, 5, 6, 7, 1 },
53        { 0, 1, 2, 5, 6, 7 },
54        { 0, 1, 5, 2, 6, 7 },
55        { 0, 1, 5, 6, 2, 7 },
56        { 0, 1, 5, 6, 7, 2 },
57        { 0, 5, 1, 2, 6, 7 },
58        { 0, 5, 1, 6, 2, 7 },
59        { 0, 5, 1, 6, 7, 2 },
60        { 0, 5, 6, 1, 2, 7 },
61        { 0, 5, 6, 1, 7, 2 },
62        { 0, 5, 6, 7, 1, 2 }
63   };
64   for (size_t Len = 1; Len < 8; Len++) {
65     std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
66     for (int Iter = 0; Iter < 3000; Iter++) {
67       C.resize(Len);
68       size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
69                                     C.data(), C.size());
70       C.resize(NewSize);
71       FoundUnits.insert(C);
72     }
73     for (const Unit &U : Expected)
74       if (U.size() <= Len)
75         ExpectedUnitsWitThisLength.insert(U);
76     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
77   }
78 }
79 
TEST(Fuzzer,Hash)80 TEST(Fuzzer, Hash) {
81   uint8_t A[] = {'a', 'b', 'c'};
82   fuzzer::Unit U(A, A + sizeof(A));
83   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
84   U.push_back('d');
85   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
86 }
87 
88 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
89                                               size_t MaxSize);
90 
TestEraseByte(Mutator M,int NumIter)91 void TestEraseByte(Mutator M, int NumIter) {
92   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
93   fuzzer::EF = t.get();
94   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
95   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
96   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
97   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
98   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
99   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
100   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
101   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
102   Random Rand(0);
103   MutationDispatcher MD(Rand, {});
104   int FoundMask = 0;
105   for (int i = 0; i < NumIter; i++) {
106     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
107     size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
108     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
109     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
110     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
111     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
112     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
113     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
114     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
115     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
116   }
117   EXPECT_EQ(FoundMask, 255);
118 }
119 
TEST(FuzzerMutate,EraseByte1)120 TEST(FuzzerMutate, EraseByte1) {
121   TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100);
122 }
TEST(FuzzerMutate,EraseByte2)123 TEST(FuzzerMutate, EraseByte2) {
124   TestEraseByte(&MutationDispatcher::Mutate, 1000);
125 }
126 
TestInsertByte(Mutator M,int NumIter)127 void TestInsertByte(Mutator M, int NumIter) {
128   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
129   fuzzer::EF = t.get();
130   Random Rand(0);
131   MutationDispatcher MD(Rand, {});
132   int FoundMask = 0;
133   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
134   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
135   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
136   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
137   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
138   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
139   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
140   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
141   for (int i = 0; i < NumIter; i++) {
142     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
143     size_t NewSize = (MD.*M)(T, 7, 8);
144     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
145     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
146     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
147     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
148     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
149     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
150     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
151     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
152   }
153   EXPECT_EQ(FoundMask, 255);
154 }
155 
TEST(FuzzerMutate,InsertByte1)156 TEST(FuzzerMutate, InsertByte1) {
157   TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
158 }
TEST(FuzzerMutate,InsertByte2)159 TEST(FuzzerMutate, InsertByte2) {
160   TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
161 }
162 
TestChangeByte(Mutator M,int NumIter)163 void TestChangeByte(Mutator M, int NumIter) {
164   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
165   fuzzer::EF = t.get();
166   Random Rand(0);
167   MutationDispatcher MD(Rand, {});
168   int FoundMask = 0;
169   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
170   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
171   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
172   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
173   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
174   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
175   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
176   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
177   for (int i = 0; i < NumIter; i++) {
178     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
179     size_t NewSize = (MD.*M)(T, 8, 9);
180     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
181     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
182     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
183     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
184     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
185     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
186     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
187     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
188   }
189   EXPECT_EQ(FoundMask, 255);
190 }
191 
TEST(FuzzerMutate,ChangeByte1)192 TEST(FuzzerMutate, ChangeByte1) {
193   TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
194 }
TEST(FuzzerMutate,ChangeByte2)195 TEST(FuzzerMutate, ChangeByte2) {
196   TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
197 }
198 
TestChangeBit(Mutator M,int NumIter)199 void TestChangeBit(Mutator M, int NumIter) {
200   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
201   fuzzer::EF = t.get();
202   Random Rand(0);
203   MutationDispatcher MD(Rand, {});
204   int FoundMask = 0;
205   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
206   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
207   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
208   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
209   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
210   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
211   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
212   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
213   for (int i = 0; i < NumIter; i++) {
214     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
215     size_t NewSize = (MD.*M)(T, 8, 9);
216     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
217     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
218     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
219     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
220     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
221     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
222     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
223     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
224   }
225   EXPECT_EQ(FoundMask, 255);
226 }
227 
TEST(FuzzerMutate,ChangeBit1)228 TEST(FuzzerMutate, ChangeBit1) {
229   TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
230 }
TEST(FuzzerMutate,ChangeBit2)231 TEST(FuzzerMutate, ChangeBit2) {
232   TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
233 }
234 
TestShuffleBytes(Mutator M,int NumIter)235 void TestShuffleBytes(Mutator M, int NumIter) {
236   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
237   fuzzer::EF = t.get();
238   Random Rand(0);
239   MutationDispatcher MD(Rand, {});
240   int FoundMask = 0;
241   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
242   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
243   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
244   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
245   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
246   for (int i = 0; i < NumIter; i++) {
247     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
248     size_t NewSize = (MD.*M)(T, 7, 7);
249     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
250     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
251     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
252     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
253     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
254   }
255   EXPECT_EQ(FoundMask, 31);
256 }
257 
TEST(FuzzerMutate,ShuffleBytes1)258 TEST(FuzzerMutate, ShuffleBytes1) {
259   TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);
260 }
TEST(FuzzerMutate,ShuffleBytes2)261 TEST(FuzzerMutate, ShuffleBytes2) {
262   TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
263 }
264 
TestAddWordFromDictionary(Mutator M,int NumIter)265 void TestAddWordFromDictionary(Mutator M, int NumIter) {
266   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
267   fuzzer::EF = t.get();
268   Random Rand(0);
269   MutationDispatcher MD(Rand, {});
270   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
271   uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
272   MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
273   MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
274   int FoundMask = 0;
275   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
276   uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
277   uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
278   uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
279   uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
280   uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
281   uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
282   uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
283   for (int i = 0; i < NumIter; i++) {
284     uint8_t T[7] = {0x00, 0x11, 0x22};
285     size_t NewSize = (MD.*M)(T, 3, 7);
286     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
287     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
288     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
289     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
290     if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
291     if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
292     if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
293     if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
294   }
295   EXPECT_EQ(FoundMask, 255);
296 }
297 
TEST(FuzzerMutate,AddWordFromDictionary1)298 TEST(FuzzerMutate, AddWordFromDictionary1) {
299   TestAddWordFromDictionary(
300       &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
301 }
302 
TEST(FuzzerMutate,AddWordFromDictionary2)303 TEST(FuzzerMutate, AddWordFromDictionary2) {
304   TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
305 }
306 
TestAddWordFromDictionaryWithHint(Mutator M,int NumIter)307 void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
308   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
309   fuzzer::EF = t.get();
310   Random Rand(0);
311   MutationDispatcher MD(Rand, {});
312   uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
313   size_t PosHint = 7777;
314   MD.AddWordToAutoDictionary(Word(W, sizeof(W)), PosHint);
315   int FoundMask = 0;
316   for (int i = 0; i < NumIter; i++) {
317     uint8_t T[10000];
318     memset(T, 0, sizeof(T));
319     size_t NewSize = (MD.*M)(T, 9000, 10000);
320     if (NewSize >= PosHint + sizeof(W) &&
321         !memcmp(W, T + PosHint, sizeof(W)))
322       FoundMask = 1;
323   }
324   EXPECT_EQ(FoundMask, 1);
325 }
326 
TEST(FuzzerMutate,AddWordFromDictionaryWithHint1)327 TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {
328   TestAddWordFromDictionaryWithHint(
329       &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5);
330 }
331 
TEST(FuzzerMutate,AddWordFromDictionaryWithHint2)332 TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {
333   TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10);
334 }
335 
TestChangeASCIIInteger(Mutator M,int NumIter)336 void TestChangeASCIIInteger(Mutator M, int NumIter) {
337   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
338   fuzzer::EF = t.get();
339   Random Rand(0);
340   MutationDispatcher MD(Rand, {});
341 
342   uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
343   uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
344   uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
345   uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
346   int FoundMask = 0;
347   for (int i = 0; i < NumIter; i++) {
348     uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
349     size_t NewSize = (MD.*M)(T, 8, 8);
350     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
351     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
352     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
353     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
354     else if (NewSize == 8)                       FoundMask |= 1 << 4;
355   }
356   EXPECT_EQ(FoundMask, 31);
357 }
358 
TEST(FuzzerMutate,ChangeASCIIInteger1)359 TEST(FuzzerMutate, ChangeASCIIInteger1) {
360   TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
361                          1 << 15);
362 }
363 
TEST(FuzzerMutate,ChangeASCIIInteger2)364 TEST(FuzzerMutate, ChangeASCIIInteger2) {
365   TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
366 }
367 
368 
TEST(FuzzerDictionary,ParseOneDictionaryEntry)369 TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
370   Unit U;
371   EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
372   EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
373   EXPECT_FALSE(ParseOneDictionaryEntry("\t  ", &U));
374   EXPECT_FALSE(ParseOneDictionaryEntry("  \" ", &U));
375   EXPECT_FALSE(ParseOneDictionaryEntry("  zz\" ", &U));
376   EXPECT_FALSE(ParseOneDictionaryEntry("  \"zz ", &U));
377   EXPECT_FALSE(ParseOneDictionaryEntry("  \"\" ", &U));
378   EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
379   EXPECT_EQ(U, Unit({'a'}));
380   EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
381   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
382   EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
383   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
384   EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
385   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
386   EXPECT_EQ(U, Unit({'\\'}));
387   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
388   EXPECT_EQ(U, Unit({0xAB}));
389   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
390   EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
391   EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
392   EXPECT_EQ(U, Unit({'#'}));
393   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
394   EXPECT_EQ(U, Unit({'"'}));
395 }
396 
TEST(FuzzerDictionary,ParseDictionaryFile)397 TEST(FuzzerDictionary, ParseDictionaryFile) {
398   std::vector<Unit> Units;
399   EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
400   EXPECT_FALSE(ParseDictionaryFile("", &Units));
401   EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
402   EXPECT_EQ(Units.size(), 0U);
403   EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
404   EXPECT_EQ(Units.size(), 0U);
405   EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
406   EXPECT_EQ(Units.size(), 0U);
407   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\n", &Units));
408   EXPECT_EQ(Units.size(), 0U);
409   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\naaa=\"aa\"", &Units));
410   EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
411   EXPECT_TRUE(
412       ParseDictionaryFile("  #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
413   EXPECT_EQ(Units,
414             std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
415 }
416 
TEST(FuzzerUtil,Base64)417 TEST(FuzzerUtil, Base64) {
418   EXPECT_EQ("", Base64({}));
419   EXPECT_EQ("YQ==", Base64({'a'}));
420   EXPECT_EQ("eA==", Base64({'x'}));
421   EXPECT_EQ("YWI=", Base64({'a', 'b'}));
422   EXPECT_EQ("eHk=", Base64({'x', 'y'}));
423   EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
424   EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
425   EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
426   EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
427   EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
428 }
429 
TEST(Corpus,Distribution)430 TEST(Corpus, Distribution) {
431   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
432   fuzzer::EF = t.get();
433   Random Rand(0);
434   MutationDispatcher MD(Rand, {});
435   Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {});
436   size_t N = 10;
437   size_t TriesPerUnit = 1<<20;
438   for (size_t i = 0; i < N; i++) {
439     Fuzz.AddToCorpus(Unit{ static_cast<uint8_t>(i) });
440   }
441   std::vector<size_t> Hist(N);
442   for (size_t i = 0; i < N * TriesPerUnit; i++) {
443     Hist[Fuzz.ChooseUnitIdxToMutate()]++;
444   }
445   for (size_t i = 0; i < N; i++) {
446     // A weak sanity check that every unit gets invoked.
447     EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
448   }
449 }
450