blob: bcbd1169a68138ff16426a4cca22f0d5f2921408 [file] [log] [blame]
Mike Aizatskyf13cbee2016-04-01 18:38:58 +00001// This file is distributed under the University of Illinois Open Source
2// License. See LICENSE.TXT for details.
3
Dan Liew0617f152016-06-10 05:33:07 +00004// 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
Kostya Serebryany71672552015-01-30 23:26:57 +00008#include "FuzzerInternal.h"
9#include "gtest/gtest.h"
Dan Liew1873a492016-06-07 23:32:50 +000010#include <memory>
Kostya Serebryany71672552015-01-30 23:26:57 +000011#include <set>
12
Kostya Serebryany8ce74242015-08-01 01:42:51 +000013using namespace fuzzer;
14
Kostya Serebryany566bc5a2015-05-06 22:19:00 +000015// For now, have LLVMFuzzerTestOneInput just to make it link.
16// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
Ivan Krasindf919102016-01-22 22:28:27 +000017extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
Kostya Serebryany71672552015-01-30 23:26:57 +000018 abort();
19}
20
21TEST(Fuzzer, CrossOver) {
Dan Liew1873a492016-06-07 23:32:50 +000022 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
23 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +000024 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +000025 MutationDispatcher MD(Rand, {});
Kostya Serebryany71672552015-01-30 23:26:57 +000026 Unit A({0, 1, 2}), B({5, 6, 7});
27 Unit C;
28 Unit Expected[] = {
29 { 0 },
30 { 0, 1 },
31 { 0, 5 },
32 { 0, 1, 2 },
33 { 0, 1, 5 },
34 { 0, 5, 1 },
35 { 0, 5, 6 },
36 { 0, 1, 2, 5 },
37 { 0, 1, 5, 2 },
38 { 0, 1, 5, 6 },
39 { 0, 5, 1, 2 },
40 { 0, 5, 1, 6 },
41 { 0, 5, 6, 1 },
42 { 0, 5, 6, 7 },
43 { 0, 1, 2, 5, 6 },
44 { 0, 1, 5, 2, 6 },
45 { 0, 1, 5, 6, 2 },
46 { 0, 1, 5, 6, 7 },
47 { 0, 5, 1, 2, 6 },
48 { 0, 5, 1, 6, 2 },
49 { 0, 5, 1, 6, 7 },
50 { 0, 5, 6, 1, 2 },
51 { 0, 5, 6, 1, 7 },
52 { 0, 5, 6, 7, 1 },
53 { 0, 1, 2, 5, 6, 7 },
54 { 0, 1, 5, 2, 6, 7 },
55 { 0, 1, 5, 6, 2, 7 },
56 { 0, 1, 5, 6, 7, 2 },
57 { 0, 5, 1, 2, 6, 7 },
58 { 0, 5, 1, 6, 2, 7 },
59 { 0, 5, 1, 6, 7, 2 },
60 { 0, 5, 6, 1, 2, 7 },
61 { 0, 5, 6, 1, 7, 2 },
62 { 0, 5, 6, 7, 1, 2 }
63 };
64 for (size_t Len = 1; Len < 8; Len++) {
65 std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
66 for (int Iter = 0; Iter < 3000; Iter++) {
Kostya Serebryanyf3424592015-05-22 22:35:31 +000067 C.resize(Len);
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +000068 size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
69 C.data(), C.size());
Kostya Serebryanyf3424592015-05-22 22:35:31 +000070 C.resize(NewSize);
Kostya Serebryany71672552015-01-30 23:26:57 +000071 FoundUnits.insert(C);
72 }
73 for (const Unit &U : Expected)
74 if (U.size() <= Len)
75 ExpectedUnitsWitThisLength.insert(U);
76 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
77 }
78}
Kostya Serebryany96eab652015-05-14 22:41:49 +000079
80TEST(Fuzzer, Hash) {
81 uint8_t A[] = {'a', 'b', 'c'};
82 fuzzer::Unit U(A, A + sizeof(A));
83 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
84 U.push_back('d');
85 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
86}
Kostya Serebryany8ce74242015-08-01 01:42:51 +000087
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +000088typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
89 size_t MaxSize);
Kostya Serebryany8ce74242015-08-01 01:42:51 +000090
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +000091void TestEraseBytes(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +000092 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
93 fuzzer::EF = t.get();
Kostya Serebryany8ce74242015-08-01 01:42:51 +000094 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
95 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
96 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
97 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
98 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
99 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
100 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
101 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000102
103 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
104 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
105 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
106
107 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
108 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
109 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
110
111
Kostya Serebryanya3992212016-02-13 03:00:53 +0000112 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000113 MutationDispatcher MD(Rand, {});
Kostya Serebryany8ce74242015-08-01 01:42:51 +0000114 int FoundMask = 0;
115 for (int i = 0; i < NumIter; i++) {
116 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000117 size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000118 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
119 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
120 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
121 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
122 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
123 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
124 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
125 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000126
127 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
128 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
129 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
130
131 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
132 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
133 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
Kostya Serebryany8ce74242015-08-01 01:42:51 +0000134 }
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000135 EXPECT_EQ(FoundMask, (1 << 14) - 1);
Kostya Serebryany8ce74242015-08-01 01:42:51 +0000136}
137
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000138TEST(FuzzerMutate, EraseBytes1) {
139 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000140}
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000141TEST(FuzzerMutate, EraseBytes2) {
142 TestEraseBytes(&MutationDispatcher::Mutate, 2000);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000143}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000144
145void TestInsertByte(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000146 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
147 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000148 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000149 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000150 int FoundMask = 0;
151 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
152 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
153 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
154 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
155 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
156 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
157 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
158 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
159 for (int i = 0; i < NumIter; i++) {
160 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000161 size_t NewSize = (MD.*M)(T, 7, 8);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000162 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
163 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
164 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
165 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
166 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
167 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
168 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
169 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
170 }
171 EXPECT_EQ(FoundMask, 255);
172}
173
Kostya Serebryany7d211662015-09-04 00:12:11 +0000174TEST(FuzzerMutate, InsertByte1) {
175 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
176}
177TEST(FuzzerMutate, InsertByte2) {
178 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
179}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000180
Kostya Serebryanydfbe59b2016-08-15 17:48:28 +0000181void TestInsertRepeatedBytes(Mutator M, int NumIter) {
182 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
183 fuzzer::EF = t.get();
184 Random Rand(0);
185 MutationDispatcher MD(Rand, {});
186 int FoundMask = 0;
187 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
188 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
189 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
190 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
191 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
192
193 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
194 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
195 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
196 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
197 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
198
199 for (int i = 0; i < NumIter; i++) {
200 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
201 size_t NewSize = (MD.*M)(T, 4, 8);
202 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
203 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
204 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
205 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
206 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
207
208 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
209 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
210 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
211 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
212 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
213
214 }
215 EXPECT_EQ(FoundMask, (1 << 10) - 1);
216}
217
218TEST(FuzzerMutate, InsertRepeatedBytes1) {
219 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
220}
221TEST(FuzzerMutate, InsertRepeatedBytes2) {
222 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 200000);
223}
224
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000225void TestChangeByte(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000226 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
227 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000228 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000229 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000230 int FoundMask = 0;
231 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
232 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
233 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
234 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
235 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
236 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
237 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
238 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
239 for (int i = 0; i < NumIter; i++) {
240 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000241 size_t NewSize = (MD.*M)(T, 8, 9);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000242 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
243 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
244 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
245 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
246 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
247 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
248 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
249 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
250 }
251 EXPECT_EQ(FoundMask, 255);
252}
253
Kostya Serebryany7d211662015-09-04 00:12:11 +0000254TEST(FuzzerMutate, ChangeByte1) {
255 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
256}
257TEST(FuzzerMutate, ChangeByte2) {
258 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
259}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000260
261void TestChangeBit(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000262 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
263 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000264 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000265 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000266 int FoundMask = 0;
267 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
268 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
269 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
270 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
271 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
272 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
273 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
274 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
275 for (int i = 0; i < NumIter; i++) {
276 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000277 size_t NewSize = (MD.*M)(T, 8, 9);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000278 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
279 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
280 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
281 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
282 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
283 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
284 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
285 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
286 }
287 EXPECT_EQ(FoundMask, 255);
288}
289
Kostya Serebryany7d211662015-09-04 00:12:11 +0000290TEST(FuzzerMutate, ChangeBit1) {
291 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
292}
293TEST(FuzzerMutate, ChangeBit2) {
294 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
295}
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000296
297void TestShuffleBytes(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000298 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
299 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000300 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000301 MutationDispatcher MD(Rand, {});
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000302 int FoundMask = 0;
303 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
304 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
305 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
306 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
307 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
308 for (int i = 0; i < NumIter; i++) {
309 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000310 size_t NewSize = (MD.*M)(T, 7, 7);
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000311 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
312 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
313 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
314 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
315 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
316 }
317 EXPECT_EQ(FoundMask, 31);
318}
319
Kostya Serebryany7d211662015-09-04 00:12:11 +0000320TEST(FuzzerMutate, ShuffleBytes1) {
Kostya Serebryanya3992212016-02-13 03:00:53 +0000321 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000322}
323TEST(FuzzerMutate, ShuffleBytes2) {
Dan Liewc4989d22016-06-15 01:40:02 +0000324 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000325}
326
327void TestAddWordFromDictionary(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000328 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
329 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000330 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000331 MutationDispatcher MD(Rand, {});
Kostya Serebryany7d211662015-09-04 00:12:11 +0000332 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
333 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000334 MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
335 MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
Kostya Serebryany7d211662015-09-04 00:12:11 +0000336 int FoundMask = 0;
337 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
338 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
339 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
340 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
341 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
342 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
343 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
344 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
345 for (int i = 0; i < NumIter; i++) {
346 uint8_t T[7] = {0x00, 0x11, 0x22};
347 size_t NewSize = (MD.*M)(T, 3, 7);
348 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
349 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
350 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
351 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
352 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
353 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
354 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
355 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
356 }
357 EXPECT_EQ(FoundMask, 255);
358}
359
360TEST(FuzzerMutate, AddWordFromDictionary1) {
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000361 TestAddWordFromDictionary(
362 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000363}
364
365TEST(FuzzerMutate, AddWordFromDictionary2) {
366 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
367}
Kostya Serebryany9838b2b2015-09-03 20:23:46 +0000368
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000369void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000370 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
371 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000372 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000373 MutationDispatcher MD(Rand, {});
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000374 uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000375 size_t PosHint = 7777;
Kostya Serebryanyc135b552016-07-15 23:27:19 +0000376 MD.AddWordToAutoDictionary({Word(W, sizeof(W)), PosHint});
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000377 int FoundMask = 0;
378 for (int i = 0; i < NumIter; i++) {
379 uint8_t T[10000];
380 memset(T, 0, sizeof(T));
381 size_t NewSize = (MD.*M)(T, 9000, 10000);
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000382 if (NewSize >= PosHint + sizeof(W) &&
383 !memcmp(W, T + PosHint, sizeof(W)))
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000384 FoundMask = 1;
385 }
386 EXPECT_EQ(FoundMask, 1);
387}
388
389TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {
390 TestAddWordFromDictionaryWithHint(
Kostya Serebryany4b358742016-01-14 02:36:44 +0000391 &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5);
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000392}
393
394TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {
395 TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10);
396}
397
Kostya Serebryany25425ad2015-09-08 17:19:31 +0000398void TestChangeASCIIInteger(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000399 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
400 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000401 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000402 MutationDispatcher MD(Rand, {});
Kostya Serebryany25425ad2015-09-08 17:19:31 +0000403
404 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
405 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
406 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
407 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
408 int FoundMask = 0;
409 for (int i = 0; i < NumIter; i++) {
410 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
411 size_t NewSize = (MD.*M)(T, 8, 8);
412 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
413 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
414 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
415 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
416 else if (NewSize == 8) FoundMask |= 1 << 4;
417 }
418 EXPECT_EQ(FoundMask, 31);
419}
420
421TEST(FuzzerMutate, ChangeASCIIInteger1) {
422 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
423 1 << 15);
424}
425
426TEST(FuzzerMutate, ChangeASCIIInteger2) {
427 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
428}
429
430
Kostya Serebryany9838b2b2015-09-03 20:23:46 +0000431TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
432 Unit U;
433 EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
434 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
435 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
436 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
437 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
438 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
439 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
440 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
441 EXPECT_EQ(U, Unit({'a'}));
442 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
443 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
444 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
445 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
446 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
447 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
448 EXPECT_EQ(U, Unit({'\\'}));
449 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
450 EXPECT_EQ(U, Unit({0xAB}));
451 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
452 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
453 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
454 EXPECT_EQ(U, Unit({'#'}));
455 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
456 EXPECT_EQ(U, Unit({'"'}));
457}
458
459TEST(FuzzerDictionary, ParseDictionaryFile) {
460 std::vector<Unit> Units;
461 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
462 EXPECT_FALSE(ParseDictionaryFile("", &Units));
463 EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
464 EXPECT_EQ(Units.size(), 0U);
465 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
466 EXPECT_EQ(Units.size(), 0U);
467 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
468 EXPECT_EQ(Units.size(), 0U);
469 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
470 EXPECT_EQ(Units.size(), 0U);
471 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
472 EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
473 EXPECT_TRUE(
474 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
475 EXPECT_EQ(Units,
476 std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
477}
Kostya Serebryany9e48cda2015-12-04 22:29:39 +0000478
479TEST(FuzzerUtil, Base64) {
480 EXPECT_EQ("", Base64({}));
481 EXPECT_EQ("YQ==", Base64({'a'}));
482 EXPECT_EQ("eA==", Base64({'x'}));
483 EXPECT_EQ("YWI=", Base64({'a', 'b'}));
484 EXPECT_EQ("eHk=", Base64({'x', 'y'}));
485 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
486 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
487 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
488 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
489 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
490}
Ivan Krasindf919102016-01-22 22:28:27 +0000491
492TEST(Corpus, Distribution) {
Dan Liew1873a492016-06-07 23:32:50 +0000493 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
494 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000495 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000496 MutationDispatcher MD(Rand, {});
497 Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {});
Ivan Krasindf919102016-01-22 22:28:27 +0000498 size_t N = 10;
499 size_t TriesPerUnit = 1<<20;
500 for (size_t i = 0; i < N; i++) {
501 Fuzz.AddToCorpus(Unit{ static_cast<uint8_t>(i) });
502 }
503 std::vector<size_t> Hist(N);
504 for (size_t i = 0; i < N * TriesPerUnit; i++) {
505 Hist[Fuzz.ChooseUnitIdxToMutate()]++;
506 }
507 for (size_t i = 0; i < N; i++) {
508 // A weak sanity check that every unit gets invoked.
509 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
510 }
511}