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