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