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