Home | History | Annotate | Download | only in test
      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