From 0a95c63879cb41ba95cd80324246e410654778d1 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Fri, 28 Aug 2026 09:11:25 -0700 Subject: [PATCH] Fix oneof handling in SubsetMiniTable to preserve roundtrip equivalence during conversion fuzz testing. PiperOrigin-RevId: 972624039 --- upb/message/convert_fuzz_test.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/upb/message/convert_fuzz_test.cc b/upb/message/convert_fuzz_test.cc index 2c86d02a2b749..583b6fef91182 100644 --- a/upb/message/convert_fuzz_test.cc +++ b/upb/message/convert_fuzz_test.cc @@ -38,7 +38,12 @@ const upb_MiniTable* SubsetMiniTable(const upb_MiniTable* src, uint64_t mask, int field_count = upb_MiniTable_FieldCount(src); for (int i = 0; i < field_count; ++i) { const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(src, i); - if (mask & (1ULL << (i % 64))) { + // If the field belongs to a oneof, select/drop the oneof as a whole unit + // to preserve roundtrip equivalence. Splitting individual fields within the + // same oneof between known and unknown fields can invert wire serialization + // order when multiple oneof fields are present in the wire payload. + int mask_bit = (f->presence < 0) ? (32 + (~f->presence)) : (i % 32); + if (mask & (1ULL << (mask_bit % 64))) { upb_MiniTableField new_f = *f; if (f->UPB_PRIVATE(submsg_ofs) != kUpb_NoSub) { new_subs.push_back( @@ -615,6 +620,12 @@ TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression_b529945368) { 20), 372456973, 1140553636); } + +TEST(ConvertFuzz, ConvertFuzzRegression_b553987075) { + ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"$::1/1*^(|%"}, {}, "", {}}, + 13624504597643522060ULL, 16497767249782210611ULL, " 00", + 3016566825, 2825661372); +} } // namespace } // namespace upb