| 503 | } |
| 504 | |
| 505 | bool Shrink(const spv_target_env& target_env, |
| 506 | spv_const_fuzzer_options fuzzer_options, |
| 507 | spv_validator_options validator_options, |
| 508 | const std::vector<uint32_t>& binary_in, |
| 509 | const spvtools::fuzz::protobufs::FactSequence& initial_facts, |
| 510 | const std::string& shrink_transformations_file, |
| 511 | const std::string& shrink_temp_file_prefix, |
| 512 | const std::vector<std::string>& interestingness_command, |
| 513 | std::vector<uint32_t>* binary_out, |
| 514 | spvtools::fuzz::protobufs::TransformationSequence* |
| 515 | transformations_applied) { |
| 516 | spvtools::fuzz::protobufs::TransformationSequence transformation_sequence; |
| 517 | if (!ParseTransformations(shrink_transformations_file, |
| 518 | &transformation_sequence)) { |
| 519 | return false; |
| 520 | } |
| 521 | assert(!interestingness_command.empty() && |
| 522 | "An error should have been raised because the interestingness_command " |
| 523 | "is empty."); |
| 524 | std::stringstream joined; |
| 525 | joined << interestingness_command[0]; |
| 526 | for (size_t i = 1, size = interestingness_command.size(); i < size; ++i) { |
| 527 | joined << " " << interestingness_command[i]; |
| 528 | } |
| 529 | std::string interestingness_command_joined = joined.str(); |
| 530 | |
| 531 | spvtools::fuzz::Shrinker::InterestingnessFunction interestingness_function = |
| 532 | [interestingness_command_joined, shrink_temp_file_prefix]( |
| 533 | std::vector<uint32_t> binary, uint32_t reductions_applied) -> bool { |
| 534 | std::stringstream ss; |
| 535 | ss << shrink_temp_file_prefix << std::setw(4) << std::setfill('0') |
| 536 | << reductions_applied << ".spv"; |
| 537 | const auto spv_file = ss.str(); |
| 538 | const std::string command = interestingness_command_joined + " " + spv_file; |
| 539 | auto write_file_succeeded = |
| 540 | WriteFile(spv_file.c_str(), "wb", &binary[0], binary.size()); |
| 541 | (void)(write_file_succeeded); |
| 542 | assert(write_file_succeeded); |
| 543 | return ExecuteCommand(command); |
| 544 | }; |
| 545 | |
| 546 | auto shrink_result = |
| 547 | spvtools::fuzz::Shrinker( |
| 548 | target_env, spvtools::utils::CLIMessageConsumer, binary_in, |
| 549 | initial_facts, transformation_sequence, interestingness_function, |
| 550 | fuzzer_options->shrinker_step_limit, |
| 551 | fuzzer_options->replay_validation_enabled, validator_options) |
| 552 | .Run(); |
| 553 | |
| 554 | *binary_out = std::move(shrink_result.transformed_binary); |
| 555 | *transformations_applied = std::move(shrink_result.applied_transformations); |
| 556 | return spvtools::fuzz::Shrinker::ShrinkerResultStatus::kComplete == |
| 557 | shrink_result.status || |
| 558 | spvtools::fuzz::Shrinker::ShrinkerResultStatus::kStepLimitReached == |
| 559 | shrink_result.status; |
| 560 | } |
| 561 | |
| 562 | bool Fuzz(const spv_target_env& target_env, |
no test coverage detected