diff --git a/domain_tests/container_test.cc b/domain_tests/container_test.cc index c599fa48..d665ed70 100644 --- a/domain_tests/container_test.cc +++ b/domain_tests/container_test.cc @@ -247,15 +247,29 @@ TEST(Container, MaxSizeAndSoftMaxSizeOverwriteEachOther) { EXPECT_TRUE(domain_soft.ValidateCorpusValue(*corpus_val_soft).ok()); } -TEST(ContainerDeathTest, MutationAbortsWhenSizeExceedsMaxSize) { +TEST(ContainerTest, + MutationDoesNotAbortWhenSizeExceedsMaxSizeButEnforcesShrink) { auto domain_hard = Arbitrary>().WithMaxSize(2); std::vector value = {1, 2, 3}; Value val(domain_hard, value); absl::BitGen bitgen; - EXPECT_DEATH( - val.Mutate(domain_hard, bitgen, /*metadata=*/{}, /*only_shrink=*/false), - "Size 3 is not between 0 and 2"); + // Should not crash, despite size 3 > max_size 2. + val.Mutate(domain_hard, bitgen, /*metadata=*/{}, /*only_shrink=*/false); + + // Size should not have grown. + EXPECT_LE(val.user_value.size(), 3); + + // If we mutate enough times, it should eventually shrink to <= 2. + bool shrunk = false; + for (int i = 0; i < 1000; ++i) { + val.Mutate(domain_hard, bitgen, /*metadata=*/{}, /*only_shrink=*/false); + if (val.user_value.size() <= 2) { + shrunk = true; + break; + } + } + EXPECT_TRUE(shrunk); } TEST(ContainerTest, WithSoftMaxSizeMutationDoesNotGrowIfSizeExceedsLimit) { diff --git a/fuzztest/internal/domains/container_of_impl.h b/fuzztest/internal/domains/container_of_impl.h index 7a8cd456..ca8286dd 100644 --- a/fuzztest/internal/domains/container_of_impl.h +++ b/fuzztest/internal/domains/container_of_impl.h @@ -114,14 +114,10 @@ class ContainerOfImplBase const domain_implementor::MutationMetadata& metadata, bool only_shrink) { permanent_dict_candidate_ = std::nullopt; - if (!validate_max_size()) { - FUZZTEST_CHECK(min_size() <= val.size()) - << "Size " << val.size() << " is smaller than min size " - << min_size(); - } else { - FUZZTEST_CHECK(min_size() <= val.size() && val.size() <= max_size()) - << "Size " << val.size() << " is not between " << min_size() - << " and " << max_size(); + FUZZTEST_CHECK(min_size() <= val.size()) + << "Size " << val.size() << " is smaller than min size " << min_size(); + if (validate_max_size() && val.size() > max_size()) { + only_shrink = true; } const bool can_shrink = val.size() > min_size();