1 // 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 #include "FuzzerInternal.h" 9 #include "gtest/gtest.h" 10 #include <memory> 11 #include <set> 12 13 using namespace fuzzer; 14 15 // For now, have LLVMFuzzerTestOneInput just to make it link. 16 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput. 17 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 18 abort(); 19 } 20 21 TEST(Fuzzer, CrossOver) { 22 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 23 fuzzer::EF = t.get(); 24 Random Rand(0); 25 MutationDispatcher MD(Rand, {}); 26 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++) { 67 C.resize(Len); 68 size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(), 69 C.data(), C.size()); 70 C.resize(NewSize); 71 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 } 79 80 TEST(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 } 87 88 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size, 89 size_t MaxSize); 90 91 void TestEraseByte(Mutator M, int NumIter) { 92 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 93 fuzzer::EF = t.get(); 94 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}; 102 Random Rand(0); 103 MutationDispatcher MD(Rand, {}); 104 int FoundMask = 0; 105 for (int i = 0; i < NumIter; i++) { 106 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 107 size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T)); 108 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; 116 } 117 EXPECT_EQ(FoundMask, 255); 118 } 119 120 TEST(FuzzerMutate, EraseByte1) { 121 TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100); 122 } 123 TEST(FuzzerMutate, EraseByte2) { 124 TestEraseByte(&MutationDispatcher::Mutate, 1000); 125 } 126 127 void TestInsertByte(Mutator M, int NumIter) { 128 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 129 fuzzer::EF = t.get(); 130 Random Rand(0); 131 MutationDispatcher MD(Rand, {}); 132 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}; 143 size_t NewSize = (MD.*M)(T, 7, 8); 144 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 156 TEST(FuzzerMutate, InsertByte1) { 157 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15); 158 } 159 TEST(FuzzerMutate, InsertByte2) { 160 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17); 161 } 162 163 void TestChangeByte(Mutator M, int NumIter) { 164 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 165 fuzzer::EF = t.get(); 166 Random Rand(0); 167 MutationDispatcher MD(Rand, {}); 168 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}; 179 size_t NewSize = (MD.*M)(T, 8, 9); 180 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 192 TEST(FuzzerMutate, ChangeByte1) { 193 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15); 194 } 195 TEST(FuzzerMutate, ChangeByte2) { 196 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17); 197 } 198 199 void TestChangeBit(Mutator M, int NumIter) { 200 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 201 fuzzer::EF = t.get(); 202 Random Rand(0); 203 MutationDispatcher MD(Rand, {}); 204 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}; 215 size_t NewSize = (MD.*M)(T, 8, 9); 216 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 228 TEST(FuzzerMutate, ChangeBit1) { 229 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16); 230 } 231 TEST(FuzzerMutate, ChangeBit2) { 232 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18); 233 } 234 235 void TestShuffleBytes(Mutator M, int NumIter) { 236 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 237 fuzzer::EF = t.get(); 238 Random Rand(0); 239 MutationDispatcher MD(Rand, {}); 240 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}; 248 size_t NewSize = (MD.*M)(T, 7, 7); 249 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 258 TEST(FuzzerMutate, ShuffleBytes1) { 259 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16); 260 } 261 TEST(FuzzerMutate, ShuffleBytes2) { 262 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20); 263 } 264 265 void TestAddWordFromDictionary(Mutator M, int NumIter) { 266 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 267 fuzzer::EF = t.get(); 268 Random Rand(0); 269 MutationDispatcher MD(Rand, {}); 270 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD}; 271 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF}; 272 MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1))); 273 MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2))); 274 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 298 TEST(FuzzerMutate, AddWordFromDictionary1) { 299 TestAddWordFromDictionary( 300 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15); 301 } 302 303 TEST(FuzzerMutate, AddWordFromDictionary2) { 304 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15); 305 } 306 307 void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) { 308 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 309 fuzzer::EF = t.get(); 310 Random Rand(0); 311 MutationDispatcher MD(Rand, {}); 312 uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF}; 313 size_t PosHint = 7777; 314 MD.AddWordToAutoDictionary(Word(W, sizeof(W)), PosHint); 315 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); 320 if (NewSize >= PosHint + sizeof(W) && 321 !memcmp(W, T + PosHint, sizeof(W))) 322 FoundMask = 1; 323 } 324 EXPECT_EQ(FoundMask, 1); 325 } 326 327 TEST(FuzzerMutate, AddWordFromDictionaryWithHint1) { 328 TestAddWordFromDictionaryWithHint( 329 &MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary, 1 << 5); 330 } 331 332 TEST(FuzzerMutate, AddWordFromDictionaryWithHint2) { 333 TestAddWordFromDictionaryWithHint(&MutationDispatcher::Mutate, 1 << 10); 334 } 335 336 void TestChangeASCIIInteger(Mutator M, int NumIter) { 337 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 338 fuzzer::EF = t.get(); 339 Random Rand(0); 340 MutationDispatcher MD(Rand, {}); 341 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 359 TEST(FuzzerMutate, ChangeASCIIInteger1) { 360 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger, 361 1 << 15); 362 } 363 364 TEST(FuzzerMutate, ChangeASCIIInteger2) { 365 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15); 366 } 367 368 369 TEST(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 397 TEST(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 } 416 417 TEST(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 } 429 430 TEST(Corpus, Distribution) { 431 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 432 fuzzer::EF = t.get(); 433 Random Rand(0); 434 MutationDispatcher MD(Rand, {}); 435 Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {}); 436 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 } 450