From e6ea44c9119b0f5976ea7b335395753833fc382d Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 7 Nov 2023 13:38:16 -0800 Subject: [PATCH] Fix upb_MiniTable_GetOneof(miniTable, field) to work correctly if `field` is the very first field in the proto. PiperOrigin-RevId: 580285127 --- upb/mini_table/message.c | 2 +- upb/test/BUILD | 1 + upb/test/proto3_test.proto | 10 ++++++++++ upb/test/test_mini_table_oneof.cc | 10 ++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/upb/mini_table/message.c b/upb/mini_table/message.c index 56f23014a3..28635cdb0a 100644 --- a/upb/mini_table/message.c +++ b/upb/mini_table/message.c @@ -55,7 +55,7 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, } const upb_MiniTableField* ptr = &m->fields[0]; const upb_MiniTableField* end = &m->fields[m->field_count]; - while (++ptr < end) { + for (; ptr < end; ptr++) { if (ptr->presence == (*f).presence) { return ptr; } diff --git a/upb/test/BUILD b/upb/test/BUILD index b101237ddf..93661f452e 100644 --- a/upb/test/BUILD +++ b/upb/test/BUILD @@ -239,6 +239,7 @@ cc_test( ], deps = [ ":empty_upb_proto_reflection", + ":proto3_test_upb_proto", ":test_messages_proto2_upb_minitable", ":test_upb_proto", "@com_google_googletest//:gtest_main", diff --git a/upb/test/proto3_test.proto b/upb/test/proto3_test.proto index 28bc4d347d..774538f42b 100644 --- a/upb/test/proto3_test.proto +++ b/upb/test/proto3_test.proto @@ -27,3 +27,13 @@ message TestMessage3 { optional TestMessage3 msg = 5; repeated TestMessage3 r_msg = 6; } + +// See the InitialFieldOneOf test in test_mini_table_oneof.cc. +message TestOneOfInitialField { + oneof oneof_field { + int32 a = 1; + uint32 b = 2; + } + + float c = 3; +} diff --git a/upb/test/test_mini_table_oneof.cc b/upb/test/test_mini_table_oneof.cc index 3c0ecae0f5..850d57186e 100644 --- a/upb/test/test_mini_table_oneof.cc +++ b/upb/test/test_mini_table_oneof.cc @@ -9,6 +9,7 @@ #include "google/protobuf/test_messages_proto2.upb_minitable.h" #include "upb/mini_table/field.h" #include "upb/mini_table/message.h" +#include "upb/test/proto3_test.upb.h" // Must be last. #include "upb/port/def.inc" @@ -29,6 +30,15 @@ TEST(MiniTableOneofTest, OneOfIteratorProto2) { } while (upb_MiniTable_NextOneofField(google_protobuf_table, &ptr)); } +TEST(MiniTableOneofTest, InitialFieldOneOf) { + const upb_MiniTable* table = &upb__test__TestOneOfInitialField_msg_init; + const upb_MiniTableField* field = upb_MiniTable_FindFieldByNumber(table, 1); + ASSERT_TRUE(field != nullptr); + + const upb_MiniTableField* ptr = upb_MiniTable_GetOneof(table, field); + EXPECT_TRUE(ptr == field); +} + TEST(MiniTableOneofTest, InitialFieldNotOneOf) { constexpr int test_field_number = 1; // optional int that is not a oneof const upb_MiniTable* google_protobuf_table =