blob: 3630e39a24aeb5ca21333289bceb1adf6f4c7a7a [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
91void TestEraseByte(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 Serebryanya3992212016-02-13 03:00:53 +0000102 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000103 MutationDispatcher MD(Rand, {});
Kostya Serebryany8ce74242015-08-01 01:42:51 +0000104 int FoundMask = 0;
105 for (int i = 0; i < NumIter; i++) {
106 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000107 size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000108 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
109 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
110 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
111 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
112 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
113 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
114 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
115 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
Kostya Serebryany8ce74242015-08-01 01:42:51 +0000116 }
117 EXPECT_EQ(FoundMask, 255);
118}
119
Kostya Serebryany7d211662015-09-04 00:12:11 +0000120TEST(FuzzerMutate, EraseByte1) {
121 TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100);
122}
123TEST(FuzzerMutate, EraseByte2) {
124 TestEraseByte(&MutationDispatcher::Mutate, 1000);
125}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000126
127void TestInsertByte(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000128 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
129 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000130 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000131 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000132 int FoundMask = 0;
133 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
134 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
135 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
136 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
137 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
138 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
139 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
140 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
141 for (int i = 0; i < NumIter; i++) {
142 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000143 size_t NewSize = (MD.*M)(T, 7, 8);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000144 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
145 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
146 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
147 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
148 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
149 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
150 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
151 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
152 }
153 EXPECT_EQ(FoundMask, 255);
154}
155
Kostya Serebryany7d211662015-09-04 00:12:11 +0000156TEST(FuzzerMutate, InsertByte1) {
157 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
158}
159TEST(FuzzerMutate, InsertByte2) {
160 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
161}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000162
163void TestChangeByte(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000164 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
165 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000166 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000167 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000168 int FoundMask = 0;
169 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
170 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
171 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
172 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
173 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
174 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
175 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
176 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
177 for (int i = 0; i < NumIter; i++) {
178 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000179 size_t NewSize = (MD.*M)(T, 8, 9);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000180 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
181 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
182 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
183 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
184 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
185 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
186 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
187 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
188 }
189 EXPECT_EQ(FoundMask, 255);
190}
191
Kostya Serebryany7d211662015-09-04 00:12:11 +0000192TEST(FuzzerMutate, ChangeByte1) {
193 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
194}
195TEST(FuzzerMutate, ChangeByte2) {
196 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
197}
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000198
199void TestChangeBit(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000200 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
201 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000202 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000203 MutationDispatcher MD(Rand, {});
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000204 int FoundMask = 0;
205 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
206 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
207 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
208 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
209 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
210 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
211 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
212 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
213 for (int i = 0; i < NumIter; i++) {
214 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000215 size_t NewSize = (MD.*M)(T, 8, 9);
Kostya Serebryany86a5fba2015-08-01 02:23:06 +0000216 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
217 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
218 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
219 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
220 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
221 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
222 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
223 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
224 }
225 EXPECT_EQ(FoundMask, 255);
226}
227
Kostya Serebryany7d211662015-09-04 00:12:11 +0000228TEST(FuzzerMutate, ChangeBit1) {
229 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
230}
231TEST(FuzzerMutate, ChangeBit2) {
232 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
233}
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000234
235void TestShuffleBytes(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000236 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
237 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000238 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000239 MutationDispatcher MD(Rand, {});
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000240 int FoundMask = 0;
241 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
242 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
243 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
244 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
245 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
246 for (int i = 0; i < NumIter; i++) {
247 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
Kostya Serebryanyec2dcb12015-09-03 21:24:19 +0000248 size_t NewSize = (MD.*M)(T, 7, 7);
Kostya Serebryanybf29ff22015-08-06 01:29:13 +0000249 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
250 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
251 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
252 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
253 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
254 }
255 EXPECT_EQ(FoundMask, 31);
256}
257
Kostya Serebryany7d211662015-09-04 00:12:11 +0000258TEST(FuzzerMutate, ShuffleBytes1) {
Kostya Serebryanya3992212016-02-13 03:00:53 +0000259 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000260}
261TEST(FuzzerMutate, ShuffleBytes2) {
Dan Liewc4989d22016-06-15 01:40:02 +0000262 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000263}
264
265void TestAddWordFromDictionary(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000266 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
267 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000268 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000269 MutationDispatcher MD(Rand, {});
Kostya Serebryany7d211662015-09-04 00:12:11 +0000270 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
271 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000272 MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
273 MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
Kostya Serebryany7d211662015-09-04 00:12:11 +0000274 int FoundMask = 0;
275 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
276 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
277 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
278 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
279 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
280 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
281 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
282 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
283 for (int i = 0; i < NumIter; i++) {
284 uint8_t T[7] = {0x00, 0x11, 0x22};
285 size_t NewSize = (MD.*M)(T, 3, 7);
286 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
287 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
288 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
289 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
290 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
291 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
292 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
293 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
294 }
295 EXPECT_EQ(FoundMask, 255);
296}
297
298TEST(FuzzerMutate, AddWordFromDictionary1) {
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000299 TestAddWordFromDictionary(
300 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
Kostya Serebryany7d211662015-09-04 00:12:11 +0000301}
302
303TEST(FuzzerMutate, AddWordFromDictionary2) {
304 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
305}
Kostya Serebryany9838b2b2015-09-03 20:23:46 +0000306
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000307void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000308 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
309 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000310 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000311 MutationDispatcher MD(Rand, {});
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000312 uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000313 size_t PosHint = 7777;
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000314 MD.AddWordToAutoDictionary(Word(W, sizeof(W)), PosHint);
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000315 int FoundMask = 0;
316 for (int i = 0; i < NumIter; i++) {
317 uint8_t T[10000];
318 memset(T, 0, sizeof(T));
319 size_t NewSize = (MD.*M)(T, 9000, 10000);
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000320 if (NewSize >= PosHint + sizeof(W) &&
321 !memcmp(W, T + PosHint, sizeof(W)))
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000322 FoundMask = 1;
323 }
324 EXPECT_EQ(FoundMask, 1);
325}
326
327TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) {
328 TestAddWordFromDictionaryWithHint(
Kostya Serebryany4b358742016-01-14 02:36:44 +0000329 &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5);
Kostya Serebryany152ac7a2016-01-07 01:49:35 +0000330}
331
332TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) {
333 TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10);
334}
335
Kostya Serebryany25425ad2015-09-08 17:19:31 +0000336void TestChangeASCIIInteger(Mutator M, int NumIter) {
Dan Liew1873a492016-06-07 23:32:50 +0000337 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
338 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000339 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000340 MutationDispatcher MD(Rand, {});
Kostya Serebryany25425ad2015-09-08 17:19:31 +0000341
342 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
343 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
344 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
345 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
346 int FoundMask = 0;
347 for (int i = 0; i < NumIter; i++) {
348 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
349 size_t NewSize = (MD.*M)(T, 8, 8);
350 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
351 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
352 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
353 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
354 else if (NewSize == 8) FoundMask |= 1 << 4;
355 }
356 EXPECT_EQ(FoundMask, 31);
357}
358
359TEST(FuzzerMutate, ChangeASCIIInteger1) {
360 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
361 1 << 15);
362}
363
364TEST(FuzzerMutate, ChangeASCIIInteger2) {
365 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
366}
367
368
Kostya Serebryany9838b2b2015-09-03 20:23:46 +0000369TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
370 Unit U;
371 EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
372 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
373 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
374 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
375 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
376 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
377 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
378 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
379 EXPECT_EQ(U, Unit({'a'}));
380 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
381 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
382 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
383 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
384 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
385 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
386 EXPECT_EQ(U, Unit({'\\'}));
387 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
388 EXPECT_EQ(U, Unit({0xAB}));
389 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
390 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
391 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
392 EXPECT_EQ(U, Unit({'#'}));
393 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
394 EXPECT_EQ(U, Unit({'"'}));
395}
396
397TEST(FuzzerDictionary, ParseDictionaryFile) {
398 std::vector<Unit> Units;
399 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
400 EXPECT_FALSE(ParseDictionaryFile("", &Units));
401 EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
402 EXPECT_EQ(Units.size(), 0U);
403 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
404 EXPECT_EQ(Units.size(), 0U);
405 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
406 EXPECT_EQ(Units.size(), 0U);
407 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
408 EXPECT_EQ(Units.size(), 0U);
409 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
410 EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
411 EXPECT_TRUE(
412 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
413 EXPECT_EQ(Units,
414 std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
415}
Kostya Serebryany9e48cda2015-12-04 22:29:39 +0000416
417TEST(FuzzerUtil, Base64) {
418 EXPECT_EQ("", Base64({}));
419 EXPECT_EQ("YQ==", Base64({'a'}));
420 EXPECT_EQ("eA==", Base64({'x'}));
421 EXPECT_EQ("YWI=", Base64({'a', 'b'}));
422 EXPECT_EQ("eHk=", Base64({'x', 'y'}));
423 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
424 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
425 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
426 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
427 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
428}
Ivan Krasindf919102016-01-22 22:28:27 +0000429
430TEST(Corpus, Distribution) {
Dan Liew1873a492016-06-07 23:32:50 +0000431 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
432 fuzzer::EF = t.get();
Kostya Serebryanya3992212016-02-13 03:00:53 +0000433 Random Rand(0);
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000434 MutationDispatcher MD(Rand, {});
435 Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {});
Ivan Krasindf919102016-01-22 22:28:27 +0000436 size_t N = 10;
437 size_t TriesPerUnit = 1<<20;
438 for (size_t i = 0; i < N; i++) {
439 Fuzz.AddToCorpus(Unit{ static_cast<uint8_t>(i) });
440 }
441 std::vector<size_t> Hist(N);
442 for (size_t i = 0; i < N * TriesPerUnit; i++) {
443 Hist[Fuzz.ChooseUnitIdxToMutate()]++;
444 }
445 for (size_t i = 0; i < N; i++) {
446 // A weak sanity check that every unit gets invoked.
447 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
448 }
449}