[libFuzzer] refactor the mutation functions so that they are now methods of a class...
[oota-llvm.git] / lib / Fuzzer / test / FuzzerUnittest.cpp
1 #include "FuzzerInternal.h"
2 #include "gtest/gtest.h"
3 #include <set>
4
5 using namespace fuzzer;
6
7 // For now, have LLVMFuzzerTestOneInput just to make it link.
8 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
9 extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
10   abort();
11 }
12
13 TEST(Fuzzer, CrossOver) {
14   FuzzerRandomLibc Rand(0);
15   MutationDispatcher MD(Rand);
16   Unit A({0, 1, 2}), B({5, 6, 7});
17   Unit C;
18   Unit Expected[] = {
19        { 0 },
20        { 0, 1 },
21        { 0, 5 },
22        { 0, 1, 2 },
23        { 0, 1, 5 },
24        { 0, 5, 1 },
25        { 0, 5, 6 },
26        { 0, 1, 2, 5 },
27        { 0, 1, 5, 2 },
28        { 0, 1, 5, 6 },
29        { 0, 5, 1, 2 },
30        { 0, 5, 1, 6 },
31        { 0, 5, 6, 1 },
32        { 0, 5, 6, 7 },
33        { 0, 1, 2, 5, 6 },
34        { 0, 1, 5, 2, 6 },
35        { 0, 1, 5, 6, 2 },
36        { 0, 1, 5, 6, 7 },
37        { 0, 5, 1, 2, 6 },
38        { 0, 5, 1, 6, 2 },
39        { 0, 5, 1, 6, 7 },
40        { 0, 5, 6, 1, 2 },
41        { 0, 5, 6, 1, 7 },
42        { 0, 5, 6, 7, 1 },
43        { 0, 1, 2, 5, 6, 7 },
44        { 0, 1, 5, 2, 6, 7 },
45        { 0, 1, 5, 6, 2, 7 },
46        { 0, 1, 5, 6, 7, 2 },
47        { 0, 5, 1, 2, 6, 7 },
48        { 0, 5, 1, 6, 2, 7 },
49        { 0, 5, 1, 6, 7, 2 },
50        { 0, 5, 6, 1, 2, 7 },
51        { 0, 5, 6, 1, 7, 2 },
52        { 0, 5, 6, 7, 1, 2 }
53   };
54   for (size_t Len = 1; Len < 8; Len++) {
55     std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
56     for (int Iter = 0; Iter < 3000; Iter++) {
57       C.resize(Len);
58       size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
59                                     C.data(), C.size());
60       C.resize(NewSize);
61       FoundUnits.insert(C);
62     }
63     for (const Unit &U : Expected)
64       if (U.size() <= Len)
65         ExpectedUnitsWitThisLength.insert(U);
66     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
67   }
68 }
69
70 TEST(Fuzzer, Hash) {
71   uint8_t A[] = {'a', 'b', 'c'};
72   fuzzer::Unit U(A, A + sizeof(A));
73   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
74   U.push_back('d');
75   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
76 }
77
78 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
79                                               size_t MaxSize);
80
81 void TestEraseByte(Mutator M, int NumIter) {
82   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
83   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
84   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
85   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
86   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
87   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
88   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
89   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
90   FuzzerRandomLibc Rand(0);
91   MutationDispatcher MD(Rand);
92   int FoundMask = 0;
93   for (int i = 0; i < NumIter; i++) {
94     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
95     size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
96     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
97     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
98     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
99     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
100     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
101     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
102     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
103     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
104   }
105   EXPECT_EQ(FoundMask, 255);
106 }
107
108 TEST(FuzzerMutate, EraseByte1) { TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100); }
109 TEST(FuzzerMutate, EraseByte2) { TestEraseByte(&MutationDispatcher::Mutate, 1000); }
110
111 void TestInsertByte(Mutator M, int NumIter) {
112   FuzzerRandomLibc Rand(0);
113   MutationDispatcher MD(Rand);
114   int FoundMask = 0;
115   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
116   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
117   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
118   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
119   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
120   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
121   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
122   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
123   for (int i = 0; i < NumIter; i++) {
124     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
125     size_t NewSize = (MD.*M)(T, 7, 8);
126     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
127     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
128     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
129     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
130     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
131     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
132     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
133     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
134   }
135   EXPECT_EQ(FoundMask, 255);
136 }
137
138 TEST(FuzzerMutate, InsertByte1) { TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15); }
139 TEST(FuzzerMutate, InsertByte2) { TestInsertByte(&MutationDispatcher::Mutate, 1 << 17); }
140
141 void TestChangeByte(Mutator M, int NumIter) {
142   FuzzerRandomLibc Rand(0);
143   MutationDispatcher MD(Rand);
144   int FoundMask = 0;
145   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
146   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
147   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
148   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
149   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
150   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
151   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
152   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
153   for (int i = 0; i < NumIter; i++) {
154     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
155     size_t NewSize = (MD.*M)(T, 8, 9);
156     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
157     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
158     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
159     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
160     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
161     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
162     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
163     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
164   }
165   EXPECT_EQ(FoundMask, 255);
166 }
167
168 TEST(FuzzerMutate, ChangeByte1) { TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15); }
169 TEST(FuzzerMutate, ChangeByte2) { TestChangeByte(&MutationDispatcher::Mutate, 1 << 17); }
170
171 void TestChangeBit(Mutator M, int NumIter) {
172   FuzzerRandomLibc Rand(0);
173   MutationDispatcher MD(Rand);
174   int FoundMask = 0;
175   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
176   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
177   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
178   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
179   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
180   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
181   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
182   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
183   for (int i = 0; i < NumIter; i++) {
184     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
185     size_t NewSize = (MD.*M)(T, 8, 9);
186     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
187     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
188     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
189     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
190     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
191     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
192     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
193     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
194   }
195   EXPECT_EQ(FoundMask, 255);
196 }
197
198 TEST(FuzzerMutate, ChangeBit1) { TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16); }
199 TEST(FuzzerMutate, ChangeBit2) { TestChangeBit(&MutationDispatcher::Mutate, 1 << 18); }
200
201 void TestShuffleBytes(Mutator M, int NumIter) {
202   FuzzerRandomLibc Rand(0);
203   MutationDispatcher MD(Rand);
204   int FoundMask = 0;
205   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
206   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
207   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
208   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
209   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
210   for (int i = 0; i < NumIter; i++) {
211     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
212     size_t NewSize = (MD.*M)(T, 7, 7);
213     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
214     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
215     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
216     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
217     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
218   }
219   EXPECT_EQ(FoundMask, 31);
220 }
221
222 TEST(FuzzerMutate, ShuffleBytes1) { TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 15); }
223 TEST(FuzzerMutate, ShuffleBytes2) { TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 16); }
224
225 TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
226   Unit U;
227   EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
228   EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
229   EXPECT_FALSE(ParseOneDictionaryEntry("\t  ", &U));
230   EXPECT_FALSE(ParseOneDictionaryEntry("  \" ", &U));
231   EXPECT_FALSE(ParseOneDictionaryEntry("  zz\" ", &U));
232   EXPECT_FALSE(ParseOneDictionaryEntry("  \"zz ", &U));
233   EXPECT_FALSE(ParseOneDictionaryEntry("  \"\" ", &U));
234   EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
235   EXPECT_EQ(U, Unit({'a'}));
236   EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
237   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
238   EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
239   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
240   EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
241   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
242   EXPECT_EQ(U, Unit({'\\'}));
243   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
244   EXPECT_EQ(U, Unit({0xAB}));
245   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
246   EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
247   EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
248   EXPECT_EQ(U, Unit({'#'}));
249   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
250   EXPECT_EQ(U, Unit({'"'}));
251 }
252
253 TEST(FuzzerDictionary, ParseDictionaryFile) {
254   std::vector<Unit> Units;
255   EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
256   EXPECT_FALSE(ParseDictionaryFile("", &Units));
257   EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
258   EXPECT_EQ(Units.size(), 0U);
259   EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
260   EXPECT_EQ(Units.size(), 0U);
261   EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
262   EXPECT_EQ(Units.size(), 0U);
263   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\n", &Units));
264   EXPECT_EQ(Units.size(), 0U);
265   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\naaa=\"aa\"", &Units));
266   EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
267   EXPECT_TRUE(
268       ParseDictionaryFile("  #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
269   EXPECT_EQ(Units,
270             std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
271 }