From a7e309d595353a8b045583ac07707f822ac744be Mon Sep 17 00:00:00 2001 From: FuzzTest Team Date: Tue, 26 May 2026 02:41:36 -0700 Subject: [PATCH] Refactor FlatbuffersTableUntypedDomainImpl::MutateSelectedField to use a visitor. This change introduces MutateSelectedFieldVisitor to encapsulate the logic for mutating a specific field index. This allows for a more uniform handling of different field types, including recursive calls for nested tables, within the visitor pattern. PiperOrigin-RevId: 921337267 --- .../domains/flatbuffers_domain_impl.cc | 21 ++-------- .../domains/flatbuffers_domain_impl.h | 38 +++++++++++++++---- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/fuzztest/internal/domains/flatbuffers_domain_impl.cc b/fuzztest/internal/domains/flatbuffers_domain_impl.cc index 90313441..75531b27 100644 --- a/fuzztest/internal/domains/flatbuffers_domain_impl.cc +++ b/fuzztest/internal/domains/flatbuffers_domain_impl.cc @@ -136,23 +136,10 @@ uint64_t FlatbuffersTableUntypedDomainImpl::MutateSelectedField( } ++field_counter; - if (field_counter == selected_field_index) { - VisitFlatbufferField( - schema_, field, - MutateVisitor{*this, prng, metadata, only_shrink, val}); - return field_counter; - } - - if (field->type()->base_type() == reflection::BaseType::Obj) { - auto sub_object = schema_->objects()->Get(field->type()->index()); - if (!sub_object->is_struct()) { - field_counter += - GetCachedDomain(field).MutateSelectedField( - val[field->id()], prng, metadata, only_shrink, - selected_field_index - field_counter); - } - // TODO: Add support for structs. - } + VisitFlatbufferField( + schema_, field, + MutateSelectedFieldVisitor{*this, field_counter, val, prng, metadata, + only_shrink, selected_field_index}); if (field_counter >= selected_field_index) { return field_counter; diff --git a/fuzztest/internal/domains/flatbuffers_domain_impl.h b/fuzztest/internal/domains/flatbuffers_domain_impl.h index 328b2e7b..54590714 100644 --- a/fuzztest/internal/domains/flatbuffers_domain_impl.h +++ b/fuzztest/internal/domains/flatbuffers_domain_impl.h @@ -618,22 +618,36 @@ class FlatbuffersTableUntypedDomainImpl } }; - struct MutateVisitor { + struct MutateSelectedFieldVisitor { FlatbuffersTableUntypedDomainImpl& self; + uint64_t& field_counter; + corpus_type& val; absl::BitGenRef prng; const domain_implementor::MutationMetadata& metadata; bool only_shrink; - corpus_type& corpus_value; + uint64_t selected_field_index; template void Visit(const reflection::Field* absl_nonnull field) { - auto& domain = self.GetCachedDomain(field); - auto it = corpus_value.find(field->id()); - if (it == corpus_value.end()) { - if (only_shrink) return; - it = corpus_value.try_emplace(field->id(), domain.Init(prng)).first; + if (!self.IsSupportedField(field)) return; + if (only_shrink && !val.contains(field->id())) return; + + if (field_counter == selected_field_index) { + auto& domain = self.GetCachedDomain(field); + auto it = val.find(field->id()); + if (it == val.end()) { + if (only_shrink) return; + it = val.try_emplace(field->id(), domain.Init(prng)).first; + } + domain.Mutate(it->second, prng, metadata, only_shrink); + } else { + auto& domain = self.GetCachedDomain(field); + if (auto it = val.find(field->id()); it != val.end()) { + field_counter += domain.MutateSelectedField( + it->second, prng, metadata, only_shrink, + selected_field_index - field_counter); + } } - domain.Mutate(it->second, prng, metadata, only_shrink); } }; @@ -764,6 +778,14 @@ class FlatbuffersTableDomainImpl return inner_->CountNumberOfFields(val.untyped_corpus); } + uint64_t MutateSelectedField( + corpus_type& val, absl::BitGenRef prng, + const domain_implementor::MutationMetadata& metadata, bool only_shrink, + uint64_t selected_field_index) { + return inner_->MutateSelectedField(val.untyped_corpus, prng, metadata, + only_shrink, selected_field_index); + } + // Mutates the given corpus value. void Mutate(corpus_type& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata,