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