blob: 7cdd44582329e4017feda50762933718e3f6d3ee [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/"), "");
morehouse68f46432018-08-30 15:54:44 +000037#if LIBFUZZER_WINDOWS
38 EXPECT_EQ(Basename("foo\\bar"), "bar");
39 EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
40 EXPECT_EQ(Basename("\\bar"), "bar");
41 EXPECT_EQ(Basename("foo\\x"), "x");
42 EXPECT_EQ(Basename("foo\\"), "");
43#endif
kcc86e43882018-06-06 01:23:29 +000044}
45
george.karpenkov29efa6d2017-08-21 23:25:50 +000046TEST(Fuzzer, CrossOver) {
47 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
48 fuzzer::EF = t.get();
49 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +000050 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +000051 Unit A({0, 1, 2}), B({5, 6, 7});
52 Unit C;
53 Unit Expected[] = {
54 { 0 },
55 { 0, 1 },
56 { 0, 5 },
57 { 0, 1, 2 },
58 { 0, 1, 5 },
59 { 0, 5, 1 },
60 { 0, 5, 6 },
61 { 0, 1, 2, 5 },
62 { 0, 1, 5, 2 },
63 { 0, 1, 5, 6 },
64 { 0, 5, 1, 2 },
65 { 0, 5, 1, 6 },
66 { 0, 5, 6, 1 },
67 { 0, 5, 6, 7 },
68 { 0, 1, 2, 5, 6 },
69 { 0, 1, 5, 2, 6 },
70 { 0, 1, 5, 6, 2 },
71 { 0, 1, 5, 6, 7 },
72 { 0, 5, 1, 2, 6 },
73 { 0, 5, 1, 6, 2 },
74 { 0, 5, 1, 6, 7 },
75 { 0, 5, 6, 1, 2 },
76 { 0, 5, 6, 1, 7 },
77 { 0, 5, 6, 7, 1 },
78 { 0, 1, 2, 5, 6, 7 },
79 { 0, 1, 5, 2, 6, 7 },
80 { 0, 1, 5, 6, 2, 7 },
81 { 0, 1, 5, 6, 7, 2 },
82 { 0, 5, 1, 2, 6, 7 },
83 { 0, 5, 1, 6, 2, 7 },
84 { 0, 5, 1, 6, 7, 2 },
85 { 0, 5, 6, 1, 2, 7 },
86 { 0, 5, 6, 1, 7, 2 },
87 { 0, 5, 6, 7, 1, 2 }
88 };
89 for (size_t Len = 1; Len < 8; Len++) {
george.karpenkovfbfa45c2017-08-27 23:20:09 +000090 Set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
george.karpenkov29efa6d2017-08-21 23:25:50 +000091 for (int Iter = 0; Iter < 3000; Iter++) {
92 C.resize(Len);
kccbfe84102017-12-06 23:35:02 +000093 size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
94 C.data(), C.size());
george.karpenkov29efa6d2017-08-21 23:25:50 +000095 C.resize(NewSize);
96 FoundUnits.insert(C);
97 }
98 for (const Unit &U : Expected)
99 if (U.size() <= Len)
100 ExpectedUnitsWitThisLength.insert(U);
101 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
102 }
103}
104
105TEST(Fuzzer, Hash) {
106 uint8_t A[] = {'a', 'b', 'c'};
107 fuzzer::Unit U(A, A + sizeof(A));
108 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
109 U.push_back('d');
110 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
111}
112
113typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
114 size_t MaxSize);
115
116void TestEraseBytes(Mutator M, int NumIter) {
117 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
118 fuzzer::EF = t.get();
119 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
120 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
121 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
122 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
123 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
124 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
125 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
126 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
127
128 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
129 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
130 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
131
132 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
133 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
134 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
135
136
137 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000138 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000139 int FoundMask = 0;
140 for (int i = 0; i < NumIter; i++) {
141 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000142 size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000143 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
144 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
145 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
146 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
147 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
148 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
149 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
150 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
151
152 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
153 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
154 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
155
156 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
157 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
158 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
159 }
160 EXPECT_EQ(FoundMask, (1 << 14) - 1);
161}
162
163TEST(FuzzerMutate, EraseBytes1) {
164 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
165}
166TEST(FuzzerMutate, EraseBytes2) {
167 TestEraseBytes(&MutationDispatcher::Mutate, 2000);
168}
169
170void TestInsertByte(Mutator M, int NumIter) {
171 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
172 fuzzer::EF = t.get();
173 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000174 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000175 int FoundMask = 0;
176 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
177 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
178 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
179 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
180 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
181 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
182 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
183 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
184 for (int i = 0; i < NumIter; i++) {
185 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000186 size_t NewSize = (*MD.*M)(T, 7, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000187 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
188 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
189 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
190 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
191 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
192 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
193 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
194 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
195 }
196 EXPECT_EQ(FoundMask, 255);
197}
198
199TEST(FuzzerMutate, InsertByte1) {
200 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
201}
202TEST(FuzzerMutate, InsertByte2) {
203 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
204}
205
206void TestInsertRepeatedBytes(Mutator M, int NumIter) {
207 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
208 fuzzer::EF = t.get();
209 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000210 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000211 int FoundMask = 0;
212 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
213 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
214 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
215 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
216 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
217
218 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
219 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
220 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
221 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
222 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
223
224 for (int i = 0; i < NumIter; i++) {
225 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
kccbfe84102017-12-06 23:35:02 +0000226 size_t NewSize = (*MD.*M)(T, 4, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000227 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
228 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
229 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
230 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
231 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
232
233 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
234 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
235 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
236 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
237 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
238
239 }
240 EXPECT_EQ(FoundMask, (1 << 10) - 1);
241}
242
243TEST(FuzzerMutate, InsertRepeatedBytes1) {
244 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
245}
246TEST(FuzzerMutate, InsertRepeatedBytes2) {
247 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
248}
249
250void TestChangeByte(Mutator M, int NumIter) {
251 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
252 fuzzer::EF = t.get();
253 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000254 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000255 int FoundMask = 0;
256 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
257 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
258 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
259 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
260 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
261 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
262 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
263 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
264 for (int i = 0; i < NumIter; i++) {
265 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000266 size_t NewSize = (*MD.*M)(T, 8, 9);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000267 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
268 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
269 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
270 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
271 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
272 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
273 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
274 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
275 }
276 EXPECT_EQ(FoundMask, 255);
277}
278
279TEST(FuzzerMutate, ChangeByte1) {
280 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
281}
282TEST(FuzzerMutate, ChangeByte2) {
283 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
284}
285
286void TestChangeBit(Mutator M, int NumIter) {
287 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
288 fuzzer::EF = t.get();
289 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000290 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000291 int FoundMask = 0;
292 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
293 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
294 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
295 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
296 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
297 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
298 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
299 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
300 for (int i = 0; i < NumIter; i++) {
301 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000302 size_t NewSize = (*MD.*M)(T, 8, 9);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000303 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
304 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
305 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
306 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
307 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
308 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
309 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
310 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
311 }
312 EXPECT_EQ(FoundMask, 255);
313}
314
315TEST(FuzzerMutate, ChangeBit1) {
316 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
317}
318TEST(FuzzerMutate, ChangeBit2) {
319 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
320}
321
322void TestShuffleBytes(Mutator M, int NumIter) {
323 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
324 fuzzer::EF = t.get();
325 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000326 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000327 int FoundMask = 0;
328 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
329 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
330 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
331 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
332 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
333 for (int i = 0; i < NumIter; i++) {
334 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000335 size_t NewSize = (*MD.*M)(T, 7, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000336 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
337 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
338 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
339 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
340 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
341 }
342 EXPECT_EQ(FoundMask, 31);
343}
344
345TEST(FuzzerMutate, ShuffleBytes1) {
delcypher22c63202018-04-20 06:46:14 +0000346 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000347}
348TEST(FuzzerMutate, ShuffleBytes2) {
349 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
350}
351
352void TestCopyPart(Mutator M, int NumIter) {
353 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
354 fuzzer::EF = t.get();
355 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000356 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000357 int FoundMask = 0;
358 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
359 uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
360 uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
361 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
362 uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
363
364 for (int i = 0; i < NumIter; i++) {
365 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000366 size_t NewSize = (*MD.*M)(T, 7, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000367 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
368 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
369 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
370 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
371 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
372 }
373
374 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
375 uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
376 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
377 uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
378 uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
379
380 for (int i = 0; i < NumIter; i++) {
381 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000382 size_t NewSize = (*MD.*M)(T, 5, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000383 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
384 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
385 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
386 if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
387 if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
388 }
389
390 EXPECT_EQ(FoundMask, 1023);
391}
392
393TEST(FuzzerMutate, CopyPart1) {
394 TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
395}
396TEST(FuzzerMutate, CopyPart2) {
397 TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
398}
delcypher1fda1312018-04-24 06:31:09 +0000399TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) {
400 // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an
401 // insert on an input of size `MaxSize`. Performing an insert in this case
402 // will lead to the mutation failing.
403 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
404 fuzzer::EF = t.get();
405 Random Rand(0);
406 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
407 uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
408 size_t MaxSize = sizeof(Data);
409 for (int count = 0; count < (1 << 18); ++count) {
410 size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize);
411 ASSERT_EQ(NewSize, MaxSize);
412 }
413}
george.karpenkov29efa6d2017-08-21 23:25:50 +0000414
415void TestAddWordFromDictionary(Mutator M, int NumIter) {
416 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
417 fuzzer::EF = t.get();
418 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000419 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000420 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
421 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
kccbfe84102017-12-06 23:35:02 +0000422 MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
423 MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000424 int FoundMask = 0;
425 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
426 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
427 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
428 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
429 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
430 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
431 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
432 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
433 for (int i = 0; i < NumIter; i++) {
434 uint8_t T[7] = {0x00, 0x11, 0x22};
kccbfe84102017-12-06 23:35:02 +0000435 size_t NewSize = (*MD.*M)(T, 3, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000436 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
437 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
438 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
439 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
440 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
441 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
442 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
443 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
444 }
445 EXPECT_EQ(FoundMask, 255);
446}
447
448TEST(FuzzerMutate, AddWordFromDictionary1) {
449 TestAddWordFromDictionary(
450 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
451}
452
453TEST(FuzzerMutate, AddWordFromDictionary2) {
454 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
455}
456
457void TestChangeASCIIInteger(Mutator M, int NumIter) {
458 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
459 fuzzer::EF = t.get();
460 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000461 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000462
463 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
464 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
465 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
466 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
467 int FoundMask = 0;
468 for (int i = 0; i < NumIter; i++) {
469 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
kccbfe84102017-12-06 23:35:02 +0000470 size_t NewSize = (*MD.*M)(T, 8, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000471 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
472 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
473 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
474 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
475 else if (NewSize == 8) FoundMask |= 1 << 4;
476 }
477 EXPECT_EQ(FoundMask, 31);
478}
479
480TEST(FuzzerMutate, ChangeASCIIInteger1) {
481 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
482 1 << 15);
483}
484
485TEST(FuzzerMutate, ChangeASCIIInteger2) {
486 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
487}
488
489void TestChangeBinaryInteger(Mutator M, int NumIter) {
490 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
491 fuzzer::EF = t.get();
492 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000493 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000494
495 uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
496 uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
497 uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
498 uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
499 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
500 uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
501 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
502 uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
503
504 int FoundMask = 0;
505 for (int i = 0; i < NumIter; i++) {
506 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000507 size_t NewSize = (*MD.*M)(T, 8, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000508 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
509 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
510 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
511 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
512 else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
513 else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
514 else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
515 else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
516 }
517 EXPECT_EQ(FoundMask, 255);
518}
519
520TEST(FuzzerMutate, ChangeBinaryInteger1) {
521 TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
522 1 << 12);
523}
524
525TEST(FuzzerMutate, ChangeBinaryInteger2) {
526 TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
527}
528
529
530TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
531 Unit U;
532 EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
533 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
534 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
535 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
536 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
537 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
538 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
539 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
540 EXPECT_EQ(U, Unit({'a'}));
541 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
542 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
543 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
544 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
545 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
546 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
547 EXPECT_EQ(U, Unit({'\\'}));
548 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
549 EXPECT_EQ(U, Unit({0xAB}));
550 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
551 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
552 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
553 EXPECT_EQ(U, Unit({'#'}));
554 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
555 EXPECT_EQ(U, Unit({'"'}));
556}
557
558TEST(FuzzerDictionary, ParseDictionaryFile) {
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000559 Vector<Unit> Units;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000560 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
561 EXPECT_FALSE(ParseDictionaryFile("", &Units));
562 EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
563 EXPECT_EQ(Units.size(), 0U);
564 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
565 EXPECT_EQ(Units.size(), 0U);
566 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
567 EXPECT_EQ(Units.size(), 0U);
568 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
569 EXPECT_EQ(Units.size(), 0U);
570 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000571 EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000572 EXPECT_TRUE(
573 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
574 EXPECT_EQ(Units,
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000575 Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000576}
577
578TEST(FuzzerUtil, Base64) {
579 EXPECT_EQ("", Base64({}));
580 EXPECT_EQ("YQ==", Base64({'a'}));
581 EXPECT_EQ("eA==", Base64({'x'}));
582 EXPECT_EQ("YWI=", Base64({'a', 'b'}));
583 EXPECT_EQ("eHk=", Base64({'x', 'y'}));
584 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
585 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
586 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
587 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
588 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
589}
590
591TEST(Corpus, Distribution) {
kccadf188b2018-06-07 01:40:20 +0000592 DataFlowTrace DFT;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000593 Random Rand(0);
594 std::unique_ptr<InputCorpus> C(new InputCorpus(""));
595 size_t N = 10;
596 size_t TriesPerUnit = 1<<16;
597 for (size_t i = 0; i < N; i++)
kcc0cab3f02018-07-19 01:23:32 +0000598 C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, 1, false, false, {}, DFT,
599 nullptr);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000600
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000601 Vector<size_t> Hist(N);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000602 for (size_t i = 0; i < N * TriesPerUnit; i++) {
603 Hist[C->ChooseUnitIdxToMutate(Rand)]++;
604 }
605 for (size_t i = 0; i < N; i++) {
606 // A weak sanity check that every unit gets invoked.
607 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
608 }
609}
610
611TEST(Merge, Bad) {
612 const char *kInvalidInputs[] = {
613 "",
614 "x",
615 "3\nx",
616 "2\n3",
617 "2\n2",
618 "2\n2\nA\n",
619 "2\n2\nA\nB\nC\n",
620 "0\n0\n",
621 "1\n1\nA\nDONE 0",
622 "1\n1\nA\nSTARTED 1",
623 };
624 Merger M;
625 for (auto S : kInvalidInputs) {
626 // fprintf(stderr, "TESTING:\n%s\n", S);
627 EXPECT_FALSE(M.Parse(S, false));
628 }
629}
630
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000631void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
george.karpenkov29efa6d2017-08-21 23:25:50 +0000632 EXPECT_EQ(A, B);
633}
634
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000635void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
636 Set<std::string> a(A.begin(), A.end());
637 Set<std::string> b(B.begin(), B.end());
george.karpenkov29efa6d2017-08-21 23:25:50 +0000638 EXPECT_EQ(a, b);
639}
640
641static void Merge(const std::string &Input,
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000642 const Vector<std::string> Result,
george.karpenkov29efa6d2017-08-21 23:25:50 +0000643 size_t NumNewFeatures) {
644 Merger M;
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000645 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000646 EXPECT_TRUE(M.Parse(Input, true));
647 std::stringstream SS;
648 M.PrintSummary(SS);
649 EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
650 EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
651 EQ(NewFiles, Result);
652}
653
654TEST(Merge, Good) {
655 Merger M;
656
657 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
658 EXPECT_EQ(M.Files.size(), 1U);
659 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
660 EXPECT_EQ(M.Files[0].Name, "AA");
661 EXPECT_TRUE(M.LastFailure.empty());
662 EXPECT_EQ(M.FirstNotProcessedFile, 0U);
663
664 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
665 EXPECT_EQ(M.Files.size(), 2U);
666 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
667 EXPECT_EQ(M.Files[0].Name, "AA");
668 EXPECT_EQ(M.Files[1].Name, "BB");
669 EXPECT_EQ(M.LastFailure, "AA");
670 EXPECT_EQ(M.FirstNotProcessedFile, 1U);
671
672 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
673 "STARTED 0 1000\n"
674 "DONE 0 1 2 3\n"
675 "STARTED 1 1001\n"
676 "DONE 1 4 5 6 \n"
677 "STARTED 2 1002\n"
678 "", true));
679 EXPECT_EQ(M.Files.size(), 3U);
680 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
681 EXPECT_EQ(M.Files[0].Name, "AA");
682 EXPECT_EQ(M.Files[0].Size, 1000U);
683 EXPECT_EQ(M.Files[1].Name, "BB");
684 EXPECT_EQ(M.Files[1].Size, 1001U);
685 EXPECT_EQ(M.Files[2].Name, "C");
686 EXPECT_EQ(M.Files[2].Size, 1002U);
687 EXPECT_EQ(M.LastFailure, "C");
688 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
689 EQ(M.Files[0].Features, {1, 2, 3});
690 EQ(M.Files[1].Features, {4, 5, 6});
691
692
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000693 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000694
695 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
696 "STARTED 0 1000\nDONE 0 1 2 3\n"
697 "STARTED 1 1001\nDONE 1 4 5 6 \n"
698 "STARTED 2 1002\nDONE 2 6 1 3 \n"
699 "", true));
700 EXPECT_EQ(M.Files.size(), 3U);
701 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
702 EXPECT_TRUE(M.LastFailure.empty());
703 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
704 EQ(M.Files[0].Features, {1, 2, 3});
705 EQ(M.Files[1].Features, {4, 5, 6});
706 EQ(M.Files[2].Features, {1, 3, 6});
707 EXPECT_EQ(0U, M.Merge(&NewFiles));
708 EQ(NewFiles, {});
709
710 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
711 "STARTED 0 1000\nDONE 0 1 2 3\n"
712 "STARTED 1 1001\nDONE 1 4 5 6 \n"
713 "STARTED 2 1002\nDONE 2 6 1 3\n"
714 "", true));
715 EQ(M.Files[0].Features, {1, 2, 3});
716 EQ(M.Files[1].Features, {4, 5, 6});
717 EQ(M.Files[2].Features, {1, 3, 6});
718 EXPECT_EQ(3U, M.Merge(&NewFiles));
719 EQ(NewFiles, {"B"});
720
721 // Same as the above, but with InitialFeatures.
722 EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
723 "STARTED 0 1001\nDONE 0 4 5 6 \n"
724 "STARTED 1 1002\nDONE 1 6 1 3\n"
725 "", true));
726 EQ(M.Files[0].Features, {4, 5, 6});
727 EQ(M.Files[1].Features, {1, 3, 6});
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000728 Set<uint32_t> InitialFeatures;
729 InitialFeatures.insert(1);
730 InitialFeatures.insert(2);
731 InitialFeatures.insert(3);
732 EXPECT_EQ(3U, M.Merge(InitialFeatures, &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"
739 "STARTED 0 1000\nDONE 0 1 2 3\n"
740 "STARTED 1 1001\nDONE 1 4 5 6 \n"
741 "STARTED 2 1002\nDONE 2 6 1 3 \n",
742 {"B"}, 3);
743
744 Merge("3\n0\nA\nB\nC\n"
745 "STARTED 0 2000\nDONE 0 1 2 3\n"
746 "STARTED 1 1001\nDONE 1 4 5 6 \n"
747 "STARTED 2 1002\nDONE 2 6 1 3 \n",
748 {"A", "B", "C"}, 6);
749
750 Merge("4\n0\nA\nB\nC\nD\n"
751 "STARTED 0 2000\nDONE 0 1 2 3\n"
752 "STARTED 1 1101\nDONE 1 4 5 6 \n"
753 "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
754 "STARTED 3 1000\nDONE 3 1 \n",
755 {"A", "B", "C", "D"}, 7);
756
757 Merge("4\n1\nA\nB\nC\nD\n"
758 "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
759 "STARTED 1 1100\nDONE 1 1 2 3 \n"
760 "STARTED 2 1100\nDONE 2 2 3 \n"
761 "STARTED 3 1000\nDONE 3 1 \n",
762 {"B", "D"}, 3);
763}
764
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}