spirv-fuzz: Set message consumer in replayer when shrinking (#3591)

Fixes an issue with the shrinker, where the message consumer set for
the shrinker was not being passed on to the replay object that the
shrinker creates.  This meant that messages generated during replay
would cause an exception to be thrown.
This commit is contained in:
Alastair Donaldson 2020-07-27 08:11:12 +01:00 committed by GitHub
parent d6306537dc
commit 059ab0819e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 11 deletions

View File

@ -121,11 +121,13 @@ Shrinker::ShrinkerResultStatus Shrinker::Run(
// succeeds, (b) get the binary that results from running these // succeeds, (b) get the binary that results from running these
// transformations, and (c) get the subsequence of the initial transformations // transformations, and (c) get the subsequence of the initial transformations
// that actually apply (in principle this could be a strict subsequence). // that actually apply (in principle this could be a strict subsequence).
if (Replayer(impl_->target_env, impl_->validate_during_replay, Replayer replayer(impl_->target_env, impl_->validate_during_replay,
impl_->validator_options) impl_->validator_options);
.Run(binary_in, initial_facts, transformation_sequence_in, replayer.SetMessageConsumer(impl_->consumer);
transformation_sequence_in.transformation_size(), if (replayer.Run(binary_in, initial_facts, transformation_sequence_in,
&current_best_binary, &current_best_transformations) != static_cast<uint32_t>(
transformation_sequence_in.transformation_size()),
&current_best_binary, &current_best_transformations) !=
Replayer::ReplayerResultStatus::kComplete) { Replayer::ReplayerResultStatus::kComplete) {
return ShrinkerResultStatus::kReplayFailed; return ShrinkerResultStatus::kReplayFailed;
} }
@ -185,7 +187,8 @@ Shrinker::ShrinkerResultStatus Shrinker::Run(
// Remove a chunk of transformations according to the current index and // Remove a chunk of transformations according to the current index and
// chunk size. // chunk size.
auto transformations_with_chunk_removed = auto transformations_with_chunk_removed =
RemoveChunk(current_best_transformations, chunk_index, chunk_size); RemoveChunk(current_best_transformations,
static_cast<uint32_t>(chunk_index), chunk_size);
// Replay the smaller sequence of transformations to get a next binary and // Replay the smaller sequence of transformations to get a next binary and
// transformation sequence. Note that the transformations arising from // transformation sequence. Note that the transformations arising from
@ -194,11 +197,11 @@ Shrinker::ShrinkerResultStatus Shrinker::Run(
// transformations inapplicable. // transformations inapplicable.
std::vector<uint32_t> next_binary; std::vector<uint32_t> next_binary;
protobufs::TransformationSequence next_transformation_sequence; protobufs::TransformationSequence next_transformation_sequence;
if (Replayer(impl_->target_env, impl_->validate_during_replay, if (replayer.Run(
impl_->validator_options) binary_in, initial_facts, transformations_with_chunk_removed,
.Run(binary_in, initial_facts, transformations_with_chunk_removed, static_cast<uint32_t>(
transformations_with_chunk_removed.transformation_size(), transformations_with_chunk_removed.transformation_size()),
&next_binary, &next_transformation_sequence) != &next_binary, &next_transformation_sequence) !=
Replayer::ReplayerResultStatus::kComplete) { Replayer::ReplayerResultStatus::kComplete) {
// Replay should not fail; if it does, we need to abort shrinking. // Replay should not fail; if it does, we need to abort shrinking.
return ShrinkerResultStatus::kReplayFailed; return ShrinkerResultStatus::kReplayFailed;

View File

@ -1111,6 +1111,18 @@ TEST(FuzzerShrinkerTest, Miscellaneous3) {
*temp.mutable_constant_uniform_fact() = resolution_y_eq_100; *temp.mutable_constant_uniform_fact() = resolution_y_eq_100;
*facts.mutable_fact()->Add() = temp; *facts.mutable_fact()->Add() = temp;
} }
// Also add an invalid fact, which should be ignored.
{
protobufs::FactConstantUniform bad_fact;
// The descriptor set, binding and indices used here deliberately make no
// sense.
*bad_fact.mutable_uniform_buffer_element_descriptor() =
MakeUniformBufferElementDescriptor(22, 33, {44, 55});
*bad_fact.mutable_constant_word()->Add() = 100;
protobufs::Fact temp;
*temp.mutable_constant_uniform_fact() = bad_fact;
*facts.mutable_fact()->Add() = temp;
}
// Do 2 fuzzer runs, starting from an initial seed of 194 (seed value chosen // Do 2 fuzzer runs, starting from an initial seed of 194 (seed value chosen
// arbitrarily). // arbitrarily).