blob: e3b06702603d076d56ef3a2aa6ccf597919d7739 [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++)
kcc0cab3f02018-07-19 01:23:32 +0000591 C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, 1, false, false, {}, DFT,
592 nullptr);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000593
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000594 Vector<size_t> Hist(N);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000595 for (size_t i = 0; i < N * TriesPerUnit; i++) {
596 Hist[C->ChooseUnitIdxToMutate(Rand)]++;
597 }
598 for (size_t i = 0; i < N; i++) {
599 // A weak sanity check that every unit gets invoked.
600 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
601 }
602}
603
604TEST(Merge, Bad) {
605 const char *kInvalidInputs[] = {
606 "",
607 "x",
608 "3\nx",
609 "2\n3",
610 "2\n2",
611 "2\n2\nA\n",
612 "2\n2\nA\nB\nC\n",
613 "0\n0\n",
614 "1\n1\nA\nDONE 0",
615 "1\n1\nA\nSTARTED 1",
616 };
617 Merger M;
618 for (auto S : kInvalidInputs) {
619 // fprintf(stderr, "TESTING:\n%s\n", S);
620 EXPECT_FALSE(M.Parse(S, false));
621 }
622}
623
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000624void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
george.karpenkov29efa6d2017-08-21 23:25:50 +0000625 EXPECT_EQ(A, B);
626}
627
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000628void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
629 Set<std::string> a(A.begin(), A.end());
630 Set<std::string> b(B.begin(), B.end());
george.karpenkov29efa6d2017-08-21 23:25:50 +0000631 EXPECT_EQ(a, b);
632}
633
634static void Merge(const std::string &Input,
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000635 const Vector<std::string> Result,
george.karpenkov29efa6d2017-08-21 23:25:50 +0000636 size_t NumNewFeatures) {
637 Merger M;
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000638 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000639 EXPECT_TRUE(M.Parse(Input, true));
640 std::stringstream SS;
641 M.PrintSummary(SS);
642 EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
643 EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
644 EQ(NewFiles, Result);
645}
646
647TEST(Merge, Good) {
648 Merger M;
649
650 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
651 EXPECT_EQ(M.Files.size(), 1U);
652 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
653 EXPECT_EQ(M.Files[0].Name, "AA");
654 EXPECT_TRUE(M.LastFailure.empty());
655 EXPECT_EQ(M.FirstNotProcessedFile, 0U);
656
657 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
658 EXPECT_EQ(M.Files.size(), 2U);
659 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
660 EXPECT_EQ(M.Files[0].Name, "AA");
661 EXPECT_EQ(M.Files[1].Name, "BB");
662 EXPECT_EQ(M.LastFailure, "AA");
663 EXPECT_EQ(M.FirstNotProcessedFile, 1U);
664
665 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
666 "STARTED 0 1000\n"
667 "DONE 0 1 2 3\n"
668 "STARTED 1 1001\n"
669 "DONE 1 4 5 6 \n"
670 "STARTED 2 1002\n"
671 "", true));
672 EXPECT_EQ(M.Files.size(), 3U);
673 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
674 EXPECT_EQ(M.Files[0].Name, "AA");
675 EXPECT_EQ(M.Files[0].Size, 1000U);
676 EXPECT_EQ(M.Files[1].Name, "BB");
677 EXPECT_EQ(M.Files[1].Size, 1001U);
678 EXPECT_EQ(M.Files[2].Name, "C");
679 EXPECT_EQ(M.Files[2].Size, 1002U);
680 EXPECT_EQ(M.LastFailure, "C");
681 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
682 EQ(M.Files[0].Features, {1, 2, 3});
683 EQ(M.Files[1].Features, {4, 5, 6});
684
685
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000686 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000687
688 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
689 "STARTED 0 1000\nDONE 0 1 2 3\n"
690 "STARTED 1 1001\nDONE 1 4 5 6 \n"
691 "STARTED 2 1002\nDONE 2 6 1 3 \n"
692 "", true));
693 EXPECT_EQ(M.Files.size(), 3U);
694 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
695 EXPECT_TRUE(M.LastFailure.empty());
696 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
697 EQ(M.Files[0].Features, {1, 2, 3});
698 EQ(M.Files[1].Features, {4, 5, 6});
699 EQ(M.Files[2].Features, {1, 3, 6});
700 EXPECT_EQ(0U, M.Merge(&NewFiles));
701 EQ(NewFiles, {});
702
703 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
704 "STARTED 0 1000\nDONE 0 1 2 3\n"
705 "STARTED 1 1001\nDONE 1 4 5 6 \n"
706 "STARTED 2 1002\nDONE 2 6 1 3\n"
707 "", true));
708 EQ(M.Files[0].Features, {1, 2, 3});
709 EQ(M.Files[1].Features, {4, 5, 6});
710 EQ(M.Files[2].Features, {1, 3, 6});
711 EXPECT_EQ(3U, M.Merge(&NewFiles));
712 EQ(NewFiles, {"B"});
713
714 // Same as the above, but with InitialFeatures.
715 EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
716 "STARTED 0 1001\nDONE 0 4 5 6 \n"
717 "STARTED 1 1002\nDONE 1 6 1 3\n"
718 "", true));
719 EQ(M.Files[0].Features, {4, 5, 6});
720 EQ(M.Files[1].Features, {1, 3, 6});
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000721 Set<uint32_t> InitialFeatures;
722 InitialFeatures.insert(1);
723 InitialFeatures.insert(2);
724 InitialFeatures.insert(3);
725 EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFiles));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000726 EQ(NewFiles, {"B"});
727}
728
729TEST(Merge, Merge) {
730
731 Merge("3\n1\nA\nB\nC\n"
732 "STARTED 0 1000\nDONE 0 1 2 3\n"
733 "STARTED 1 1001\nDONE 1 4 5 6 \n"
734 "STARTED 2 1002\nDONE 2 6 1 3 \n",
735 {"B"}, 3);
736
737 Merge("3\n0\nA\nB\nC\n"
738 "STARTED 0 2000\nDONE 0 1 2 3\n"
739 "STARTED 1 1001\nDONE 1 4 5 6 \n"
740 "STARTED 2 1002\nDONE 2 6 1 3 \n",
741 {"A", "B", "C"}, 6);
742
743 Merge("4\n0\nA\nB\nC\nD\n"
744 "STARTED 0 2000\nDONE 0 1 2 3\n"
745 "STARTED 1 1101\nDONE 1 4 5 6 \n"
746 "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
747 "STARTED 3 1000\nDONE 3 1 \n",
748 {"A", "B", "C", "D"}, 7);
749
750 Merge("4\n1\nA\nB\nC\nD\n"
751 "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
752 "STARTED 1 1100\nDONE 1 1 2 3 \n"
753 "STARTED 2 1100\nDONE 2 2 3 \n"
754 "STARTED 3 1000\nDONE 3 1 \n",
755 {"B", "D"}, 3);
756}
757
758TEST(Fuzzer, ForEachNonZeroByte) {
759 const size_t N = 64;
760 alignas(64) uint8_t Ar[N + 8] = {
761 0, 0, 0, 0, 0, 0, 0, 0,
762 1, 2, 0, 0, 0, 0, 0, 0,
763 0, 0, 3, 0, 4, 0, 0, 0,
764 0, 0, 0, 0, 0, 0, 0, 0,
765 0, 0, 0, 5, 0, 6, 0, 0,
766 0, 0, 0, 0, 0, 0, 7, 0,
767 0, 0, 0, 0, 0, 0, 0, 0,
768 0, 0, 0, 0, 0, 0, 0, 8,
769 9, 9, 9, 9, 9, 9, 9, 9,
770 };
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000771 typedef Vector<std::pair<size_t, uint8_t> > Vec;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000772 Vec Res, Expected;
773 auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
774 Res.push_back({FirstFeature + Idx, V});
775 };
776 ForEachNonZeroByte(Ar, Ar + N, 100, CB);
777 Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
778 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
779 EXPECT_EQ(Res, Expected);
780
781 Res.clear();
782 ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
783 Expected = { {109, 2}, {118, 3}, {120, 4},
784 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
785 EXPECT_EQ(Res, Expected);
786
787 Res.clear();
788 ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
789 Expected = { {109, 2}, {118, 3}, {120, 4},
790 {135, 5}, {137, 6}, {146, 7}};
791 EXPECT_EQ(Res, Expected);
792}
793
morehousea80f6452017-12-04 19:25:59 +0000794// FuzzerCommand unit tests. The arguments in the two helper methods below must
795// match.
796static void makeCommandArgs(Vector<std::string> *ArgsToAdd) {
797 assert(ArgsToAdd);
798 ArgsToAdd->clear();
799 ArgsToAdd->push_back("foo");
800 ArgsToAdd->push_back("-bar=baz");
801 ArgsToAdd->push_back("qux");
802 ArgsToAdd->push_back(Command::ignoreRemainingArgs());
803 ArgsToAdd->push_back("quux");
804 ArgsToAdd->push_back("-grault=garply");
805}
806
807static std::string makeCmdLine(const char *separator, const char *suffix) {
808 std::string CmdLine("foo -bar=baz qux ");
809 if (strlen(separator) != 0) {
810 CmdLine += separator;
811 CmdLine += " ";
812 }
813 CmdLine += Command::ignoreRemainingArgs();
814 CmdLine += " quux -grault=garply";
815 if (strlen(suffix) != 0) {
816 CmdLine += " ";
817 CmdLine += suffix;
818 }
819 return CmdLine;
820}
821
822TEST(FuzzerCommand, Create) {
823 std::string CmdLine;
824
825 // Default constructor
826 Command DefaultCmd;
827
828 CmdLine = DefaultCmd.toString();
829 EXPECT_EQ(CmdLine, "");
830
831 // Explicit constructor
832 Vector<std::string> ArgsToAdd;
833 makeCommandArgs(&ArgsToAdd);
834 Command InitializedCmd(ArgsToAdd);
835
836 CmdLine = InitializedCmd.toString();
837 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
838
839 // Compare each argument
840 auto InitializedArgs = InitializedCmd.getArguments();
841 auto i = ArgsToAdd.begin();
842 auto j = InitializedArgs.begin();
843 while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
844 EXPECT_EQ(*i++, *j++);
845 }
846 EXPECT_EQ(i, ArgsToAdd.end());
847 EXPECT_EQ(j, InitializedArgs.end());
848
849 // Copy constructor
850 Command CopiedCmd(InitializedCmd);
851
852 CmdLine = CopiedCmd.toString();
853 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
854
855 // Assignment operator
856 Command AssignedCmd;
857 AssignedCmd = CopiedCmd;
858
859 CmdLine = AssignedCmd.toString();
860 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
861}
862
863TEST(FuzzerCommand, ModifyArguments) {
864 Vector<std::string> ArgsToAdd;
865 makeCommandArgs(&ArgsToAdd);
866 Command Cmd;
867 std::string CmdLine;
868
869 Cmd.addArguments(ArgsToAdd);
870 CmdLine = Cmd.toString();
871 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
872
873 Cmd.addArgument("waldo");
874 EXPECT_TRUE(Cmd.hasArgument("waldo"));
875
876 CmdLine = Cmd.toString();
877 EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
878
879 Cmd.removeArgument("waldo");
880 EXPECT_FALSE(Cmd.hasArgument("waldo"));
881
882 CmdLine = Cmd.toString();
883 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
884}
885
886TEST(FuzzerCommand, ModifyFlags) {
887 Vector<std::string> ArgsToAdd;
888 makeCommandArgs(&ArgsToAdd);
889 Command Cmd(ArgsToAdd);
890 std::string Value, CmdLine;
891 ASSERT_FALSE(Cmd.hasFlag("fred"));
892
893 Value = Cmd.getFlagValue("fred");
894 EXPECT_EQ(Value, "");
895
896 CmdLine = Cmd.toString();
897 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
898
899 Cmd.addFlag("fred", "plugh");
900 EXPECT_TRUE(Cmd.hasFlag("fred"));
901
902 Value = Cmd.getFlagValue("fred");
903 EXPECT_EQ(Value, "plugh");
904
905 CmdLine = Cmd.toString();
906 EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
907
908 Cmd.removeFlag("fred");
909 EXPECT_FALSE(Cmd.hasFlag("fred"));
910
911 Value = Cmd.getFlagValue("fred");
912 EXPECT_EQ(Value, "");
913
914 CmdLine = Cmd.toString();
915 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
916}
917
918TEST(FuzzerCommand, SetOutput) {
919 Vector<std::string> ArgsToAdd;
920 makeCommandArgs(&ArgsToAdd);
921 Command Cmd(ArgsToAdd);
922 std::string CmdLine;
923 ASSERT_FALSE(Cmd.hasOutputFile());
924 ASSERT_FALSE(Cmd.isOutAndErrCombined());
925
926 Cmd.combineOutAndErr(true);
927 EXPECT_TRUE(Cmd.isOutAndErrCombined());
928
929 CmdLine = Cmd.toString();
930 EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
931
932 Cmd.combineOutAndErr(false);
933 EXPECT_FALSE(Cmd.isOutAndErrCombined());
934
935 Cmd.setOutputFile("xyzzy");
936 EXPECT_TRUE(Cmd.hasOutputFile());
937
938 CmdLine = Cmd.toString();
939 EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
940
941 Cmd.setOutputFile("thud");
942 EXPECT_TRUE(Cmd.hasOutputFile());
943
944 CmdLine = Cmd.toString();
945 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
946
947 Cmd.combineOutAndErr();
948 EXPECT_TRUE(Cmd.isOutAndErrCombined());
949
950 CmdLine = Cmd.toString();
morehouse2e96d0e2017-12-05 17:13:17 +0000951 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
morehousea80f6452017-12-04 19:25:59 +0000952}
953
george.karpenkov29efa6d2017-08-21 23:25:50 +0000954int main(int argc, char **argv) {
955 testing::InitGoogleTest(&argc, argv);
956 return RUN_ALL_TESTS();
957}