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