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