518cfab5d9381968be3737bf6d31c094b15352a5
[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   Unit A({0, 1, 2}), B({5, 6, 7});
16   Unit C;
17   Unit Expected[] = {
18        { 0 },
19        { 0, 1 },
20        { 0, 5 },
21        { 0, 1, 2 },
22        { 0, 1, 5 },
23        { 0, 5, 1 },
24        { 0, 5, 6 },
25        { 0, 1, 2, 5 },
26        { 0, 1, 5, 2 },
27        { 0, 1, 5, 6 },
28        { 0, 5, 1, 2 },
29        { 0, 5, 1, 6 },
30        { 0, 5, 6, 1 },
31        { 0, 5, 6, 7 },
32        { 0, 1, 2, 5, 6 },
33        { 0, 1, 5, 2, 6 },
34        { 0, 1, 5, 6, 2 },
35        { 0, 1, 5, 6, 7 },
36        { 0, 5, 1, 2, 6 },
37        { 0, 5, 1, 6, 2 },
38        { 0, 5, 1, 6, 7 },
39        { 0, 5, 6, 1, 2 },
40        { 0, 5, 6, 1, 7 },
41        { 0, 5, 6, 7, 1 },
42        { 0, 1, 2, 5, 6, 7 },
43        { 0, 1, 5, 2, 6, 7 },
44        { 0, 1, 5, 6, 2, 7 },
45        { 0, 1, 5, 6, 7, 2 },
46        { 0, 5, 1, 2, 6, 7 },
47        { 0, 5, 1, 6, 2, 7 },
48        { 0, 5, 1, 6, 7, 2 },
49        { 0, 5, 6, 1, 2, 7 },
50        { 0, 5, 6, 1, 7, 2 },
51        { 0, 5, 6, 7, 1, 2 }
52   };
53   for (size_t Len = 1; Len < 8; Len++) {
54     std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
55     for (int Iter = 0; Iter < 3000; Iter++) {
56       C.resize(Len);
57       size_t NewSize = CrossOver(A.data(), A.size(), B.data(), B.size(),
58                                  C.data(), C.size(), Rand);
59       C.resize(NewSize);
60       FoundUnits.insert(C);
61     }
62     for (const Unit &U : Expected)
63       if (U.size() <= Len)
64         ExpectedUnitsWitThisLength.insert(U);
65     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
66   }
67 }
68
69 TEST(Fuzzer, Hash) {
70   uint8_t A[] = {'a', 'b', 'c'};
71   fuzzer::Unit U(A, A + sizeof(A));
72   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
73   U.push_back('d');
74   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
75 }
76
77 typedef size_t (*Mutator)(uint8_t *Data, size_t Size, size_t MaxSize,
78                           FuzzerRandomBase &Rand);
79
80 void TestEraseByte(Mutator M, int NumIter) {
81   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
82   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
83   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
84   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
85   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
86   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
87   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
88   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
89   FuzzerRandomLibc Rand(0);
90   int FoundMask = 0;
91   for (int i = 0; i < NumIter; i++) {
92     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
93     size_t NewSize = M(T, sizeof(T), sizeof(T), Rand);
94     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
95     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
96     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
97     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
98     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
99     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
100     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
101     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
102   }
103   EXPECT_EQ(FoundMask, 255);
104 }
105
106 TEST(FuzzerMutate, EraseByte1) { TestEraseByte(Mutate_EraseByte, 100); }
107 TEST(FuzzerMutate, EraseByte2) { TestEraseByte(Mutate, 1000); }
108
109 void TestInsertByte(Mutator M, int NumIter) {
110   FuzzerRandomLibc Rand(0);
111   int FoundMask = 0;
112   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
113   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
114   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
115   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
116   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
117   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
118   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
119   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
120   for (int i = 0; i < NumIter; i++) {
121     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
122     size_t NewSize = M(T, 7, 8, Rand);
123     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
124     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
125     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
126     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
127     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
128     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
129     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
130     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
131   }
132   EXPECT_EQ(FoundMask, 255);
133 }
134
135 TEST(FuzzerMutate, InsertByte1) { TestInsertByte(Mutate_InsertByte, 1 << 15); }
136 TEST(FuzzerMutate, InsertByte2) { TestInsertByte(Mutate, 1 << 17); }
137
138 void TestChangeByte(Mutator M, int NumIter) {
139   FuzzerRandomLibc Rand(0);
140   int FoundMask = 0;
141   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
142   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
143   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
144   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
145   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
146   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
147   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
148   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
149   for (int i = 0; i < NumIter; i++) {
150     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
151     size_t NewSize = M(T, 8, 9, Rand);
152     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
153     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
154     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
155     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
156     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
157     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
158     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
159     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
160   }
161   EXPECT_EQ(FoundMask, 255);
162 }
163
164 TEST(FuzzerMutate, ChangeByte1) { TestChangeByte(Mutate_ChangeByte, 1 << 15); }
165 TEST(FuzzerMutate, ChangeByte2) { TestChangeByte(Mutate, 1 << 17); }
166
167 void TestChangeBit(Mutator M, int NumIter) {
168   FuzzerRandomLibc Rand(0);
169   int FoundMask = 0;
170   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
171   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
172   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
173   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
174   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
175   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
176   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
177   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
178   for (int i = 0; i < NumIter; i++) {
179     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
180     size_t NewSize = M(T, 8, 9, Rand);
181     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
182     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
183     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
184     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
185     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
186     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
187     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
188     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
189   }
190   EXPECT_EQ(FoundMask, 255);
191 }
192
193 TEST(FuzzerMutate, ChangeBit1) { TestChangeBit(Mutate_ChangeBit, 1 << 16); }
194 TEST(FuzzerMutate, ChangeBit2) { TestChangeBit(Mutate, 1 << 18); }
195
196 void TestShuffleBytes(Mutator M, int NumIter) {
197   FuzzerRandomLibc Rand(0);
198   int FoundMask = 0;
199   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
200   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
201   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
202   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
203   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
204   for (int i = 0; i < NumIter; i++) {
205     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
206     size_t NewSize = M(T, 7, 7, Rand);
207     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
208     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
209     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
210     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
211     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
212   }
213   EXPECT_EQ(FoundMask, 31);
214 }
215
216 TEST(FuzzerMutate, ShuffleBytes1) { TestShuffleBytes(Mutate_ShuffleBytes, 1 << 15); }
217 TEST(FuzzerMutate, ShuffleBytes2) { TestShuffleBytes(Mutate, 1 << 16); }