1 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 2 // See https://llvm.org/LICENSE.txt for license information. 3 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 4 5 // Avoid ODR violations (LibFuzzer is built without ASan and this test is built 6 // with ASan) involving C++ standard library types when using libcxx. 7 #define _LIBCPP_HAS_NO_ASAN 8 9 // Do not attempt to use LLVM ostream etc from gtest. 10 #define GTEST_NO_LLVM_SUPPORT 1 11 12 #include "FuzzerCorpus.h" 13 #include "FuzzerDictionary.h" 14 #include "FuzzerInternal.h" 15 #include "FuzzerMerge.h" 16 #include "FuzzerMutate.h" 17 #include "FuzzerRandom.h" 18 #include "FuzzerTracePC.h" 19 #include "gtest/gtest.h" 20 #include <memory> 21 #include <set> 22 #include <sstream> 23 24 using namespace fuzzer; 25 26 // For now, have LLVMFuzzerTestOneInput just to make it link. 27 // Later we may want to make unittests that actually call 28 // LLVMFuzzerTestOneInput. 29 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 30 abort(); 31 } 32 33 TEST(Fuzzer, Basename) { 34 EXPECT_EQ(Basename("foo/bar"), "bar"); 35 EXPECT_EQ(Basename("bar"), "bar"); 36 EXPECT_EQ(Basename("/bar"), "bar"); 37 EXPECT_EQ(Basename("foo/x"), "x"); 38 EXPECT_EQ(Basename("foo/"), ""); 39 #if LIBFUZZER_WINDOWS 40 EXPECT_EQ(Basename("foo\\bar"), "bar"); 41 EXPECT_EQ(Basename("foo\\bar/baz"), "baz"); 42 EXPECT_EQ(Basename("\\bar"), "bar"); 43 EXPECT_EQ(Basename("foo\\x"), "x"); 44 EXPECT_EQ(Basename("foo\\"), ""); 45 #endif 46 } 47 48 TEST(Fuzzer, CrossOver) { 49 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 50 fuzzer::EF = t.get(); 51 Random Rand(0); 52 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 53 Unit A({0, 1, 2}), B({5, 6, 7}); 54 Unit C; 55 Unit Expected[] = { 56 { 0 }, 57 { 0, 1 }, 58 { 0, 5 }, 59 { 0, 1, 2 }, 60 { 0, 1, 5 }, 61 { 0, 5, 1 }, 62 { 0, 5, 6 }, 63 { 0, 1, 2, 5 }, 64 { 0, 1, 5, 2 }, 65 { 0, 1, 5, 6 }, 66 { 0, 5, 1, 2 }, 67 { 0, 5, 1, 6 }, 68 { 0, 5, 6, 1 }, 69 { 0, 5, 6, 7 }, 70 { 0, 1, 2, 5, 6 }, 71 { 0, 1, 5, 2, 6 }, 72 { 0, 1, 5, 6, 2 }, 73 { 0, 1, 5, 6, 7 }, 74 { 0, 5, 1, 2, 6 }, 75 { 0, 5, 1, 6, 2 }, 76 { 0, 5, 1, 6, 7 }, 77 { 0, 5, 6, 1, 2 }, 78 { 0, 5, 6, 1, 7 }, 79 { 0, 5, 6, 7, 1 }, 80 { 0, 1, 2, 5, 6, 7 }, 81 { 0, 1, 5, 2, 6, 7 }, 82 { 0, 1, 5, 6, 2, 7 }, 83 { 0, 1, 5, 6, 7, 2 }, 84 { 0, 5, 1, 2, 6, 7 }, 85 { 0, 5, 1, 6, 2, 7 }, 86 { 0, 5, 1, 6, 7, 2 }, 87 { 0, 5, 6, 1, 2, 7 }, 88 { 0, 5, 6, 1, 7, 2 }, 89 { 0, 5, 6, 7, 1, 2 } 90 }; 91 for (size_t Len = 1; Len < 8; Len++) { 92 std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength; 93 for (int Iter = 0; Iter < 3000; Iter++) { 94 C.resize(Len); 95 size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(), 96 C.data(), C.size()); 97 C.resize(NewSize); 98 FoundUnits.insert(C); 99 } 100 for (const Unit &U : Expected) 101 if (U.size() <= Len) 102 ExpectedUnitsWitThisLength.insert(U); 103 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits); 104 } 105 } 106 107 TEST(Fuzzer, Hash) { 108 uint8_t A[] = {'a', 'b', 'c'}; 109 fuzzer::Unit U(A, A + sizeof(A)); 110 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U)); 111 U.push_back('d'); 112 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U)); 113 } 114 115 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size, 116 size_t MaxSize); 117 118 void TestEraseBytes(Mutator M, int NumIter) { 119 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 120 fuzzer::EF = t.get(); 121 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 122 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 123 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77}; 124 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77}; 125 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77}; 126 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77}; 127 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77}; 128 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 129 130 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 131 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; 132 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77}; 133 134 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77}; 135 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44}; 136 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77}; 137 138 139 Random Rand(0); 140 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 141 int FoundMask = 0; 142 for (int i = 0; i < NumIter; i++) { 143 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 144 size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T)); 145 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0; 146 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1; 147 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2; 148 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3; 149 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4; 150 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5; 151 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6; 152 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7; 153 154 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8; 155 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9; 156 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10; 157 158 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11; 159 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12; 160 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13; 161 } 162 EXPECT_EQ(FoundMask, (1 << 14) - 1); 163 } 164 165 TEST(FuzzerMutate, EraseBytes1) { 166 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200); 167 } 168 TEST(FuzzerMutate, EraseBytes2) { 169 TestEraseBytes(&MutationDispatcher::Mutate, 2000); 170 } 171 172 void TestInsertByte(Mutator M, int NumIter) { 173 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 174 fuzzer::EF = t.get(); 175 Random Rand(0); 176 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 177 int FoundMask = 0; 178 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 179 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 180 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66}; 181 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66}; 182 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66}; 183 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66}; 184 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66}; 185 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8}; 186 for (int i = 0; i < NumIter; i++) { 187 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 188 size_t NewSize = (*MD.*M)(T, 7, 8); 189 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0; 190 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1; 191 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2; 192 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3; 193 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4; 194 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5; 195 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6; 196 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7; 197 } 198 EXPECT_EQ(FoundMask, 255); 199 } 200 201 TEST(FuzzerMutate, InsertByte1) { 202 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15); 203 } 204 TEST(FuzzerMutate, InsertByte2) { 205 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17); 206 } 207 208 void TestInsertRepeatedBytes(Mutator M, int NumIter) { 209 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 210 fuzzer::EF = t.get(); 211 Random Rand(0); 212 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 213 int FoundMask = 0; 214 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'}; 215 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33}; 216 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33}; 217 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33}; 218 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33}; 219 220 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'}; 221 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33}; 222 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33}; 223 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33}; 224 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33}; 225 226 for (int i = 0; i < NumIter; i++) { 227 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33}; 228 size_t NewSize = (*MD.*M)(T, 4, 8); 229 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0; 230 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1; 231 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2; 232 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3; 233 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4; 234 235 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5; 236 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6; 237 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7; 238 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8; 239 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9; 240 241 } 242 EXPECT_EQ(FoundMask, (1 << 10) - 1); 243 } 244 245 TEST(FuzzerMutate, InsertRepeatedBytes1) { 246 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 247 10000); 248 } 249 TEST(FuzzerMutate, InsertRepeatedBytes2) { 250 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000); 251 } 252 253 void TestChangeByte(Mutator M, int NumIter) { 254 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 255 fuzzer::EF = t.get(); 256 Random Rand(0); 257 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 258 int FoundMask = 0; 259 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 260 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 261 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77}; 262 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77}; 263 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77}; 264 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77}; 265 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77}; 266 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; 267 for (int i = 0; i < NumIter; i++) { 268 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 269 size_t NewSize = (*MD.*M)(T, 8, 9); 270 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 271 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 272 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 273 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 274 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 275 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 276 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 277 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 278 } 279 EXPECT_EQ(FoundMask, 255); 280 } 281 282 TEST(FuzzerMutate, ChangeByte1) { 283 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15); 284 } 285 TEST(FuzzerMutate, ChangeByte2) { 286 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17); 287 } 288 289 void TestChangeBit(Mutator M, int NumIter) { 290 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 291 fuzzer::EF = t.get(); 292 Random Rand(0); 293 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 294 int FoundMask = 0; 295 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 296 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 297 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77}; 298 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77}; 299 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77}; 300 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77}; 301 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77}; 302 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; 303 for (int i = 0; i < NumIter; i++) { 304 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 305 size_t NewSize = (*MD.*M)(T, 8, 9); 306 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 307 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 308 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 309 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 310 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 311 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 312 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 313 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 314 } 315 EXPECT_EQ(FoundMask, 255); 316 } 317 318 TEST(FuzzerMutate, ChangeBit1) { 319 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16); 320 } 321 TEST(FuzzerMutate, ChangeBit2) { 322 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18); 323 } 324 325 void TestShuffleBytes(Mutator M, int NumIter) { 326 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 327 fuzzer::EF = t.get(); 328 Random Rand(0); 329 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 330 int FoundMask = 0; 331 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66}; 332 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66}; 333 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66}; 334 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33}; 335 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66}; 336 for (int i = 0; i < NumIter; i++) { 337 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 338 size_t NewSize = (*MD.*M)(T, 7, 7); 339 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 340 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 341 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 342 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 343 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4; 344 } 345 EXPECT_EQ(FoundMask, 31); 346 } 347 348 TEST(FuzzerMutate, ShuffleBytes1) { 349 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17); 350 } 351 TEST(FuzzerMutate, ShuffleBytes2) { 352 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20); 353 } 354 355 void TestCopyPart(Mutator M, int NumIter) { 356 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 357 fuzzer::EF = t.get(); 358 Random Rand(0); 359 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 360 int FoundMask = 0; 361 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11}; 362 uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66}; 363 uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66}; 364 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66}; 365 uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66}; 366 367 for (int i = 0; i < NumIter; i++) { 368 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 369 size_t NewSize = (*MD.*M)(T, 7, 7); 370 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 371 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 372 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 373 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 374 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4; 375 } 376 377 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22}; 378 uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44}; 379 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44}; 380 uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44}; 381 uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44}; 382 383 for (int i = 0; i < NumIter; i++) { 384 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 385 size_t NewSize = (*MD.*M)(T, 5, 8); 386 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 387 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 388 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 389 if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8; 390 if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9; 391 } 392 393 EXPECT_EQ(FoundMask, 1023); 394 } 395 396 TEST(FuzzerMutate, CopyPart1) { 397 TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10); 398 } 399 TEST(FuzzerMutate, CopyPart2) { 400 TestCopyPart(&MutationDispatcher::Mutate, 1 << 13); 401 } 402 TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) { 403 // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an 404 // insert on an input of size `MaxSize`. Performing an insert in this case 405 // will lead to the mutation failing. 406 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 407 fuzzer::EF = t.get(); 408 Random Rand(0); 409 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 410 uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22}; 411 size_t MaxSize = sizeof(Data); 412 for (int count = 0; count < (1 << 18); ++count) { 413 size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize); 414 ASSERT_EQ(NewSize, MaxSize); 415 } 416 } 417 418 void TestAddWordFromDictionary(Mutator M, int NumIter) { 419 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 420 fuzzer::EF = t.get(); 421 Random Rand(0); 422 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 423 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD}; 424 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF}; 425 MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1))); 426 MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2))); 427 int FoundMask = 0; 428 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD}; 429 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22}; 430 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22}; 431 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22}; 432 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF}; 433 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22}; 434 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22}; 435 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22}; 436 for (int i = 0; i < NumIter; i++) { 437 uint8_t T[7] = {0x00, 0x11, 0x22}; 438 size_t NewSize = (*MD.*M)(T, 3, 7); 439 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 440 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 441 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 442 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 443 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4; 444 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5; 445 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6; 446 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7; 447 } 448 EXPECT_EQ(FoundMask, 255); 449 } 450 451 TEST(FuzzerMutate, AddWordFromDictionary1) { 452 TestAddWordFromDictionary( 453 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15); 454 } 455 456 TEST(FuzzerMutate, AddWordFromDictionary2) { 457 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15); 458 } 459 460 void TestChangeASCIIInteger(Mutator M, int NumIter) { 461 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 462 fuzzer::EF = t.get(); 463 Random Rand(0); 464 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 465 466 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'}; 467 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'}; 468 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'}; 469 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'}; 470 int FoundMask = 0; 471 for (int i = 0; i < NumIter; i++) { 472 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'}; 473 size_t NewSize = (*MD.*M)(T, 8, 8); 474 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 475 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 476 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 477 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 478 else if (NewSize == 8) FoundMask |= 1 << 4; 479 } 480 EXPECT_EQ(FoundMask, 31); 481 } 482 483 TEST(FuzzerMutate, ChangeASCIIInteger1) { 484 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger, 485 1 << 15); 486 } 487 488 TEST(FuzzerMutate, ChangeASCIIInteger2) { 489 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15); 490 } 491 492 void TestChangeBinaryInteger(Mutator M, int NumIter) { 493 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 494 fuzzer::EF = t.get(); 495 Random Rand(0); 496 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 497 498 uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79}; 499 uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77}; 500 uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 501 uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77}; 502 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77}; 503 uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; 504 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size 505 uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size) 506 507 int FoundMask = 0; 508 for (int i = 0; i < NumIter; i++) { 509 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 510 size_t NewSize = (*MD.*M)(T, 8, 8); 511 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 512 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 513 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 514 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 515 else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 516 else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 517 else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 518 else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 519 } 520 EXPECT_EQ(FoundMask, 255); 521 } 522 523 TEST(FuzzerMutate, ChangeBinaryInteger1) { 524 TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger, 525 1 << 12); 526 } 527 528 TEST(FuzzerMutate, ChangeBinaryInteger2) { 529 TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15); 530 } 531 532 533 TEST(FuzzerDictionary, ParseOneDictionaryEntry) { 534 Unit U; 535 EXPECT_FALSE(ParseOneDictionaryEntry("", &U)); 536 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U)); 537 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U)); 538 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U)); 539 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U)); 540 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U)); 541 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U)); 542 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U)); 543 EXPECT_EQ(U, Unit({'a'})); 544 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U)); 545 EXPECT_EQ(U, Unit({'a', 'b', 'c'})); 546 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U)); 547 EXPECT_EQ(U, Unit({'a', 'b', 'c'})); 548 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U)); 549 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U)); 550 EXPECT_EQ(U, Unit({'\\'})); 551 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U)); 552 EXPECT_EQ(U, Unit({0xAB})); 553 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U)); 554 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE})); 555 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U)); 556 EXPECT_EQ(U, Unit({'#'})); 557 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U)); 558 EXPECT_EQ(U, Unit({'"'})); 559 } 560 561 TEST(FuzzerDictionary, ParseDictionaryFile) { 562 std::vector<Unit> Units; 563 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units)); 564 EXPECT_FALSE(ParseDictionaryFile("", &Units)); 565 EXPECT_TRUE(ParseDictionaryFile("\n", &Units)); 566 EXPECT_EQ(Units.size(), 0U); 567 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units)); 568 EXPECT_EQ(Units.size(), 0U); 569 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units)); 570 EXPECT_EQ(Units.size(), 0U); 571 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units)); 572 EXPECT_EQ(Units.size(), 0U); 573 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units)); 574 EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})})); 575 EXPECT_TRUE( 576 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units)); 577 EXPECT_EQ(Units, 578 std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})})); 579 } 580 581 TEST(FuzzerUtil, Base64) { 582 EXPECT_EQ("", Base64({})); 583 EXPECT_EQ("YQ==", Base64({'a'})); 584 EXPECT_EQ("eA==", Base64({'x'})); 585 EXPECT_EQ("YWI=", Base64({'a', 'b'})); 586 EXPECT_EQ("eHk=", Base64({'x', 'y'})); 587 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'})); 588 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'})); 589 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'})); 590 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'})); 591 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'})); 592 } 593 594 #ifdef __GLIBC__ 595 class PrintfCapture { 596 public: 597 PrintfCapture() { 598 OldOutputFile = GetOutputFile(); 599 SetOutputFile(open_memstream(&Buffer, &Size)); 600 } 601 ~PrintfCapture() { 602 fclose(GetOutputFile()); 603 SetOutputFile(OldOutputFile); 604 free(Buffer); 605 } 606 std::string str() { return std::string(Buffer, Size); } 607 608 private: 609 char *Buffer; 610 size_t Size; 611 FILE *OldOutputFile; 612 }; 613 614 TEST(FuzzerUtil, PrintASCII) { 615 auto f = [](const char *Str, const char *PrintAfter = "") { 616 PrintfCapture Capture; 617 PrintASCII(reinterpret_cast<const uint8_t*>(Str), strlen(Str), PrintAfter); 618 return Capture.str(); 619 }; 620 EXPECT_EQ("hello", f("hello")); 621 EXPECT_EQ("c:\\\\", f("c:\\")); 622 EXPECT_EQ("\\\"hi\\\"", f("\"hi\"")); 623 EXPECT_EQ("\\011a", f("\ta")); 624 EXPECT_EQ("\\0111", f("\t1")); 625 EXPECT_EQ("hello\\012", f("hello\n")); 626 EXPECT_EQ("hello\n", f("hello", "\n")); 627 } 628 #endif 629 630 TEST(Corpus, Distribution) { 631 DataFlowTrace DFT; 632 Random Rand(0); 633 struct EntropicOptions Entropic = {false, 0xFF, 100, false}; 634 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 635 size_t N = 10; 636 size_t TriesPerUnit = 1<<16; 637 for (size_t i = 0; i < N; i++) 638 C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, /*NumFeatures*/ 1, 639 /*MayDeleteFile*/ false, /*HasFocusFunction*/ false, 640 /*ForceAddToCorpus*/ false, 641 /*TimeOfUnit*/ std::chrono::microseconds(0), 642 /*FeatureSet*/ {}, DFT, 643 /*BaseII*/ nullptr); 644 645 std::vector<size_t> Hist(N); 646 for (size_t i = 0; i < N * TriesPerUnit; i++) { 647 Hist[C->ChooseUnitIdxToMutate(Rand)]++; 648 } 649 for (size_t i = 0; i < N; i++) { 650 // A weak sanity check that every unit gets invoked. 651 EXPECT_GT(Hist[i], TriesPerUnit / N / 3); 652 } 653 } 654 655 TEST(Corpus, Replace) { 656 DataFlowTrace DFT; 657 struct EntropicOptions Entropic = {false, 0xFF, 100, false}; 658 std::unique_ptr<InputCorpus> C( 659 new InputCorpus(/*OutputCorpus*/ "", Entropic)); 660 InputInfo *FirstII = 661 C->AddToCorpus(Unit{0x01, 0x00}, /*NumFeatures*/ 1, 662 /*MayDeleteFile*/ false, /*HasFocusFunction*/ false, 663 /*ForceAddToCorpus*/ false, 664 /*TimeOfUnit*/ std::chrono::microseconds(1234), 665 /*FeatureSet*/ {}, DFT, 666 /*BaseII*/ nullptr); 667 InputInfo *SecondII = 668 C->AddToCorpus(Unit{0x02}, /*NumFeatures*/ 1, 669 /*MayDeleteFile*/ false, /*HasFocusFunction*/ false, 670 /*ForceAddToCorpus*/ false, 671 /*TimeOfUnit*/ std::chrono::microseconds(5678), 672 /*FeatureSet*/ {}, DFT, 673 /*BaseII*/ nullptr); 674 (void) SecondII; 675 Unit ReplacedU = Unit{0x03}; 676 677 C->Replace(FirstII, ReplacedU, 678 /*TimeOfUnit*/ std::chrono::microseconds(321)); 679 680 EXPECT_EQ(FirstII->U, Unit{0x03}); 681 EXPECT_EQ(FirstII->Reduced, true); 682 EXPECT_EQ(FirstII->TimeOfUnit, std::chrono::microseconds(321)); 683 std::vector<uint8_t> ExpectedSha1(kSHA1NumBytes); 684 ComputeSHA1(ReplacedU.data(), ReplacedU.size(), ExpectedSha1.data()); 685 std::vector<uint8_t> IISha1(FirstII->Sha1, FirstII->Sha1 + kSHA1NumBytes); 686 EXPECT_EQ(IISha1, ExpectedSha1); 687 } 688 689 template <typename T> 690 void EQ(const std::vector<T> &A, const std::vector<T> &B) { 691 EXPECT_EQ(A, B); 692 } 693 694 template <typename T> void EQ(const std::set<T> &A, const std::vector<T> &B) { 695 EXPECT_EQ(A, std::set<T>(B.begin(), B.end())); 696 } 697 698 void EQ(const std::vector<MergeFileInfo> &A, 699 const std::vector<std::string> &B) { 700 std::set<std::string> a; 701 for (const auto &File : A) 702 a.insert(File.Name); 703 std::set<std::string> b(B.begin(), B.end()); 704 EXPECT_EQ(a, b); 705 } 706 707 #define TRACED_EQ(A, ...) \ 708 { \ 709 SCOPED_TRACE(#A); \ 710 EQ(A, __VA_ARGS__); \ 711 } 712 713 TEST(Merger, Parse) { 714 Merger M; 715 716 const char *kInvalidInputs[] = { 717 // Bad file numbers 718 "", 719 "x", 720 "0\n0", 721 "3\nx", 722 "2\n3", 723 "2\n2", 724 // Bad file names 725 "2\n2\nA\n", 726 "2\n2\nA\nB\nC\n", 727 // Unknown markers 728 "2\n1\nA\nSTARTED 0\nBAD 0 0x0", 729 // Bad file IDs 730 "1\n1\nA\nSTARTED 1", 731 "2\n1\nA\nSTARTED 0\nFT 1 0x0", 732 }; 733 for (auto S : kInvalidInputs) { 734 SCOPED_TRACE(S); 735 EXPECT_FALSE(M.Parse(S, false)); 736 } 737 738 // Parse initial control file 739 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false)); 740 ASSERT_EQ(M.Files.size(), 1U); 741 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U); 742 EXPECT_EQ(M.Files[0].Name, "AA"); 743 EXPECT_TRUE(M.LastFailure.empty()); 744 EXPECT_EQ(M.FirstNotProcessedFile, 0U); 745 746 // Parse control file that failed on first attempt 747 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false)); 748 ASSERT_EQ(M.Files.size(), 2U); 749 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U); 750 EXPECT_EQ(M.Files[0].Name, "AA"); 751 EXPECT_EQ(M.Files[1].Name, "BB"); 752 EXPECT_EQ(M.LastFailure, "AA"); 753 EXPECT_EQ(M.FirstNotProcessedFile, 1U); 754 755 // Parse control file that failed on later attempt 756 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n" 757 "STARTED 0 1000\n" 758 "FT 0 1 2 3\n" 759 "STARTED 1 1001\n" 760 "FT 1 4 5 6 \n" 761 "STARTED 2 1002\n" 762 "", 763 true)); 764 ASSERT_EQ(M.Files.size(), 3U); 765 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U); 766 EXPECT_EQ(M.Files[0].Name, "AA"); 767 EXPECT_EQ(M.Files[0].Size, 1000U); 768 EXPECT_EQ(M.Files[1].Name, "BB"); 769 EXPECT_EQ(M.Files[1].Size, 1001U); 770 EXPECT_EQ(M.Files[2].Name, "C"); 771 EXPECT_EQ(M.Files[2].Size, 1002U); 772 EXPECT_EQ(M.LastFailure, "C"); 773 EXPECT_EQ(M.FirstNotProcessedFile, 3U); 774 TRACED_EQ(M.Files[0].Features, {1, 2, 3}); 775 TRACED_EQ(M.Files[1].Features, {4, 5, 6}); 776 777 // Parse control file without features or PCs 778 EXPECT_TRUE(M.Parse("2\n0\nAA\nBB\n" 779 "STARTED 0 1000\n" 780 "FT 0\n" 781 "COV 0\n" 782 "STARTED 1 1001\n" 783 "FT 1\n" 784 "COV 1\n" 785 "", 786 true)); 787 ASSERT_EQ(M.Files.size(), 2U); 788 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U); 789 EXPECT_TRUE(M.LastFailure.empty()); 790 EXPECT_EQ(M.FirstNotProcessedFile, 2U); 791 EXPECT_TRUE(M.Files[0].Features.empty()); 792 EXPECT_TRUE(M.Files[0].Cov.empty()); 793 EXPECT_TRUE(M.Files[1].Features.empty()); 794 EXPECT_TRUE(M.Files[1].Cov.empty()); 795 796 // Parse features and PCs 797 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n" 798 "STARTED 0 1000\n" 799 "FT 0 1 2 3\n" 800 "COV 0 11 12 13\n" 801 "STARTED 1 1001\n" 802 "FT 1 4 5 6\n" 803 "COV 1 7 8 9\n" 804 "STARTED 2 1002\n" 805 "FT 2 6 1 3\n" 806 "COV 2 16 11 13\n" 807 "", 808 true)); 809 ASSERT_EQ(M.Files.size(), 3U); 810 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U); 811 EXPECT_TRUE(M.LastFailure.empty()); 812 EXPECT_EQ(M.FirstNotProcessedFile, 3U); 813 TRACED_EQ(M.Files[0].Features, {1, 2, 3}); 814 TRACED_EQ(M.Files[0].Cov, {11, 12, 13}); 815 TRACED_EQ(M.Files[1].Features, {4, 5, 6}); 816 TRACED_EQ(M.Files[1].Cov, {7, 8, 9}); 817 TRACED_EQ(M.Files[2].Features, {1, 3, 6}); 818 TRACED_EQ(M.Files[2].Cov, {16}); 819 } 820 821 TEST(Merger, Merge) { 822 Merger M; 823 std::set<uint32_t> Features, NewFeatures; 824 std::set<uint32_t> Cov, NewCov; 825 std::vector<std::string> NewFiles; 826 827 // Adds new files and features 828 EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n" 829 "STARTED 0 1000\n" 830 "FT 0 1 2 3\n" 831 "STARTED 1 1001\n" 832 "FT 1 4 5 6 \n" 833 "STARTED 2 1002\n" 834 "FT 2 6 1 3\n" 835 "", 836 true)); 837 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 6U); 838 TRACED_EQ(M.Files, {"A", "B", "C"}); 839 TRACED_EQ(NewFiles, {"A", "B"}); 840 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6}); 841 842 // Doesn't return features or files in the initial corpus. 843 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n" 844 "STARTED 0 1000\n" 845 "FT 0 1 2 3\n" 846 "STARTED 1 1001\n" 847 "FT 1 4 5 6 \n" 848 "STARTED 2 1002\n" 849 "FT 2 6 1 3\n" 850 "", 851 true)); 852 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U); 853 TRACED_EQ(M.Files, {"A", "B", "C"}); 854 TRACED_EQ(NewFiles, {"B"}); 855 TRACED_EQ(NewFeatures, {4, 5, 6}); 856 857 // No new features, so no new files 858 EXPECT_TRUE(M.Parse("3\n2\nA\nB\nC\n" 859 "STARTED 0 1000\n" 860 "FT 0 1 2 3\n" 861 "STARTED 1 1001\n" 862 "FT 1 4 5 6 \n" 863 "STARTED 2 1002\n" 864 "FT 2 6 1 3\n" 865 "", 866 true)); 867 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 0U); 868 TRACED_EQ(M.Files, {"A", "B", "C"}); 869 TRACED_EQ(NewFiles, {}); 870 TRACED_EQ(NewFeatures, {}); 871 872 // Can pass initial features and coverage. 873 Features = {1, 2, 3}; 874 Cov = {}; 875 EXPECT_TRUE(M.Parse("2\n0\nA\nB\n" 876 "STARTED 0 1000\n" 877 "FT 0 1 2 3\n" 878 "STARTED 1 1001\n" 879 "FT 1 4 5 6\n" 880 "", 881 true)); 882 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U); 883 TRACED_EQ(M.Files, {"A", "B"}); 884 TRACED_EQ(NewFiles, {"B"}); 885 TRACED_EQ(NewFeatures, {4, 5, 6}); 886 Features.clear(); 887 Cov.clear(); 888 889 // Parse smaller files first 890 EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n" 891 "STARTED 0 2000\n" 892 "FT 0 1 2 3\n" 893 "STARTED 1 1001\n" 894 "FT 1 4 5 6 \n" 895 "STARTED 2 1002\n" 896 "FT 2 6 1 3 \n" 897 "", 898 true)); 899 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 6U); 900 TRACED_EQ(M.Files, {"B", "C", "A"}); 901 TRACED_EQ(NewFiles, {"B", "C", "A"}); 902 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6}); 903 904 EXPECT_TRUE(M.Parse("4\n0\nA\nB\nC\nD\n" 905 "STARTED 0 2000\n" 906 "FT 0 1 2 3\n" 907 "STARTED 1 1101\n" 908 "FT 1 4 5 6 \n" 909 "STARTED 2 1102\n" 910 "FT 2 6 1 3 100 \n" 911 "STARTED 3 1000\n" 912 "FT 3 1 \n" 913 "", 914 true)); 915 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 7U); 916 TRACED_EQ(M.Files, {"A", "B", "C", "D"}); 917 TRACED_EQ(NewFiles, {"D", "B", "C", "A"}); 918 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6, 100}); 919 920 // For same sized file, parse more features first 921 EXPECT_TRUE(M.Parse("4\n1\nA\nB\nC\nD\n" 922 "STARTED 0 2000\n" 923 "FT 0 4 5 6 7 8\n" 924 "STARTED 1 1100\n" 925 "FT 1 1 2 3 \n" 926 "STARTED 2 1100\n" 927 "FT 2 2 3 \n" 928 "STARTED 3 1000\n" 929 "FT 3 1 \n" 930 "", 931 true)); 932 EXPECT_EQ(M.Merge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 3U); 933 TRACED_EQ(M.Files, {"A", "B", "C", "D"}); 934 TRACED_EQ(NewFiles, {"D", "B"}); 935 TRACED_EQ(NewFeatures, {1, 2, 3}); 936 } 937 938 TEST(Merger, SetCoverMerge) { 939 Merger M; 940 std::set<uint32_t> Features, NewFeatures; 941 std::set<uint32_t> Cov, NewCov; 942 std::vector<std::string> NewFiles; 943 944 // Adds new files and features 945 EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n" 946 "STARTED 0 1000\n" 947 "FT 0 1 2 3\n" 948 "STARTED 1 1001\n" 949 "FT 1 4 5 6 \n" 950 "STARTED 2 1002\n" 951 "FT 2 6 1 3\n" 952 "", 953 true)); 954 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 955 6U); 956 TRACED_EQ(M.Files, {"A", "B", "C"}); 957 TRACED_EQ(NewFiles, {"A", "B"}); 958 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6}); 959 960 // Doesn't return features or files in the initial corpus. 961 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n" 962 "STARTED 0 1000\n" 963 "FT 0 1 2 3\n" 964 "STARTED 1 1001\n" 965 "FT 1 4 5 6 \n" 966 "STARTED 2 1002\n" 967 "FT 2 6 1 3\n" 968 "", 969 true)); 970 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 971 3U); 972 TRACED_EQ(M.Files, {"A", "B", "C"}); 973 TRACED_EQ(NewFiles, {"B"}); 974 TRACED_EQ(NewFeatures, {4, 5, 6}); 975 976 // No new features, so no new files 977 EXPECT_TRUE(M.Parse("3\n2\nA\nB\nC\n" 978 "STARTED 0 1000\n" 979 "FT 0 1 2 3\n" 980 "STARTED 1 1001\n" 981 "FT 1 4 5 6 \n" 982 "STARTED 2 1002\n" 983 "FT 2 6 1 3\n" 984 "", 985 true)); 986 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 987 0U); 988 TRACED_EQ(M.Files, {"A", "B", "C"}); 989 TRACED_EQ(NewFiles, {}); 990 TRACED_EQ(NewFeatures, {}); 991 992 // Can pass initial features and coverage. 993 Features = {1, 2, 3}; 994 Cov = {}; 995 EXPECT_TRUE(M.Parse("2\n0\nA\nB\n" 996 "STARTED 0 1000\n" 997 "FT 0 1 2 3\n" 998 "STARTED 1 1001\n" 999 "FT 1 4 5 6\n" 1000 "", 1001 true)); 1002 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 1003 3U); 1004 TRACED_EQ(M.Files, {"A", "B"}); 1005 TRACED_EQ(NewFiles, {"B"}); 1006 TRACED_EQ(NewFeatures, {4, 5, 6}); 1007 Features.clear(); 1008 Cov.clear(); 1009 1010 // Prefer files with a lot of features first (C has 4 features) 1011 // Then prefer B over A due to the smaller size. After choosing C and B, 1012 // A and D have no new features to contribute. 1013 EXPECT_TRUE(M.Parse("4\n0\nA\nB\nC\nD\n" 1014 "STARTED 0 2000\n" 1015 "FT 0 3 5 6\n" 1016 "STARTED 1 1000\n" 1017 "FT 1 4 5 6 \n" 1018 "STARTED 2 1000\n" 1019 "FT 2 1 2 3 4 \n" 1020 "STARTED 3 500\n" 1021 "FT 3 1 \n" 1022 "", 1023 true)); 1024 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 1025 6U); 1026 TRACED_EQ(M.Files, {"A", "B", "C", "D"}); 1027 TRACED_EQ(NewFiles, {"C", "B"}); 1028 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5, 6}); 1029 1030 // Only 1 file covers all features. 1031 EXPECT_TRUE(M.Parse("4\n1\nA\nB\nC\nD\n" 1032 "STARTED 0 2000\n" 1033 "FT 0 4 5 6 7 8\n" 1034 "STARTED 1 1100\n" 1035 "FT 1 1 2 3 \n" 1036 "STARTED 2 1100\n" 1037 "FT 2 2 3 \n" 1038 "STARTED 3 1000\n" 1039 "FT 3 1 \n" 1040 "", 1041 true)); 1042 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 1043 3U); 1044 TRACED_EQ(M.Files, {"A", "B", "C", "D"}); 1045 TRACED_EQ(NewFiles, {"B"}); 1046 TRACED_EQ(NewFeatures, {1, 2, 3}); 1047 1048 // A Feature has a value greater than (1 << 21) and hence 1049 // there are collisions in the underlying `covered features` 1050 // bitvector. 1051 EXPECT_TRUE(M.Parse("3\n0\nA\nB\nC\n" 1052 "STARTED 0 2000\n" 1053 "FT 0 1 2 3\n" 1054 "STARTED 1 1000\n" 1055 "FT 1 3 4 5 \n" 1056 "STARTED 2 1000\n" 1057 "FT 2 3 2097153 \n" // Last feature is (2^21 + 1). 1058 "", 1059 true)); 1060 EXPECT_EQ(M.SetCoverMerge(Features, &NewFeatures, Cov, &NewCov, &NewFiles), 1061 5U); 1062 TRACED_EQ(M.Files, {"A", "B", "C"}); 1063 // File 'C' is not added because it's last feature is considered 1064 // covered due to collision with feature 1. 1065 TRACED_EQ(NewFiles, {"B", "A"}); 1066 TRACED_EQ(NewFeatures, {1, 2, 3, 4, 5}); 1067 } 1068 1069 #undef TRACED_EQ 1070 1071 TEST(DFT, BlockCoverage) { 1072 BlockCoverage Cov; 1073 // Assuming C0 has 5 instrumented blocks, 1074 // C1: 7 blocks, C2: 4, C3: 9, C4 never covered, C5: 15, 1075 1076 // Add C0 1077 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 1078 EXPECT_EQ(Cov.GetCounter(0, 0), 1U); 1079 EXPECT_EQ(Cov.GetCounter(0, 1), 0U); // not seen this BB yet. 1080 EXPECT_EQ(Cov.GetCounter(0, 5), 0U); // BB ID out of bounds. 1081 EXPECT_EQ(Cov.GetCounter(1, 0), 0U); // not seen this function yet. 1082 1083 EXPECT_EQ(Cov.GetNumberOfBlocks(0), 5U); 1084 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 1U); 1085 EXPECT_EQ(Cov.GetNumberOfBlocks(1), 0U); 1086 1087 // Various errors. 1088 EXPECT_FALSE(Cov.AppendCoverage("C0\n")); // No total number. 1089 EXPECT_FALSE(Cov.AppendCoverage("C0 7\n")); // No total number. 1090 EXPECT_FALSE(Cov.AppendCoverage("CZ\n")); // Wrong function number. 1091 EXPECT_FALSE(Cov.AppendCoverage("C1 7 7")); // BB ID is too big. 1092 EXPECT_FALSE(Cov.AppendCoverage("C1 100 7")); // BB ID is too big. 1093 1094 // Add C0 more times. 1095 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 1096 EXPECT_EQ(Cov.GetCounter(0, 0), 2U); 1097 EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 5\n")); 1098 EXPECT_EQ(Cov.GetCounter(0, 0), 3U); 1099 EXPECT_EQ(Cov.GetCounter(0, 1), 1U); 1100 EXPECT_EQ(Cov.GetCounter(0, 2), 1U); 1101 EXPECT_EQ(Cov.GetCounter(0, 3), 0U); 1102 EXPECT_EQ(Cov.GetCounter(0, 4), 0U); 1103 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 3U); 1104 EXPECT_TRUE(Cov.AppendCoverage("C0 1 3 4 5\n")); 1105 EXPECT_EQ(Cov.GetCounter(0, 0), 4U); 1106 EXPECT_EQ(Cov.GetCounter(0, 1), 2U); 1107 EXPECT_EQ(Cov.GetCounter(0, 2), 1U); 1108 EXPECT_EQ(Cov.GetCounter(0, 3), 1U); 1109 EXPECT_EQ(Cov.GetCounter(0, 4), 1U); 1110 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 5U); 1111 1112 EXPECT_TRUE(Cov.AppendCoverage("C1 7\nC2 4\nC3 9\nC5 15\nC0 5\n")); 1113 EXPECT_EQ(Cov.GetCounter(0, 0), 5U); 1114 EXPECT_EQ(Cov.GetCounter(1, 0), 1U); 1115 EXPECT_EQ(Cov.GetCounter(2, 0), 1U); 1116 EXPECT_EQ(Cov.GetCounter(3, 0), 1U); 1117 EXPECT_EQ(Cov.GetCounter(4, 0), 0U); 1118 EXPECT_EQ(Cov.GetCounter(5, 0), 1U); 1119 1120 EXPECT_TRUE(Cov.AppendCoverage("C3 4 5 9\nC5 11 12 15")); 1121 EXPECT_EQ(Cov.GetCounter(0, 0), 5U); 1122 EXPECT_EQ(Cov.GetCounter(1, 0), 1U); 1123 EXPECT_EQ(Cov.GetCounter(2, 0), 1U); 1124 EXPECT_EQ(Cov.GetCounter(3, 0), 2U); 1125 EXPECT_EQ(Cov.GetCounter(3, 4), 1U); 1126 EXPECT_EQ(Cov.GetCounter(3, 5), 1U); 1127 EXPECT_EQ(Cov.GetCounter(3, 6), 0U); 1128 EXPECT_EQ(Cov.GetCounter(4, 0), 0U); 1129 EXPECT_EQ(Cov.GetCounter(5, 0), 2U); 1130 EXPECT_EQ(Cov.GetCounter(5, 10), 0U); 1131 EXPECT_EQ(Cov.GetCounter(5, 11), 1U); 1132 EXPECT_EQ(Cov.GetCounter(5, 12), 1U); 1133 } 1134 1135 TEST(DFT, FunctionWeights) { 1136 BlockCoverage Cov; 1137 // unused function gets zero weight. 1138 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 1139 auto Weights = Cov.FunctionWeights(2); 1140 EXPECT_GT(Weights[0], 0.); 1141 EXPECT_EQ(Weights[1], 0.); 1142 1143 // Less frequently used function gets less weight. 1144 Cov.clear(); 1145 EXPECT_TRUE(Cov.AppendCoverage("C0 5\nC1 5\nC1 5\n")); 1146 Weights = Cov.FunctionWeights(2); 1147 EXPECT_GT(Weights[0], Weights[1]); 1148 1149 // A function with more uncovered blocks gets more weight. 1150 Cov.clear(); 1151 EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n")); 1152 Weights = Cov.FunctionWeights(2); 1153 EXPECT_GT(Weights[1], Weights[0]); 1154 1155 // A function with DFT gets more weight than the function w/o DFT. 1156 Cov.clear(); 1157 EXPECT_TRUE(Cov.AppendCoverage("F1 111\nC0 3\nC1 1 2 3\n")); 1158 Weights = Cov.FunctionWeights(2); 1159 EXPECT_GT(Weights[1], Weights[0]); 1160 } 1161 1162 1163 TEST(Fuzzer, ForEachNonZeroByte) { 1164 const size_t N = 64; 1165 alignas(64) uint8_t Ar[N + 8] = { 1166 0, 0, 0, 0, 0, 0, 0, 0, 1167 1, 2, 0, 0, 0, 0, 0, 0, 1168 0, 0, 3, 0, 4, 0, 0, 0, 1169 0, 0, 0, 0, 0, 0, 0, 0, 1170 0, 0, 0, 5, 0, 6, 0, 0, 1171 0, 0, 0, 0, 0, 0, 7, 0, 1172 0, 0, 0, 0, 0, 0, 0, 0, 1173 0, 0, 0, 0, 0, 0, 0, 8, 1174 9, 9, 9, 9, 9, 9, 9, 9, 1175 }; 1176 typedef std::vector<std::pair<size_t, uint8_t>> Vec; 1177 Vec Res, Expected; 1178 auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) { 1179 Res.push_back({FirstFeature + Idx, V}); 1180 }; 1181 ForEachNonZeroByte(Ar, Ar + N, 100, CB); 1182 Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4}, 1183 {135, 5}, {137, 6}, {146, 7}, {163, 8}}; 1184 EXPECT_EQ(Res, Expected); 1185 1186 Res.clear(); 1187 ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB); 1188 Expected = { {109, 2}, {118, 3}, {120, 4}, 1189 {135, 5}, {137, 6}, {146, 7}, {163, 8}}; 1190 EXPECT_EQ(Res, Expected); 1191 1192 Res.clear(); 1193 ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB); 1194 Expected = { {109, 2}, {118, 3}, {120, 4}, 1195 {135, 5}, {137, 6}, {146, 7}}; 1196 EXPECT_EQ(Res, Expected); 1197 } 1198 1199 // FuzzerCommand unit tests. The arguments in the two helper methods below must 1200 // match. 1201 static void makeCommandArgs(std::vector<std::string> *ArgsToAdd) { 1202 assert(ArgsToAdd); 1203 ArgsToAdd->clear(); 1204 ArgsToAdd->push_back("foo"); 1205 ArgsToAdd->push_back("-bar=baz"); 1206 ArgsToAdd->push_back("qux"); 1207 ArgsToAdd->push_back(Command::ignoreRemainingArgs()); 1208 ArgsToAdd->push_back("quux"); 1209 ArgsToAdd->push_back("-grault=garply"); 1210 } 1211 1212 static std::string makeCmdLine(const char *separator, const char *suffix) { 1213 std::string CmdLine("foo -bar=baz qux "); 1214 if (strlen(separator) != 0) { 1215 CmdLine += separator; 1216 CmdLine += " "; 1217 } 1218 CmdLine += Command::ignoreRemainingArgs(); 1219 CmdLine += " quux -grault=garply"; 1220 if (strlen(suffix) != 0) { 1221 CmdLine += " "; 1222 CmdLine += suffix; 1223 } 1224 return CmdLine; 1225 } 1226 1227 TEST(FuzzerCommand, Create) { 1228 std::string CmdLine; 1229 1230 // Default constructor 1231 Command DefaultCmd; 1232 1233 CmdLine = DefaultCmd.toString(); 1234 EXPECT_EQ(CmdLine, ""); 1235 1236 // Explicit constructor 1237 std::vector<std::string> ArgsToAdd; 1238 makeCommandArgs(&ArgsToAdd); 1239 Command InitializedCmd(ArgsToAdd); 1240 1241 CmdLine = InitializedCmd.toString(); 1242 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1243 1244 // Compare each argument 1245 auto InitializedArgs = InitializedCmd.getArguments(); 1246 auto i = ArgsToAdd.begin(); 1247 auto j = InitializedArgs.begin(); 1248 while (i != ArgsToAdd.end() && j != InitializedArgs.end()) { 1249 EXPECT_EQ(*i++, *j++); 1250 } 1251 EXPECT_EQ(i, ArgsToAdd.end()); 1252 EXPECT_EQ(j, InitializedArgs.end()); 1253 1254 // Copy constructor 1255 Command CopiedCmd(InitializedCmd); 1256 1257 CmdLine = CopiedCmd.toString(); 1258 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1259 1260 // Assignment operator 1261 Command AssignedCmd; 1262 AssignedCmd = CopiedCmd; 1263 1264 CmdLine = AssignedCmd.toString(); 1265 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1266 } 1267 1268 TEST(FuzzerCommand, ModifyArguments) { 1269 std::vector<std::string> ArgsToAdd; 1270 makeCommandArgs(&ArgsToAdd); 1271 Command Cmd; 1272 std::string CmdLine; 1273 1274 Cmd.addArguments(ArgsToAdd); 1275 CmdLine = Cmd.toString(); 1276 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1277 1278 Cmd.addArgument("waldo"); 1279 EXPECT_TRUE(Cmd.hasArgument("waldo")); 1280 1281 CmdLine = Cmd.toString(); 1282 EXPECT_EQ(CmdLine, makeCmdLine("waldo", "")); 1283 1284 Cmd.removeArgument("waldo"); 1285 EXPECT_FALSE(Cmd.hasArgument("waldo")); 1286 1287 CmdLine = Cmd.toString(); 1288 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1289 } 1290 1291 TEST(FuzzerCommand, ModifyFlags) { 1292 std::vector<std::string> ArgsToAdd; 1293 makeCommandArgs(&ArgsToAdd); 1294 Command Cmd(ArgsToAdd); 1295 std::string Value, CmdLine; 1296 ASSERT_FALSE(Cmd.hasFlag("fred")); 1297 1298 Value = Cmd.getFlagValue("fred"); 1299 EXPECT_EQ(Value, ""); 1300 1301 CmdLine = Cmd.toString(); 1302 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1303 1304 Cmd.addFlag("fred", "plugh"); 1305 EXPECT_TRUE(Cmd.hasFlag("fred")); 1306 1307 Value = Cmd.getFlagValue("fred"); 1308 EXPECT_EQ(Value, "plugh"); 1309 1310 CmdLine = Cmd.toString(); 1311 EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", "")); 1312 1313 Cmd.removeFlag("fred"); 1314 EXPECT_FALSE(Cmd.hasFlag("fred")); 1315 1316 Value = Cmd.getFlagValue("fred"); 1317 EXPECT_EQ(Value, ""); 1318 1319 CmdLine = Cmd.toString(); 1320 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1321 } 1322 1323 TEST(FuzzerCommand, SetOutput) { 1324 std::vector<std::string> ArgsToAdd; 1325 makeCommandArgs(&ArgsToAdd); 1326 Command Cmd(ArgsToAdd); 1327 std::string CmdLine; 1328 ASSERT_FALSE(Cmd.hasOutputFile()); 1329 ASSERT_FALSE(Cmd.isOutAndErrCombined()); 1330 1331 Cmd.combineOutAndErr(true); 1332 EXPECT_TRUE(Cmd.isOutAndErrCombined()); 1333 1334 CmdLine = Cmd.toString(); 1335 EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1")); 1336 1337 Cmd.combineOutAndErr(false); 1338 EXPECT_FALSE(Cmd.isOutAndErrCombined()); 1339 1340 Cmd.setOutputFile("xyzzy"); 1341 EXPECT_TRUE(Cmd.hasOutputFile()); 1342 1343 CmdLine = Cmd.toString(); 1344 EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy")); 1345 1346 Cmd.setOutputFile("thud"); 1347 EXPECT_TRUE(Cmd.hasOutputFile()); 1348 1349 CmdLine = Cmd.toString(); 1350 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud")); 1351 1352 Cmd.combineOutAndErr(); 1353 EXPECT_TRUE(Cmd.isOutAndErrCombined()); 1354 1355 CmdLine = Cmd.toString(); 1356 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1")); 1357 } 1358 1359 TEST(Entropic, UpdateFrequency) { 1360 const size_t One = 1, Two = 2; 1361 const size_t FeatIdx1 = 0, FeatIdx2 = 42, FeatIdx3 = 12, FeatIdx4 = 26; 1362 size_t Index; 1363 // Create input corpus with default entropic configuration 1364 struct EntropicOptions Entropic = {true, 0xFF, 100, false}; 1365 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 1366 std::unique_ptr<InputInfo> II(new InputInfo()); 1367 1368 C->AddRareFeature(FeatIdx1); 1369 C->UpdateFeatureFrequency(II.get(), FeatIdx1); 1370 EXPECT_EQ(II->FeatureFreqs.size(), One); 1371 C->AddRareFeature(FeatIdx2); 1372 C->UpdateFeatureFrequency(II.get(), FeatIdx1); 1373 C->UpdateFeatureFrequency(II.get(), FeatIdx2); 1374 EXPECT_EQ(II->FeatureFreqs.size(), Two); 1375 EXPECT_EQ(II->FeatureFreqs[0].second, 2); 1376 EXPECT_EQ(II->FeatureFreqs[1].second, 1); 1377 1378 C->AddRareFeature(FeatIdx3); 1379 C->AddRareFeature(FeatIdx4); 1380 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1381 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1382 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1383 C->UpdateFeatureFrequency(II.get(), FeatIdx4); 1384 1385 for (Index = 1; Index < II->FeatureFreqs.size(); Index++) 1386 EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first); 1387 1388 II->DeleteFeatureFreq(FeatIdx3); 1389 for (Index = 1; Index < II->FeatureFreqs.size(); Index++) 1390 EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first); 1391 } 1392 1393 double SubAndSquare(double X, double Y) { 1394 double R = X - Y; 1395 R = R * R; 1396 return R; 1397 } 1398 1399 TEST(Entropic, ComputeEnergy) { 1400 const double Precision = 0.01; 1401 struct EntropicOptions Entropic = {true, 0xFF, 100, false}; 1402 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 1403 std::unique_ptr<InputInfo> II(new InputInfo()); 1404 std::vector<std::pair<uint32_t, uint16_t>> FeatureFreqs = { 1405 {1, 3}, {2, 3}, {3, 3}}; 1406 II->FeatureFreqs = FeatureFreqs; 1407 II->NumExecutedMutations = 0; 1408 II->UpdateEnergy(4, false, std::chrono::microseconds(0)); 1409 EXPECT_LT(SubAndSquare(II->Energy, 1.450805), Precision); 1410 1411 II->NumExecutedMutations = 9; 1412 II->UpdateEnergy(5, false, std::chrono::microseconds(0)); 1413 EXPECT_LT(SubAndSquare(II->Energy, 1.525496), Precision); 1414 1415 II->FeatureFreqs[0].second++; 1416 II->FeatureFreqs.push_back(std::pair<uint32_t, uint16_t>(42, 6)); 1417 II->NumExecutedMutations = 20; 1418 II->UpdateEnergy(10, false, std::chrono::microseconds(0)); 1419 EXPECT_LT(SubAndSquare(II->Energy, 1.792831), Precision); 1420 } 1421 1422 int main(int argc, char **argv) { 1423 testing::InitGoogleTest(&argc, argv); 1424 return RUN_ALL_TESTS(); 1425 } 1426