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