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
24using 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.
29extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
30  abort();
31}
32
33TEST(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
48TEST(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
107TEST(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
115typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
116                                              size_t MaxSize);
117
118void 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
165TEST(FuzzerMutate, EraseBytes1) {
166  TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
167}
168TEST(FuzzerMutate, EraseBytes2) {
169  TestEraseBytes(&MutationDispatcher::Mutate, 2000);
170}
171
172void 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
201TEST(FuzzerMutate, InsertByte1) {
202  TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
203}
204TEST(FuzzerMutate, InsertByte2) {
205  TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
206}
207
208void 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
245TEST(FuzzerMutate, InsertRepeatedBytes1) {
246  TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes,
247                          10000);
248}
249TEST(FuzzerMutate, InsertRepeatedBytes2) {
250  TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
251}
252
253void 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
282TEST(FuzzerMutate, ChangeByte1) {
283  TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
284}
285TEST(FuzzerMutate, ChangeByte2) {
286  TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
287}
288
289void 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
318TEST(FuzzerMutate, ChangeBit1) {
319  TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
320}
321TEST(FuzzerMutate, ChangeBit2) {
322  TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
323}
324
325void 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
348TEST(FuzzerMutate, ShuffleBytes1) {
349  TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
350}
351TEST(FuzzerMutate, ShuffleBytes2) {
352  TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
353}
354
355void 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
396TEST(FuzzerMutate, CopyPart1) {
397  TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
398}
399TEST(FuzzerMutate, CopyPart2) {
400  TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
401}
402TEST(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
418void 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
451TEST(FuzzerMutate, AddWordFromDictionary1) {
452  TestAddWordFromDictionary(
453      &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
454}
455
456TEST(FuzzerMutate, AddWordFromDictionary2) {
457  TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
458}
459
460void 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
483TEST(FuzzerMutate, ChangeASCIIInteger1) {
484  TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
485                         1 << 15);
486}
487
488TEST(FuzzerMutate, ChangeASCIIInteger2) {
489  TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
490}
491
492void 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
523TEST(FuzzerMutate, ChangeBinaryInteger1) {
524  TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
525                         1 << 12);
526}
527
528TEST(FuzzerMutate, ChangeBinaryInteger2) {
529  TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
530}
531
532
533TEST(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
561TEST(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
581TEST(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__
595class PrintfCapture {
596 public:
597  PrintfCapture() {
598    OldOutputFile = GetOutputFile();
599    SetOutputFile(open_memstream(&Buffer, &Size));
600  }
601  ~PrintfCapture() {
602    fclose(GetOutputFile());
603    SetOutputFile(OldOutputFile);
604    free(Buffer);
605  }
606  std::string str() { return std::string(Buffer, Size); }
607
608 private:
609  char *Buffer;
610  size_t Size;
611  FILE *OldOutputFile;
612};
613
614TEST(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
630TEST(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
655TEST(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
694template <typename T>
695void EQ(const std::vector<T> &A, const std::vector<T> &B) {
696  EXPECT_EQ(A, B);
697}
698
699template <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
703void 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
718TEST(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
826TEST(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
943TEST(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
1076TEST(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
1140TEST(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
1168TEST(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.
1206static 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
1217static 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
1232TEST(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
1273TEST(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
1296TEST(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
1328TEST(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
1364TEST(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
1398double SubAndSquare(double X, double Y) {
1399  double R = X - Y;
1400  R = R * R;
1401  return R;
1402}
1403
1404TEST(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
1427int main(int argc, char **argv) {
1428  testing::InitGoogleTest(&argc, argv);
1429  return RUN_ALL_TESTS();
1430}
1431