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