| 361 | } |
| 362 | |
| 363 | int CleanseCrashInput(const std::vector<std::string> &Args, |
| 364 | const FuzzingOptions &Options) { |
| 365 | if (Inputs->size() != 1 || !Flags.exact_artifact_path) { |
| 366 | Printf("ERROR: -cleanse_crash should be given one input file and" |
| 367 | " -exact_artifact_path\n"); |
| 368 | exit(1); |
| 369 | } |
| 370 | std::string InputFilePath = Inputs->at(0); |
| 371 | std::string OutputFilePath = Flags.exact_artifact_path; |
| 372 | Command Cmd(Args); |
| 373 | Cmd.removeFlag("cleanse_crash"); |
| 374 | |
| 375 | assert(Cmd.hasArgument(InputFilePath)); |
| 376 | Cmd.removeArgument(InputFilePath); |
| 377 | |
| 378 | auto TmpFilePath = TempPath("CleanseCrashInput", ".repro"); |
| 379 | Cmd.addArgument(TmpFilePath); |
| 380 | Cmd.setOutputFile(getDevNull()); |
| 381 | Cmd.combineOutAndErr(); |
| 382 | |
| 383 | std::string CurrentFilePath = InputFilePath; |
| 384 | auto U = FileToVector(CurrentFilePath); |
| 385 | size_t Size = U.size(); |
| 386 | |
| 387 | const std::vector<uint8_t> ReplacementBytes = {' ', 0xff}; |
| 388 | for (int NumAttempts = 0; NumAttempts < 5; NumAttempts++) { |
| 389 | bool Changed = false; |
| 390 | for (size_t Idx = 0; Idx < Size; Idx++) { |
| 391 | Printf("CLEANSE[%d]: Trying to replace byte %zd of %zd\n", NumAttempts, |
| 392 | Idx, Size); |
| 393 | uint8_t OriginalByte = U[Idx]; |
| 394 | if (ReplacementBytes.end() != std::find(ReplacementBytes.begin(), |
| 395 | ReplacementBytes.end(), |
| 396 | OriginalByte)) |
| 397 | continue; |
| 398 | for (auto NewByte : ReplacementBytes) { |
| 399 | U[Idx] = NewByte; |
| 400 | WriteToFile(U, TmpFilePath); |
| 401 | auto ExitCode = ExecuteCommand(Cmd); |
| 402 | RemoveFile(TmpFilePath); |
| 403 | if (!ExitCode) { |
| 404 | U[Idx] = OriginalByte; |
| 405 | } else { |
| 406 | Changed = true; |
| 407 | Printf("CLEANSE: Replaced byte %zd with 0x%x\n", Idx, NewByte); |
| 408 | WriteToFile(U, OutputFilePath); |
| 409 | break; |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | if (!Changed) break; |
| 414 | } |
| 415 | return 0; |
| 416 | } |
| 417 | |
| 418 | int MinimizeCrashInput(const std::vector<std::string> &Args, |
| 419 | const FuzzingOptions &Options) { |
no test coverage detected