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