Home | History | Annotate | Line # | Download | only in tests
      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 // Do not attempt to use LLVM ostream from gtest.
      9 #define GTEST_NO_LLVM_RAW_OSTREAM 1
     10 
     11 #include "FuzzerCorpus.h"
     12 #include "FuzzerDictionary.h"
     13 #include "FuzzerInternal.h"
     14 #include "FuzzerMerge.h"
     15 #include "FuzzerMutate.h"
     16 #include "FuzzerRandom.h"
     17 #include "FuzzerTracePC.h"
     18 #include "gtest/gtest.h"
     19 #include <memory>
     20 #include <set>
     21 #include <sstream>
     22 
     23 using namespace fuzzer;
     24 
     25 // For now, have LLVMFuzzerTestOneInput just to make it link.
     26 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
     27 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
     28   abort();
     29 }
     30 
     31 TEST(Fuzzer, Basename) {
     32   EXPECT_EQ(Basename("foo/bar"), "bar");
     33   EXPECT_EQ(Basename("bar"), "bar");
     34   EXPECT_EQ(Basename("/bar"), "bar");
     35   EXPECT_EQ(Basename("foo/x"), "x");
     36   EXPECT_EQ(Basename("foo/"), "");
     37 #if LIBFUZZER_WINDOWS
     38   EXPECT_EQ(Basename("foo\\bar"), "bar");
     39   EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
     40   EXPECT_EQ(Basename("\\bar"), "bar");
     41   EXPECT_EQ(Basename("foo\\x"), "x");
     42   EXPECT_EQ(Basename("foo\\"), "");
     43 #endif
     44 }
     45 
     46 TEST(Fuzzer, CrossOver) {
     47   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
     48   fuzzer::EF = t.get();
     49   Random Rand(0);
     50   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
     51   Unit A({0, 1, 2}), B({5, 6, 7});
     52   Unit C;
     53   Unit Expected[] = {
     54        { 0 },
     55        { 0, 1 },
     56        { 0, 5 },
     57        { 0, 1, 2 },
     58        { 0, 1, 5 },
     59        { 0, 5, 1 },
     60        { 0, 5, 6 },
     61        { 0, 1, 2, 5 },
     62        { 0, 1, 5, 2 },
     63        { 0, 1, 5, 6 },
     64        { 0, 5, 1, 2 },
     65        { 0, 5, 1, 6 },
     66        { 0, 5, 6, 1 },
     67        { 0, 5, 6, 7 },
     68        { 0, 1, 2, 5, 6 },
     69        { 0, 1, 5, 2, 6 },
     70        { 0, 1, 5, 6, 2 },
     71        { 0, 1, 5, 6, 7 },
     72        { 0, 5, 1, 2, 6 },
     73        { 0, 5, 1, 6, 2 },
     74        { 0, 5, 1, 6, 7 },
     75        { 0, 5, 6, 1, 2 },
     76        { 0, 5, 6, 1, 7 },
     77        { 0, 5, 6, 7, 1 },
     78        { 0, 1, 2, 5, 6, 7 },
     79        { 0, 1, 5, 2, 6, 7 },
     80        { 0, 1, 5, 6, 2, 7 },
     81        { 0, 1, 5, 6, 7, 2 },
     82        { 0, 5, 1, 2, 6, 7 },
     83        { 0, 5, 1, 6, 2, 7 },
     84        { 0, 5, 1, 6, 7, 2 },
     85        { 0, 5, 6, 1, 2, 7 },
     86        { 0, 5, 6, 1, 7, 2 },
     87        { 0, 5, 6, 7, 1, 2 }
     88   };
     89   for (size_t Len = 1; Len < 8; Len++) {
     90     Set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
     91     for (int Iter = 0; Iter < 3000; Iter++) {
     92       C.resize(Len);
     93       size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
     94                                      C.data(), C.size());
     95       C.resize(NewSize);
     96       FoundUnits.insert(C);
     97     }
     98     for (const Unit &U : Expected)
     99       if (U.size() <= Len)
    100         ExpectedUnitsWitThisLength.insert(U);
    101     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
    102   }
    103 }
    104 
    105 TEST(Fuzzer, Hash) {
    106   uint8_t A[] = {'a', 'b', 'c'};
    107   fuzzer::Unit U(A, A + sizeof(A));
    108   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
    109   U.push_back('d');
    110   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
    111 }
    112 
    113 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
    114                                               size_t MaxSize);
    115 
    116 void TestEraseBytes(Mutator M, int NumIter) {
    117   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    118   fuzzer::EF = t.get();
    119   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    120   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    121   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
    122   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
    123   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
    124   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
    125   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
    126   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    127 
    128   uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    129   uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
    130   uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
    131 
    132   uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
    133   uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
    134   uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
    135 
    136 
    137   Random Rand(0);
    138   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    139   int FoundMask = 0;
    140   for (int i = 0; i < NumIter; i++) {
    141     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    142     size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
    143     if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
    144     if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
    145     if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
    146     if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
    147     if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
    148     if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
    149     if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
    150     if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
    151 
    152     if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
    153     if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
    154     if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
    155 
    156     if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
    157     if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
    158     if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
    159   }
    160   EXPECT_EQ(FoundMask, (1 << 14) - 1);
    161 }
    162 
    163 TEST(FuzzerMutate, EraseBytes1) {
    164   TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
    165 }
    166 TEST(FuzzerMutate, EraseBytes2) {
    167   TestEraseBytes(&MutationDispatcher::Mutate, 2000);
    168 }
    169 
    170 void TestInsertByte(Mutator M, int NumIter) {
    171   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    172   fuzzer::EF = t.get();
    173   Random Rand(0);
    174   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    175   int FoundMask = 0;
    176   uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    177   uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    178   uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
    179   uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
    180   uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
    181   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
    182   uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
    183   uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
    184   for (int i = 0; i < NumIter; i++) {
    185     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    186     size_t NewSize = (*MD.*M)(T, 7, 8);
    187     if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
    188     if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
    189     if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
    190     if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
    191     if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
    192     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
    193     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
    194     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
    195   }
    196   EXPECT_EQ(FoundMask, 255);
    197 }
    198 
    199 TEST(FuzzerMutate, InsertByte1) {
    200   TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
    201 }
    202 TEST(FuzzerMutate, InsertByte2) {
    203   TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
    204 }
    205 
    206 void TestInsertRepeatedBytes(Mutator M, int NumIter) {
    207   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    208   fuzzer::EF = t.get();
    209   Random Rand(0);
    210   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    211   int FoundMask = 0;
    212   uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
    213   uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
    214   uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
    215   uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
    216   uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
    217 
    218   uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
    219   uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
    220   uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
    221   uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
    222   uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
    223 
    224   for (int i = 0; i < NumIter; i++) {
    225     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
    226     size_t NewSize = (*MD.*M)(T, 4, 8);
    227     if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
    228     if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
    229     if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
    230     if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
    231     if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
    232 
    233     if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
    234     if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
    235     if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
    236     if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
    237     if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
    238 
    239   }
    240   EXPECT_EQ(FoundMask, (1 << 10) - 1);
    241 }
    242 
    243 TEST(FuzzerMutate, InsertRepeatedBytes1) {
    244   TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
    245 }
    246 TEST(FuzzerMutate, InsertRepeatedBytes2) {
    247   TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
    248 }
    249 
    250 void TestChangeByte(Mutator M, int NumIter) {
    251   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    252   fuzzer::EF = t.get();
    253   Random Rand(0);
    254   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    255   int FoundMask = 0;
    256   uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    257   uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    258   uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
    259   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
    260   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
    261   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
    262   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
    263   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
    264   for (int i = 0; i < NumIter; i++) {
    265     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    266     size_t NewSize = (*MD.*M)(T, 8, 9);
    267     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
    268     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
    269     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
    270     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
    271     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
    272     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
    273     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
    274     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
    275   }
    276   EXPECT_EQ(FoundMask, 255);
    277 }
    278 
    279 TEST(FuzzerMutate, ChangeByte1) {
    280   TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
    281 }
    282 TEST(FuzzerMutate, ChangeByte2) {
    283   TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
    284 }
    285 
    286 void TestChangeBit(Mutator M, int NumIter) {
    287   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    288   fuzzer::EF = t.get();
    289   Random Rand(0);
    290   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    291   int FoundMask = 0;
    292   uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    293   uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    294   uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
    295   uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
    296   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
    297   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
    298   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
    299   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
    300   for (int i = 0; i < NumIter; i++) {
    301     uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    302     size_t NewSize = (*MD.*M)(T, 8, 9);
    303     if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
    304     if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
    305     if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
    306     if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
    307     if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
    308     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
    309     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
    310     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
    311   }
    312   EXPECT_EQ(FoundMask, 255);
    313 }
    314 
    315 TEST(FuzzerMutate, ChangeBit1) {
    316   TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
    317 }
    318 TEST(FuzzerMutate, ChangeBit2) {
    319   TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
    320 }
    321 
    322 void TestShuffleBytes(Mutator M, int NumIter) {
    323   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    324   fuzzer::EF = t.get();
    325   Random Rand(0);
    326   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    327   int FoundMask = 0;
    328   uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
    329   uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
    330   uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
    331   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
    332   uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
    333   for (int i = 0; i < NumIter; i++) {
    334     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    335     size_t NewSize = (*MD.*M)(T, 7, 7);
    336     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
    337     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
    338     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
    339     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
    340     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
    341   }
    342   EXPECT_EQ(FoundMask, 31);
    343 }
    344 
    345 TEST(FuzzerMutate, ShuffleBytes1) {
    346   TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
    347 }
    348 TEST(FuzzerMutate, ShuffleBytes2) {
    349   TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
    350 }
    351 
    352 void TestCopyPart(Mutator M, int NumIter) {
    353   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    354   fuzzer::EF = t.get();
    355   Random Rand(0);
    356   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    357   int FoundMask = 0;
    358   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
    359   uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
    360   uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
    361   uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
    362   uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
    363 
    364   for (int i = 0; i < NumIter; i++) {
    365     uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
    366     size_t NewSize = (*MD.*M)(T, 7, 7);
    367     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
    368     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
    369     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
    370     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
    371     if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
    372   }
    373 
    374   uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
    375   uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
    376   uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
    377   uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
    378   uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
    379 
    380   for (int i = 0; i < NumIter; i++) {
    381     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    382     size_t NewSize = (*MD.*M)(T, 5, 8);
    383     if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
    384     if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
    385     if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
    386     if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
    387     if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
    388   }
    389 
    390   EXPECT_EQ(FoundMask, 1023);
    391 }
    392 
    393 TEST(FuzzerMutate, CopyPart1) {
    394   TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
    395 }
    396 TEST(FuzzerMutate, CopyPart2) {
    397   TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
    398 }
    399 TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) {
    400   // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an
    401   // insert on an input of size `MaxSize`.  Performing an insert in this case
    402   // will lead to the mutation failing.
    403   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    404   fuzzer::EF = t.get();
    405   Random Rand(0);
    406   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    407   uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
    408   size_t MaxSize = sizeof(Data);
    409   for (int count = 0; count < (1 << 18); ++count) {
    410     size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize);
    411     ASSERT_EQ(NewSize, MaxSize);
    412   }
    413 }
    414 
    415 void TestAddWordFromDictionary(Mutator M, int NumIter) {
    416   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    417   fuzzer::EF = t.get();
    418   Random Rand(0);
    419   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    420   uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
    421   uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
    422   MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
    423   MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
    424   int FoundMask = 0;
    425   uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
    426   uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
    427   uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
    428   uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
    429   uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
    430   uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
    431   uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
    432   uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
    433   for (int i = 0; i < NumIter; i++) {
    434     uint8_t T[7] = {0x00, 0x11, 0x22};
    435     size_t NewSize = (*MD.*M)(T, 3, 7);
    436     if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
    437     if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
    438     if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
    439     if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
    440     if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
    441     if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
    442     if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
    443     if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
    444   }
    445   EXPECT_EQ(FoundMask, 255);
    446 }
    447 
    448 TEST(FuzzerMutate, AddWordFromDictionary1) {
    449   TestAddWordFromDictionary(
    450       &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
    451 }
    452 
    453 TEST(FuzzerMutate, AddWordFromDictionary2) {
    454   TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
    455 }
    456 
    457 void TestChangeASCIIInteger(Mutator M, int NumIter) {
    458   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    459   fuzzer::EF = t.get();
    460   Random Rand(0);
    461   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    462 
    463   uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
    464   uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
    465   uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
    466   uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
    467   int FoundMask = 0;
    468   for (int i = 0; i < NumIter; i++) {
    469     uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
    470     size_t NewSize = (*MD.*M)(T, 8, 8);
    471     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
    472     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
    473     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
    474     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
    475     else if (NewSize == 8)                       FoundMask |= 1 << 4;
    476   }
    477   EXPECT_EQ(FoundMask, 31);
    478 }
    479 
    480 TEST(FuzzerMutate, ChangeASCIIInteger1) {
    481   TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
    482                          1 << 15);
    483 }
    484 
    485 TEST(FuzzerMutate, ChangeASCIIInteger2) {
    486   TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
    487 }
    488 
    489 void TestChangeBinaryInteger(Mutator M, int NumIter) {
    490   std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
    491   fuzzer::EF = t.get();
    492   Random Rand(0);
    493   std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
    494 
    495   uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
    496   uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
    497   uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    498   uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
    499   uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
    500   uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
    501   uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
    502   uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
    503 
    504   int FoundMask = 0;
    505   for (int i = 0; i < NumIter; i++) {
    506     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    507     size_t NewSize = (*MD.*M)(T, 8, 8);
    508     /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
    509     else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
    510     else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
    511     else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
    512     else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
    513     else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
    514     else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
    515     else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
    516   }
    517   EXPECT_EQ(FoundMask, 255);
    518 }
    519 
    520 TEST(FuzzerMutate, ChangeBinaryInteger1) {
    521   TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
    522                          1 << 12);
    523 }
    524 
    525 TEST(FuzzerMutate, ChangeBinaryInteger2) {
    526   TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
    527 }
    528 
    529 
    530 TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
    531   Unit U;
    532   EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
    533   EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
    534   EXPECT_FALSE(ParseOneDictionaryEntry("\t  ", &U));
    535   EXPECT_FALSE(ParseOneDictionaryEntry("  \" ", &U));
    536   EXPECT_FALSE(ParseOneDictionaryEntry("  zz\" ", &U));
    537   EXPECT_FALSE(ParseOneDictionaryEntry("  \"zz ", &U));
    538   EXPECT_FALSE(ParseOneDictionaryEntry("  \"\" ", &U));
    539   EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
    540   EXPECT_EQ(U, Unit({'a'}));
    541   EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
    542   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
    543   EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
    544   EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
    545   EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
    546   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
    547   EXPECT_EQ(U, Unit({'\\'}));
    548   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
    549   EXPECT_EQ(U, Unit({0xAB}));
    550   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
    551   EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
    552   EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
    553   EXPECT_EQ(U, Unit({'#'}));
    554   EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
    555   EXPECT_EQ(U, Unit({'"'}));
    556 }
    557 
    558 TEST(FuzzerDictionary, ParseDictionaryFile) {
    559   Vector<Unit> Units;
    560   EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
    561   EXPECT_FALSE(ParseDictionaryFile("", &Units));
    562   EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
    563   EXPECT_EQ(Units.size(), 0U);
    564   EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
    565   EXPECT_EQ(Units.size(), 0U);
    566   EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
    567   EXPECT_EQ(Units.size(), 0U);
    568   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\n", &Units));
    569   EXPECT_EQ(Units.size(), 0U);
    570   EXPECT_TRUE(ParseDictionaryFile("  #zzzz\naaa=\"aa\"", &Units));
    571   EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})}));
    572   EXPECT_TRUE(
    573       ParseDictionaryFile("  #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
    574   EXPECT_EQ(Units,
    575             Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
    576 }
    577 
    578 TEST(FuzzerUtil, Base64) {
    579   EXPECT_EQ("", Base64({}));
    580   EXPECT_EQ("YQ==", Base64({'a'}));
    581   EXPECT_EQ("eA==", Base64({'x'}));
    582   EXPECT_EQ("YWI=", Base64({'a', 'b'}));
    583   EXPECT_EQ("eHk=", Base64({'x', 'y'}));
    584   EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
    585   EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
    586   EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
    587   EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
    588   EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
    589 }
    590 
    591 TEST(Corpus, Distribution) {
    592   DataFlowTrace DFT;
    593   Random Rand(0);
    594   std::unique_ptr<InputCorpus> C(new InputCorpus(""));
    595   size_t N = 10;
    596   size_t TriesPerUnit = 1<<16;
    597   for (size_t i = 0; i < N; i++)
    598     C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, 1, false, false, {}, DFT,
    599                    nullptr);
    600 
    601   Vector<size_t> Hist(N);
    602   for (size_t i = 0; i < N * TriesPerUnit; i++) {
    603     Hist[C->ChooseUnitIdxToMutate(Rand)]++;
    604   }
    605   for (size_t i = 0; i < N; i++) {
    606     // A weak sanity check that every unit gets invoked.
    607     EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
    608   }
    609 }
    610 
    611 TEST(Merge, Bad) {
    612   const char *kInvalidInputs[] = {
    613     "",
    614     "x",
    615     "3\nx",
    616     "2\n3",
    617     "2\n2",
    618     "2\n2\nA\n",
    619     "2\n2\nA\nB\nC\n",
    620     "0\n0\n",
    621     "1\n1\nA\nDONE 0",
    622     "1\n1\nA\nSTARTED 1",
    623   };
    624   Merger M;
    625   for (auto S : kInvalidInputs) {
    626     // fprintf(stderr, "TESTING:\n%s\n", S);
    627     EXPECT_FALSE(M.Parse(S, false));
    628   }
    629 }
    630 
    631 void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
    632   EXPECT_EQ(A, B);
    633 }
    634 
    635 void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
    636   Set<std::string> a(A.begin(), A.end());
    637   Set<std::string> b(B.begin(), B.end());
    638   EXPECT_EQ(a, b);
    639 }
    640 
    641 static void Merge(const std::string &Input,
    642                   const Vector<std::string> Result,
    643                   size_t NumNewFeatures) {
    644   Merger M;
    645   Vector<std::string> NewFiles;
    646   EXPECT_TRUE(M.Parse(Input, true));
    647   std::stringstream SS;
    648   M.PrintSummary(SS);
    649   EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
    650   EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
    651   EQ(NewFiles, Result);
    652 }
    653 
    654 TEST(Merge, Good) {
    655   Merger M;
    656 
    657   EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
    658   EXPECT_EQ(M.Files.size(), 1U);
    659   EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
    660   EXPECT_EQ(M.Files[0].Name, "AA");
    661   EXPECT_TRUE(M.LastFailure.empty());
    662   EXPECT_EQ(M.FirstNotProcessedFile, 0U);
    663 
    664   EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
    665   EXPECT_EQ(M.Files.size(), 2U);
    666   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
    667   EXPECT_EQ(M.Files[0].Name, "AA");
    668   EXPECT_EQ(M.Files[1].Name, "BB");
    669   EXPECT_EQ(M.LastFailure, "AA");
    670   EXPECT_EQ(M.FirstNotProcessedFile, 1U);
    671 
    672   EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
    673                         "STARTED 0 1000\n"
    674                         "DONE 0 1 2 3\n"
    675                         "STARTED 1 1001\n"
    676                         "DONE 1 4 5 6 \n"
    677                         "STARTED 2 1002\n"
    678                         "", true));
    679   EXPECT_EQ(M.Files.size(), 3U);
    680   EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
    681   EXPECT_EQ(M.Files[0].Name, "AA");
    682   EXPECT_EQ(M.Files[0].Size, 1000U);
    683   EXPECT_EQ(M.Files[1].Name, "BB");
    684   EXPECT_EQ(M.Files[1].Size, 1001U);
    685   EXPECT_EQ(M.Files[2].Name, "C");
    686   EXPECT_EQ(M.Files[2].Size, 1002U);
    687   EXPECT_EQ(M.LastFailure, "C");
    688   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
    689   EQ(M.Files[0].Features, {1, 2, 3});
    690   EQ(M.Files[1].Features, {4, 5, 6});
    691 
    692 
    693   Vector<std::string> NewFiles;
    694 
    695   EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
    696                         "STARTED 0 1000\nDONE 0 1 2 3\n"
    697                         "STARTED 1 1001\nDONE 1 4 5 6 \n"
    698                         "STARTED 2 1002\nDONE 2 6 1 3 \n"
    699                         "", true));
    700   EXPECT_EQ(M.Files.size(), 3U);
    701   EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
    702   EXPECT_TRUE(M.LastFailure.empty());
    703   EXPECT_EQ(M.FirstNotProcessedFile, 3U);
    704   EQ(M.Files[0].Features, {1, 2, 3});
    705   EQ(M.Files[1].Features, {4, 5, 6});
    706   EQ(M.Files[2].Features, {1, 3, 6});
    707   EXPECT_EQ(0U, M.Merge(&NewFiles));
    708   EQ(NewFiles, {});
    709 
    710   EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
    711                         "STARTED 0 1000\nDONE 0 1 2 3\n"
    712                         "STARTED 1 1001\nDONE 1 4 5 6 \n"
    713                         "STARTED 2 1002\nDONE 2 6 1 3\n"
    714                         "", true));
    715   EQ(M.Files[0].Features, {1, 2, 3});
    716   EQ(M.Files[1].Features, {4, 5, 6});
    717   EQ(M.Files[2].Features, {1, 3, 6});
    718   EXPECT_EQ(3U, M.Merge(&NewFiles));
    719   EQ(NewFiles, {"B"});
    720 
    721   // Same as the above, but with InitialFeatures.
    722   EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
    723                         "STARTED 0 1001\nDONE 0 4 5 6 \n"
    724                         "STARTED 1 1002\nDONE 1 6 1 3\n"
    725                         "", true));
    726   EQ(M.Files[0].Features, {4, 5, 6});
    727   EQ(M.Files[1].Features, {1, 3, 6});
    728   Set<uint32_t> InitialFeatures;
    729   InitialFeatures.insert(1);
    730   InitialFeatures.insert(2);
    731   InitialFeatures.insert(3);
    732   EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFiles));
    733   EQ(NewFiles, {"B"});
    734 }
    735 
    736 TEST(Merge, Merge) {
    737 
    738   Merge("3\n1\nA\nB\nC\n"
    739         "STARTED 0 1000\nDONE 0 1 2 3\n"
    740         "STARTED 1 1001\nDONE 1 4 5 6 \n"
    741         "STARTED 2 1002\nDONE 2 6 1 3 \n",
    742         {"B"}, 3);
    743 
    744   Merge("3\n0\nA\nB\nC\n"
    745         "STARTED 0 2000\nDONE 0 1 2 3\n"
    746         "STARTED 1 1001\nDONE 1 4 5 6 \n"
    747         "STARTED 2 1002\nDONE 2 6 1 3 \n",
    748         {"A", "B", "C"}, 6);
    749 
    750   Merge("4\n0\nA\nB\nC\nD\n"
    751         "STARTED 0 2000\nDONE 0 1 2 3\n"
    752         "STARTED 1 1101\nDONE 1 4 5 6 \n"
    753         "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
    754         "STARTED 3 1000\nDONE 3 1  \n",
    755         {"A", "B", "C", "D"}, 7);
    756 
    757   Merge("4\n1\nA\nB\nC\nD\n"
    758         "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
    759         "STARTED 1 1100\nDONE 1 1 2 3 \n"
    760         "STARTED 2 1100\nDONE 2 2 3 \n"
    761         "STARTED 3 1000\nDONE 3 1  \n",
    762         {"B", "D"}, 3);
    763 }
    764 
    765 TEST(Fuzzer, ForEachNonZeroByte) {
    766   const size_t N = 64;
    767   alignas(64) uint8_t Ar[N + 8] = {
    768     0, 0, 0, 0, 0, 0, 0, 0,
    769     1, 2, 0, 0, 0, 0, 0, 0,
    770     0, 0, 3, 0, 4, 0, 0, 0,
    771     0, 0, 0, 0, 0, 0, 0, 0,
    772     0, 0, 0, 5, 0, 6, 0, 0,
    773     0, 0, 0, 0, 0, 0, 7, 0,
    774     0, 0, 0, 0, 0, 0, 0, 0,
    775     0, 0, 0, 0, 0, 0, 0, 8,
    776     9, 9, 9, 9, 9, 9, 9, 9,
    777   };
    778   typedef Vector<std::pair<size_t, uint8_t> > Vec;
    779   Vec Res, Expected;
    780   auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
    781     Res.push_back({FirstFeature + Idx, V});
    782   };
    783   ForEachNonZeroByte(Ar, Ar + N, 100, CB);
    784   Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
    785               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
    786   EXPECT_EQ(Res, Expected);
    787 
    788   Res.clear();
    789   ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
    790   Expected = {          {109, 2}, {118, 3}, {120, 4},
    791               {135, 5}, {137, 6}, {146, 7}, {163, 8}};
    792   EXPECT_EQ(Res, Expected);
    793 
    794   Res.clear();
    795   ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
    796   Expected = {          {109, 2}, {118, 3}, {120, 4},
    797               {135, 5}, {137, 6}, {146, 7}};
    798   EXPECT_EQ(Res, Expected);
    799 }
    800 
    801 // FuzzerCommand unit tests. The arguments in the two helper methods below must
    802 // match.
    803 static void makeCommandArgs(Vector<std::string> *ArgsToAdd) {
    804   assert(ArgsToAdd);
    805   ArgsToAdd->clear();
    806   ArgsToAdd->push_back("foo");
    807   ArgsToAdd->push_back("-bar=baz");
    808   ArgsToAdd->push_back("qux");
    809   ArgsToAdd->push_back(Command::ignoreRemainingArgs());
    810   ArgsToAdd->push_back("quux");
    811   ArgsToAdd->push_back("-grault=garply");
    812 }
    813 
    814 static std::string makeCmdLine(const char *separator, const char *suffix) {
    815   std::string CmdLine("foo -bar=baz qux ");
    816   if (strlen(separator) != 0) {
    817     CmdLine += separator;
    818     CmdLine += " ";
    819   }
    820   CmdLine += Command::ignoreRemainingArgs();
    821   CmdLine += " quux -grault=garply";
    822   if (strlen(suffix) != 0) {
    823     CmdLine += " ";
    824     CmdLine += suffix;
    825   }
    826   return CmdLine;
    827 }
    828 
    829 TEST(FuzzerCommand, Create) {
    830   std::string CmdLine;
    831 
    832   // Default constructor
    833   Command DefaultCmd;
    834 
    835   CmdLine = DefaultCmd.toString();
    836   EXPECT_EQ(CmdLine, "");
    837 
    838   // Explicit constructor
    839   Vector<std::string> ArgsToAdd;
    840   makeCommandArgs(&ArgsToAdd);
    841   Command InitializedCmd(ArgsToAdd);
    842 
    843   CmdLine = InitializedCmd.toString();
    844   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    845 
    846   // Compare each argument
    847   auto InitializedArgs = InitializedCmd.getArguments();
    848   auto i = ArgsToAdd.begin();
    849   auto j = InitializedArgs.begin();
    850   while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
    851     EXPECT_EQ(*i++, *j++);
    852   }
    853   EXPECT_EQ(i, ArgsToAdd.end());
    854   EXPECT_EQ(j, InitializedArgs.end());
    855 
    856   // Copy constructor
    857   Command CopiedCmd(InitializedCmd);
    858 
    859   CmdLine = CopiedCmd.toString();
    860   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    861 
    862   // Assignment operator
    863   Command AssignedCmd;
    864   AssignedCmd = CopiedCmd;
    865 
    866   CmdLine = AssignedCmd.toString();
    867   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    868 }
    869 
    870 TEST(FuzzerCommand, ModifyArguments) {
    871   Vector<std::string> ArgsToAdd;
    872   makeCommandArgs(&ArgsToAdd);
    873   Command Cmd;
    874   std::string CmdLine;
    875 
    876   Cmd.addArguments(ArgsToAdd);
    877   CmdLine = Cmd.toString();
    878   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    879 
    880   Cmd.addArgument("waldo");
    881   EXPECT_TRUE(Cmd.hasArgument("waldo"));
    882 
    883   CmdLine = Cmd.toString();
    884   EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
    885 
    886   Cmd.removeArgument("waldo");
    887   EXPECT_FALSE(Cmd.hasArgument("waldo"));
    888 
    889   CmdLine = Cmd.toString();
    890   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    891 }
    892 
    893 TEST(FuzzerCommand, ModifyFlags) {
    894   Vector<std::string> ArgsToAdd;
    895   makeCommandArgs(&ArgsToAdd);
    896   Command Cmd(ArgsToAdd);
    897   std::string Value, CmdLine;
    898   ASSERT_FALSE(Cmd.hasFlag("fred"));
    899 
    900   Value = Cmd.getFlagValue("fred");
    901   EXPECT_EQ(Value, "");
    902 
    903   CmdLine = Cmd.toString();
    904   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    905 
    906   Cmd.addFlag("fred", "plugh");
    907   EXPECT_TRUE(Cmd.hasFlag("fred"));
    908 
    909   Value = Cmd.getFlagValue("fred");
    910   EXPECT_EQ(Value, "plugh");
    911 
    912   CmdLine = Cmd.toString();
    913   EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
    914 
    915   Cmd.removeFlag("fred");
    916   EXPECT_FALSE(Cmd.hasFlag("fred"));
    917 
    918   Value = Cmd.getFlagValue("fred");
    919   EXPECT_EQ(Value, "");
    920 
    921   CmdLine = Cmd.toString();
    922   EXPECT_EQ(CmdLine, makeCmdLine("", ""));
    923 }
    924 
    925 TEST(FuzzerCommand, SetOutput) {
    926   Vector<std::string> ArgsToAdd;
    927   makeCommandArgs(&ArgsToAdd);
    928   Command Cmd(ArgsToAdd);
    929   std::string CmdLine;
    930   ASSERT_FALSE(Cmd.hasOutputFile());
    931   ASSERT_FALSE(Cmd.isOutAndErrCombined());
    932 
    933   Cmd.combineOutAndErr(true);
    934   EXPECT_TRUE(Cmd.isOutAndErrCombined());
    935 
    936   CmdLine = Cmd.toString();
    937   EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
    938 
    939   Cmd.combineOutAndErr(false);
    940   EXPECT_FALSE(Cmd.isOutAndErrCombined());
    941 
    942   Cmd.setOutputFile("xyzzy");
    943   EXPECT_TRUE(Cmd.hasOutputFile());
    944 
    945   CmdLine = Cmd.toString();
    946   EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
    947 
    948   Cmd.setOutputFile("thud");
    949   EXPECT_TRUE(Cmd.hasOutputFile());
    950 
    951   CmdLine = Cmd.toString();
    952   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
    953 
    954   Cmd.combineOutAndErr();
    955   EXPECT_TRUE(Cmd.isOutAndErrCombined());
    956 
    957   CmdLine = Cmd.toString();
    958   EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
    959 }
    960 
    961 int main(int argc, char **argv) {
    962   testing::InitGoogleTest(&argc, argv);
    963   return RUN_ALL_TESTS();
    964 }
    965