blob: 3f57a5d60c28ee6634dbe462777c97f99be0bac2 [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
31TEST(Fuzzer, CrossOver) {
32 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
33 fuzzer::EF = t.get();
34 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +000035 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +000036 Unit A({0, 1, 2}), B({5, 6, 7});
37 Unit C;
38 Unit Expected[] = {
39 { 0 },
40 { 0, 1 },
41 { 0, 5 },
42 { 0, 1, 2 },
43 { 0, 1, 5 },
44 { 0, 5, 1 },
45 { 0, 5, 6 },
46 { 0, 1, 2, 5 },
47 { 0, 1, 5, 2 },
48 { 0, 1, 5, 6 },
49 { 0, 5, 1, 2 },
50 { 0, 5, 1, 6 },
51 { 0, 5, 6, 1 },
52 { 0, 5, 6, 7 },
53 { 0, 1, 2, 5, 6 },
54 { 0, 1, 5, 2, 6 },
55 { 0, 1, 5, 6, 2 },
56 { 0, 1, 5, 6, 7 },
57 { 0, 5, 1, 2, 6 },
58 { 0, 5, 1, 6, 2 },
59 { 0, 5, 1, 6, 7 },
60 { 0, 5, 6, 1, 2 },
61 { 0, 5, 6, 1, 7 },
62 { 0, 5, 6, 7, 1 },
63 { 0, 1, 2, 5, 6, 7 },
64 { 0, 1, 5, 2, 6, 7 },
65 { 0, 1, 5, 6, 2, 7 },
66 { 0, 1, 5, 6, 7, 2 },
67 { 0, 5, 1, 2, 6, 7 },
68 { 0, 5, 1, 6, 2, 7 },
69 { 0, 5, 1, 6, 7, 2 },
70 { 0, 5, 6, 1, 2, 7 },
71 { 0, 5, 6, 1, 7, 2 },
72 { 0, 5, 6, 7, 1, 2 }
73 };
74 for (size_t Len = 1; Len < 8; Len++) {
george.karpenkovfbfa45c2017-08-27 23:20:09 +000075 Set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
george.karpenkov29efa6d2017-08-21 23:25:50 +000076 for (int Iter = 0; Iter < 3000; Iter++) {
77 C.resize(Len);
kccbfe84102017-12-06 23:35:02 +000078 size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
79 C.data(), C.size());
george.karpenkov29efa6d2017-08-21 23:25:50 +000080 C.resize(NewSize);
81 FoundUnits.insert(C);
82 }
83 for (const Unit &U : Expected)
84 if (U.size() <= Len)
85 ExpectedUnitsWitThisLength.insert(U);
86 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
87 }
88}
89
90TEST(Fuzzer, Hash) {
91 uint8_t A[] = {'a', 'b', 'c'};
92 fuzzer::Unit U(A, A + sizeof(A));
93 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
94 U.push_back('d');
95 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
96}
97
98typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
99 size_t MaxSize);
100
101void TestEraseBytes(Mutator M, int NumIter) {
102 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
103 fuzzer::EF = t.get();
104 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
105 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
106 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
107 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
108 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
109 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
110 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
111 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
112
113 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
114 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
115 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
116
117 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
118 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
119 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
120
121
122 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000123 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000124 int FoundMask = 0;
125 for (int i = 0; i < NumIter; i++) {
126 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000127 size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000128 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
129 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
130 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
131 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
132 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
133 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
134 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
135 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
136
137 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
138 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
139 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
140
141 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
142 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
143 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
144 }
145 EXPECT_EQ(FoundMask, (1 << 14) - 1);
146}
147
148TEST(FuzzerMutate, EraseBytes1) {
149 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
150}
151TEST(FuzzerMutate, EraseBytes2) {
152 TestEraseBytes(&MutationDispatcher::Mutate, 2000);
153}
154
155void TestInsertByte(Mutator M, int NumIter) {
156 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
157 fuzzer::EF = t.get();
158 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000159 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000160 int FoundMask = 0;
161 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
162 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
163 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
164 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
165 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
166 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
167 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
168 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
169 for (int i = 0; i < NumIter; i++) {
170 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000171 size_t NewSize = (*MD.*M)(T, 7, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000172 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
173 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
174 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
175 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
176 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
177 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
178 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
179 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
180 }
181 EXPECT_EQ(FoundMask, 255);
182}
183
184TEST(FuzzerMutate, InsertByte1) {
185 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
186}
187TEST(FuzzerMutate, InsertByte2) {
188 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
189}
190
191void TestInsertRepeatedBytes(Mutator M, int NumIter) {
192 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
193 fuzzer::EF = t.get();
194 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000195 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000196 int FoundMask = 0;
197 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
198 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
199 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
200 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
201 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
202
203 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
204 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
205 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
206 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
207 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
208
209 for (int i = 0; i < NumIter; i++) {
210 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
kccbfe84102017-12-06 23:35:02 +0000211 size_t NewSize = (*MD.*M)(T, 4, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000212 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
213 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
214 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
215 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
216 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
217
218 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
219 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
220 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
221 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
222 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
223
224 }
225 EXPECT_EQ(FoundMask, (1 << 10) - 1);
226}
227
228TEST(FuzzerMutate, InsertRepeatedBytes1) {
229 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
230}
231TEST(FuzzerMutate, InsertRepeatedBytes2) {
232 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
233}
234
235void TestChangeByte(Mutator M, int NumIter) {
236 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
237 fuzzer::EF = t.get();
238 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000239 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000240 int FoundMask = 0;
241 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
242 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
243 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
244 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
245 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
246 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
247 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
248 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
249 for (int i = 0; i < NumIter; i++) {
250 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000251 size_t NewSize = (*MD.*M)(T, 8, 9);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000252 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
253 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
254 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
255 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
256 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
257 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
258 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
259 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
260 }
261 EXPECT_EQ(FoundMask, 255);
262}
263
264TEST(FuzzerMutate, ChangeByte1) {
265 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
266}
267TEST(FuzzerMutate, ChangeByte2) {
268 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
269}
270
271void TestChangeBit(Mutator M, int NumIter) {
272 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
273 fuzzer::EF = t.get();
274 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000275 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000276 int FoundMask = 0;
277 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
278 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
279 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
280 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
281 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
282 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
283 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
284 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
285 for (int i = 0; i < NumIter; i++) {
286 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000287 size_t NewSize = (*MD.*M)(T, 8, 9);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000288 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
289 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
290 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
291 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
292 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
293 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
294 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
295 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
296 }
297 EXPECT_EQ(FoundMask, 255);
298}
299
300TEST(FuzzerMutate, ChangeBit1) {
301 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
302}
303TEST(FuzzerMutate, ChangeBit2) {
304 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
305}
306
307void TestShuffleBytes(Mutator M, int NumIter) {
308 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
309 fuzzer::EF = t.get();
310 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000311 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000312 int FoundMask = 0;
313 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
314 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
315 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
316 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
317 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
318 for (int i = 0; i < NumIter; i++) {
319 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000320 size_t NewSize = (*MD.*M)(T, 7, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000321 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
322 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
323 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
324 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
325 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
326 }
327 EXPECT_EQ(FoundMask, 31);
328}
329
330TEST(FuzzerMutate, ShuffleBytes1) {
delcypher22c63202018-04-20 06:46:14 +0000331 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000332}
333TEST(FuzzerMutate, ShuffleBytes2) {
334 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
335}
336
337void TestCopyPart(Mutator M, int NumIter) {
338 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
339 fuzzer::EF = t.get();
340 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000341 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000342 int FoundMask = 0;
343 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
344 uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
345 uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
346 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
347 uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
348
349 for (int i = 0; i < NumIter; i++) {
350 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
kccbfe84102017-12-06 23:35:02 +0000351 size_t NewSize = (*MD.*M)(T, 7, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000352 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
353 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
354 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
355 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
356 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
357 }
358
359 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
360 uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
361 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
362 uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
363 uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
364
365 for (int i = 0; i < NumIter; i++) {
366 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000367 size_t NewSize = (*MD.*M)(T, 5, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000368 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
369 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
370 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
371 if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
372 if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
373 }
374
375 EXPECT_EQ(FoundMask, 1023);
376}
377
378TEST(FuzzerMutate, CopyPart1) {
379 TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
380}
381TEST(FuzzerMutate, CopyPart2) {
382 TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
383}
384
385void TestAddWordFromDictionary(Mutator M, int NumIter) {
386 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
387 fuzzer::EF = t.get();
388 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000389 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000390 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
391 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
kccbfe84102017-12-06 23:35:02 +0000392 MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
393 MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000394 int FoundMask = 0;
395 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
396 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
397 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
398 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
399 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
400 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
401 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
402 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
403 for (int i = 0; i < NumIter; i++) {
404 uint8_t T[7] = {0x00, 0x11, 0x22};
kccbfe84102017-12-06 23:35:02 +0000405 size_t NewSize = (*MD.*M)(T, 3, 7);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000406 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
407 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
408 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
409 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
410 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
411 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
412 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
413 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
414 }
415 EXPECT_EQ(FoundMask, 255);
416}
417
418TEST(FuzzerMutate, AddWordFromDictionary1) {
419 TestAddWordFromDictionary(
420 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
421}
422
423TEST(FuzzerMutate, AddWordFromDictionary2) {
424 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
425}
426
427void TestChangeASCIIInteger(Mutator M, int NumIter) {
428 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
429 fuzzer::EF = t.get();
430 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000431 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000432
433 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
434 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
435 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
436 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
437 int FoundMask = 0;
438 for (int i = 0; i < NumIter; i++) {
439 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
kccbfe84102017-12-06 23:35:02 +0000440 size_t NewSize = (*MD.*M)(T, 8, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000441 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
442 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
443 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
444 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
445 else if (NewSize == 8) FoundMask |= 1 << 4;
446 }
447 EXPECT_EQ(FoundMask, 31);
448}
449
450TEST(FuzzerMutate, ChangeASCIIInteger1) {
451 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
452 1 << 15);
453}
454
455TEST(FuzzerMutate, ChangeASCIIInteger2) {
456 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
457}
458
459void TestChangeBinaryInteger(Mutator M, int NumIter) {
460 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
461 fuzzer::EF = t.get();
462 Random Rand(0);
kccbfe84102017-12-06 23:35:02 +0000463 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000464
465 uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
466 uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
467 uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
468 uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
469 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
470 uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
471 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
472 uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
473
474 int FoundMask = 0;
475 for (int i = 0; i < NumIter; i++) {
476 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
kccbfe84102017-12-06 23:35:02 +0000477 size_t NewSize = (*MD.*M)(T, 8, 8);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000478 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
479 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
480 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
481 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
482 else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
483 else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
484 else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
485 else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
486 }
487 EXPECT_EQ(FoundMask, 255);
488}
489
490TEST(FuzzerMutate, ChangeBinaryInteger1) {
491 TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
492 1 << 12);
493}
494
495TEST(FuzzerMutate, ChangeBinaryInteger2) {
496 TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
497}
498
499
500TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
501 Unit U;
502 EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
503 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
504 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
505 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
506 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
507 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
508 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
509 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
510 EXPECT_EQ(U, Unit({'a'}));
511 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
512 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
513 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
514 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
515 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
516 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
517 EXPECT_EQ(U, Unit({'\\'}));
518 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
519 EXPECT_EQ(U, Unit({0xAB}));
520 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
521 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
522 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
523 EXPECT_EQ(U, Unit({'#'}));
524 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
525 EXPECT_EQ(U, Unit({'"'}));
526}
527
528TEST(FuzzerDictionary, ParseDictionaryFile) {
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000529 Vector<Unit> Units;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000530 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
531 EXPECT_FALSE(ParseDictionaryFile("", &Units));
532 EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
533 EXPECT_EQ(Units.size(), 0U);
534 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
535 EXPECT_EQ(Units.size(), 0U);
536 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
537 EXPECT_EQ(Units.size(), 0U);
538 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
539 EXPECT_EQ(Units.size(), 0U);
540 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000541 EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000542 EXPECT_TRUE(
543 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
544 EXPECT_EQ(Units,
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000545 Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000546}
547
548TEST(FuzzerUtil, Base64) {
549 EXPECT_EQ("", Base64({}));
550 EXPECT_EQ("YQ==", Base64({'a'}));
551 EXPECT_EQ("eA==", Base64({'x'}));
552 EXPECT_EQ("YWI=", Base64({'a', 'b'}));
553 EXPECT_EQ("eHk=", Base64({'x', 'y'}));
554 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
555 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
556 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
557 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
558 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
559}
560
561TEST(Corpus, Distribution) {
562 Random Rand(0);
563 std::unique_ptr<InputCorpus> C(new InputCorpus(""));
564 size_t N = 10;
565 size_t TriesPerUnit = 1<<16;
566 for (size_t i = 0; i < N; i++)
567 C->AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 1, false, {});
568
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000569 Vector<size_t> Hist(N);
george.karpenkov29efa6d2017-08-21 23:25:50 +0000570 for (size_t i = 0; i < N * TriesPerUnit; i++) {
571 Hist[C->ChooseUnitIdxToMutate(Rand)]++;
572 }
573 for (size_t i = 0; i < N; i++) {
574 // A weak sanity check that every unit gets invoked.
575 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
576 }
577}
578
579TEST(Merge, Bad) {
580 const char *kInvalidInputs[] = {
581 "",
582 "x",
583 "3\nx",
584 "2\n3",
585 "2\n2",
586 "2\n2\nA\n",
587 "2\n2\nA\nB\nC\n",
588 "0\n0\n",
589 "1\n1\nA\nDONE 0",
590 "1\n1\nA\nSTARTED 1",
591 };
592 Merger M;
593 for (auto S : kInvalidInputs) {
594 // fprintf(stderr, "TESTING:\n%s\n", S);
595 EXPECT_FALSE(M.Parse(S, false));
596 }
597}
598
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000599void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
george.karpenkov29efa6d2017-08-21 23:25:50 +0000600 EXPECT_EQ(A, B);
601}
602
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000603void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
604 Set<std::string> a(A.begin(), A.end());
605 Set<std::string> b(B.begin(), B.end());
george.karpenkov29efa6d2017-08-21 23:25:50 +0000606 EXPECT_EQ(a, b);
607}
608
609static void Merge(const std::string &Input,
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000610 const Vector<std::string> Result,
george.karpenkov29efa6d2017-08-21 23:25:50 +0000611 size_t NumNewFeatures) {
612 Merger M;
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000613 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000614 EXPECT_TRUE(M.Parse(Input, true));
615 std::stringstream SS;
616 M.PrintSummary(SS);
617 EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
618 EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
619 EQ(NewFiles, Result);
620}
621
622TEST(Merge, Good) {
623 Merger M;
624
625 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
626 EXPECT_EQ(M.Files.size(), 1U);
627 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
628 EXPECT_EQ(M.Files[0].Name, "AA");
629 EXPECT_TRUE(M.LastFailure.empty());
630 EXPECT_EQ(M.FirstNotProcessedFile, 0U);
631
632 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
633 EXPECT_EQ(M.Files.size(), 2U);
634 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
635 EXPECT_EQ(M.Files[0].Name, "AA");
636 EXPECT_EQ(M.Files[1].Name, "BB");
637 EXPECT_EQ(M.LastFailure, "AA");
638 EXPECT_EQ(M.FirstNotProcessedFile, 1U);
639
640 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
641 "STARTED 0 1000\n"
642 "DONE 0 1 2 3\n"
643 "STARTED 1 1001\n"
644 "DONE 1 4 5 6 \n"
645 "STARTED 2 1002\n"
646 "", true));
647 EXPECT_EQ(M.Files.size(), 3U);
648 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
649 EXPECT_EQ(M.Files[0].Name, "AA");
650 EXPECT_EQ(M.Files[0].Size, 1000U);
651 EXPECT_EQ(M.Files[1].Name, "BB");
652 EXPECT_EQ(M.Files[1].Size, 1001U);
653 EXPECT_EQ(M.Files[2].Name, "C");
654 EXPECT_EQ(M.Files[2].Size, 1002U);
655 EXPECT_EQ(M.LastFailure, "C");
656 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
657 EQ(M.Files[0].Features, {1, 2, 3});
658 EQ(M.Files[1].Features, {4, 5, 6});
659
660
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000661 Vector<std::string> NewFiles;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000662
663 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
664 "STARTED 0 1000\nDONE 0 1 2 3\n"
665 "STARTED 1 1001\nDONE 1 4 5 6 \n"
666 "STARTED 2 1002\nDONE 2 6 1 3 \n"
667 "", true));
668 EXPECT_EQ(M.Files.size(), 3U);
669 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
670 EXPECT_TRUE(M.LastFailure.empty());
671 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
672 EQ(M.Files[0].Features, {1, 2, 3});
673 EQ(M.Files[1].Features, {4, 5, 6});
674 EQ(M.Files[2].Features, {1, 3, 6});
675 EXPECT_EQ(0U, M.Merge(&NewFiles));
676 EQ(NewFiles, {});
677
678 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
679 "STARTED 0 1000\nDONE 0 1 2 3\n"
680 "STARTED 1 1001\nDONE 1 4 5 6 \n"
681 "STARTED 2 1002\nDONE 2 6 1 3\n"
682 "", true));
683 EQ(M.Files[0].Features, {1, 2, 3});
684 EQ(M.Files[1].Features, {4, 5, 6});
685 EQ(M.Files[2].Features, {1, 3, 6});
686 EXPECT_EQ(3U, M.Merge(&NewFiles));
687 EQ(NewFiles, {"B"});
688
689 // Same as the above, but with InitialFeatures.
690 EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
691 "STARTED 0 1001\nDONE 0 4 5 6 \n"
692 "STARTED 1 1002\nDONE 1 6 1 3\n"
693 "", true));
694 EQ(M.Files[0].Features, {4, 5, 6});
695 EQ(M.Files[1].Features, {1, 3, 6});
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000696 Set<uint32_t> InitialFeatures;
697 InitialFeatures.insert(1);
698 InitialFeatures.insert(2);
699 InitialFeatures.insert(3);
700 EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFiles));
george.karpenkov29efa6d2017-08-21 23:25:50 +0000701 EQ(NewFiles, {"B"});
702}
703
704TEST(Merge, Merge) {
705
706 Merge("3\n1\nA\nB\nC\n"
707 "STARTED 0 1000\nDONE 0 1 2 3\n"
708 "STARTED 1 1001\nDONE 1 4 5 6 \n"
709 "STARTED 2 1002\nDONE 2 6 1 3 \n",
710 {"B"}, 3);
711
712 Merge("3\n0\nA\nB\nC\n"
713 "STARTED 0 2000\nDONE 0 1 2 3\n"
714 "STARTED 1 1001\nDONE 1 4 5 6 \n"
715 "STARTED 2 1002\nDONE 2 6 1 3 \n",
716 {"A", "B", "C"}, 6);
717
718 Merge("4\n0\nA\nB\nC\nD\n"
719 "STARTED 0 2000\nDONE 0 1 2 3\n"
720 "STARTED 1 1101\nDONE 1 4 5 6 \n"
721 "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
722 "STARTED 3 1000\nDONE 3 1 \n",
723 {"A", "B", "C", "D"}, 7);
724
725 Merge("4\n1\nA\nB\nC\nD\n"
726 "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
727 "STARTED 1 1100\nDONE 1 1 2 3 \n"
728 "STARTED 2 1100\nDONE 2 2 3 \n"
729 "STARTED 3 1000\nDONE 3 1 \n",
730 {"B", "D"}, 3);
731}
732
733TEST(Fuzzer, ForEachNonZeroByte) {
734 const size_t N = 64;
735 alignas(64) uint8_t Ar[N + 8] = {
736 0, 0, 0, 0, 0, 0, 0, 0,
737 1, 2, 0, 0, 0, 0, 0, 0,
738 0, 0, 3, 0, 4, 0, 0, 0,
739 0, 0, 0, 0, 0, 0, 0, 0,
740 0, 0, 0, 5, 0, 6, 0, 0,
741 0, 0, 0, 0, 0, 0, 7, 0,
742 0, 0, 0, 0, 0, 0, 0, 0,
743 0, 0, 0, 0, 0, 0, 0, 8,
744 9, 9, 9, 9, 9, 9, 9, 9,
745 };
george.karpenkovfbfa45c2017-08-27 23:20:09 +0000746 typedef Vector<std::pair<size_t, uint8_t> > Vec;
george.karpenkov29efa6d2017-08-21 23:25:50 +0000747 Vec Res, Expected;
748 auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
749 Res.push_back({FirstFeature + Idx, V});
750 };
751 ForEachNonZeroByte(Ar, Ar + N, 100, CB);
752 Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
753 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
754 EXPECT_EQ(Res, Expected);
755
756 Res.clear();
757 ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
758 Expected = { {109, 2}, {118, 3}, {120, 4},
759 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
760 EXPECT_EQ(Res, Expected);
761
762 Res.clear();
763 ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
764 Expected = { {109, 2}, {118, 3}, {120, 4},
765 {135, 5}, {137, 6}, {146, 7}};
766 EXPECT_EQ(Res, Expected);
767}
768
morehousea80f6452017-12-04 19:25:59 +0000769// FuzzerCommand unit tests. The arguments in the two helper methods below must
770// match.
771static void makeCommandArgs(Vector<std::string> *ArgsToAdd) {
772 assert(ArgsToAdd);
773 ArgsToAdd->clear();
774 ArgsToAdd->push_back("foo");
775 ArgsToAdd->push_back("-bar=baz");
776 ArgsToAdd->push_back("qux");
777 ArgsToAdd->push_back(Command::ignoreRemainingArgs());
778 ArgsToAdd->push_back("quux");
779 ArgsToAdd->push_back("-grault=garply");
780}
781
782static std::string makeCmdLine(const char *separator, const char *suffix) {
783 std::string CmdLine("foo -bar=baz qux ");
784 if (strlen(separator) != 0) {
785 CmdLine += separator;
786 CmdLine += " ";
787 }
788 CmdLine += Command::ignoreRemainingArgs();
789 CmdLine += " quux -grault=garply";
790 if (strlen(suffix) != 0) {
791 CmdLine += " ";
792 CmdLine += suffix;
793 }
794 return CmdLine;
795}
796
797TEST(FuzzerCommand, Create) {
798 std::string CmdLine;
799
800 // Default constructor
801 Command DefaultCmd;
802
803 CmdLine = DefaultCmd.toString();
804 EXPECT_EQ(CmdLine, "");
805
806 // Explicit constructor
807 Vector<std::string> ArgsToAdd;
808 makeCommandArgs(&ArgsToAdd);
809 Command InitializedCmd(ArgsToAdd);
810
811 CmdLine = InitializedCmd.toString();
812 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
813
814 // Compare each argument
815 auto InitializedArgs = InitializedCmd.getArguments();
816 auto i = ArgsToAdd.begin();
817 auto j = InitializedArgs.begin();
818 while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
819 EXPECT_EQ(*i++, *j++);
820 }
821 EXPECT_EQ(i, ArgsToAdd.end());
822 EXPECT_EQ(j, InitializedArgs.end());
823
824 // Copy constructor
825 Command CopiedCmd(InitializedCmd);
826
827 CmdLine = CopiedCmd.toString();
828 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
829
830 // Assignment operator
831 Command AssignedCmd;
832 AssignedCmd = CopiedCmd;
833
834 CmdLine = AssignedCmd.toString();
835 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
836}
837
838TEST(FuzzerCommand, ModifyArguments) {
839 Vector<std::string> ArgsToAdd;
840 makeCommandArgs(&ArgsToAdd);
841 Command Cmd;
842 std::string CmdLine;
843
844 Cmd.addArguments(ArgsToAdd);
845 CmdLine = Cmd.toString();
846 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
847
848 Cmd.addArgument("waldo");
849 EXPECT_TRUE(Cmd.hasArgument("waldo"));
850
851 CmdLine = Cmd.toString();
852 EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
853
854 Cmd.removeArgument("waldo");
855 EXPECT_FALSE(Cmd.hasArgument("waldo"));
856
857 CmdLine = Cmd.toString();
858 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
859}
860
861TEST(FuzzerCommand, ModifyFlags) {
862 Vector<std::string> ArgsToAdd;
863 makeCommandArgs(&ArgsToAdd);
864 Command Cmd(ArgsToAdd);
865 std::string Value, CmdLine;
866 ASSERT_FALSE(Cmd.hasFlag("fred"));
867
868 Value = Cmd.getFlagValue("fred");
869 EXPECT_EQ(Value, "");
870
871 CmdLine = Cmd.toString();
872 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
873
874 Cmd.addFlag("fred", "plugh");
875 EXPECT_TRUE(Cmd.hasFlag("fred"));
876
877 Value = Cmd.getFlagValue("fred");
878 EXPECT_EQ(Value, "plugh");
879
880 CmdLine = Cmd.toString();
881 EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
882
883 Cmd.removeFlag("fred");
884 EXPECT_FALSE(Cmd.hasFlag("fred"));
885
886 Value = Cmd.getFlagValue("fred");
887 EXPECT_EQ(Value, "");
888
889 CmdLine = Cmd.toString();
890 EXPECT_EQ(CmdLine, makeCmdLine("", ""));
891}
892
893TEST(FuzzerCommand, SetOutput) {
894 Vector<std::string> ArgsToAdd;
895 makeCommandArgs(&ArgsToAdd);
896 Command Cmd(ArgsToAdd);
897 std::string CmdLine;
898 ASSERT_FALSE(Cmd.hasOutputFile());
899 ASSERT_FALSE(Cmd.isOutAndErrCombined());
900
901 Cmd.combineOutAndErr(true);
902 EXPECT_TRUE(Cmd.isOutAndErrCombined());
903
904 CmdLine = Cmd.toString();
905 EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
906
907 Cmd.combineOutAndErr(false);
908 EXPECT_FALSE(Cmd.isOutAndErrCombined());
909
910 Cmd.setOutputFile("xyzzy");
911 EXPECT_TRUE(Cmd.hasOutputFile());
912
913 CmdLine = Cmd.toString();
914 EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
915
916 Cmd.setOutputFile("thud");
917 EXPECT_TRUE(Cmd.hasOutputFile());
918
919 CmdLine = Cmd.toString();
920 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
921
922 Cmd.combineOutAndErr();
923 EXPECT_TRUE(Cmd.isOutAndErrCombined());
924
925 CmdLine = Cmd.toString();
morehouse2e96d0e2017-12-05 17:13:17 +0000926 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
morehousea80f6452017-12-04 19:25:59 +0000927}
928
george.karpenkov29efa6d2017-08-21 23:25:50 +0000929int main(int argc, char **argv) {
930 testing::InitGoogleTest(&argc, argv);
931 return RUN_ALL_TESTS();
932}