Fix the conditions of copying/inserting dictionary entries. Previously they would reject feasible mutations in edge cases. PiperOrigin-RevId: 551018646
diff --git a/e2e_tests/functional_test.cc b/e2e_tests/functional_test.cc index 0e78f2f..d7c5b6a 100644 --- a/e2e_tests/functional_test.cc +++ b/e2e_tests/functional_test.cc
@@ -744,6 +744,13 @@ EXPECT_THAT(status, Eq(Signal(SIGABRT))); } +TEST_F(FuzzingModeTest, FixedSizeVectorValueTestFindsAbortInFuzzingMode) { + auto [status, std_out, std_err] = + RunWith("--fuzz=MySuite.FixedSizeVectorValue"); + EXPECT_THAT(std_err, HasSubstr("argument 0: {'F'")); + EXPECT_THAT(status, Eq(Signal(SIGABRT))); +} + TEST_F(FuzzingModeTest, GoogleTestExpectationsStopTheFuzzer) { auto [status, std_out, std_err] = RunWith("--fuzz=MySuite.GoogleTestExpect");
diff --git a/e2e_tests/testdata/fuzz_tests_for_microbenchmarking.cc b/e2e_tests/testdata/fuzz_tests_for_microbenchmarking.cc index 825e05f..399903e 100644 --- a/e2e_tests/testdata/fuzz_tests_for_microbenchmarking.cc +++ b/e2e_tests/testdata/fuzz_tests_for_microbenchmarking.cc
@@ -213,6 +213,10 @@ } FUZZ_TEST(MySuite, VectorValue); +constexpr auto& FixedSizeVectorValue = VectorValue; +FUZZ_TEST(MySuite, FixedSizeVectorValue) + .WithDomains(fuzztest::VectorOf(fuzztest::Arbitrary<char>()).WithSize(4)); + __attribute__((optnone)) void WithDomainClass(uint8_t a, double d) { // This will only crash with a=10, to make it easier to check the results. // d can have any value.
diff --git a/fuzztest/internal/domains/container_mutation_helpers.h b/fuzztest/internal/domains/container_mutation_helpers.h index 6de1ce5..c6c17de 100644 --- a/fuzztest/internal/domains/container_mutation_helpers.h +++ b/fuzztest/internal/domains/container_mutation_helpers.h
@@ -117,7 +117,7 @@ bool CopyFromDictionaryEntry(const DictionaryEntry<ContainerT>& dict_entry, absl::BitGenRef prng, ContainerT& val, size_t max_size) { - if (dict_entry.value.size() >= max_size) return false; + if (dict_entry.value.size() > max_size) return false; size_t position_hint = GetOrGuessPositionHint( dict_entry.position_hint, std::min(val.size(), max_size - dict_entry.value.size()), prng); @@ -132,7 +132,7 @@ const DictionaryEntry<ContainerT>& dict_entry, absl::BitGenRef prng, ContainerT& val, size_t max_size, std::optional<DictionaryEntry<ContainerT>>& permanent_dict_candidate) { - if (dict_entry.value.size() >= max_size) return false; + if (dict_entry.value.size() > max_size) return false; size_t position_hint = GetOrGuessPositionHint( dict_entry.position_hint, std::min(val.size(), max_size - dict_entry.value.size()), prng); @@ -153,7 +153,7 @@ bool InsertFromDictionaryEntry(const DictionaryEntry<ContainerT>& dict_entry, absl::BitGenRef prng, ContainerT& val, size_t max_size) { - if (dict_entry.value.size() >= max_size) return false; + if (val.size() + dict_entry.value.size() > max_size) return false; size_t position_hint = GetOrGuessPositionHint(dict_entry.position_hint, val.size(), prng); return InsertPart<is_self>(dict_entry.value, val, 0, dict_entry.value.size(), @@ -167,7 +167,7 @@ const DictionaryEntry<ContainerT>& dict_entry, absl::BitGenRef prng, ContainerT& val, size_t max_size, std::optional<DictionaryEntry<ContainerT>>& permanent_dict_candidate) { - if (dict_entry.value.size() >= max_size) return false; + if (val.size() + dict_entry.value.size() > max_size) return false; size_t position_hint = GetOrGuessPositionHint(dict_entry.position_hint, val.size(), prng); bool mutated =