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