mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Treat mismatched length-delimited repeated Group tags as unknown fields in upb.
PiperOrigin-RevId: 921438940
This commit is contained in:
parent
40825a1df7
commit
9040f41344
4 changed files with 49 additions and 3 deletions
|
|
@ -855,7 +855,7 @@ static int _upb_Decoder_GetDelimitedOp(upb_Decoder* d, const upb_MiniTable* mt,
|
|||
[kRepeatedBase + kUpb_FieldType_Fixed32] = OP_FIXPCK_LG2(2),
|
||||
[kRepeatedBase + kUpb_FieldType_Bool] = OP_VARPCK_LG2(0),
|
||||
[kRepeatedBase + kUpb_FieldType_String] = kUpb_DecodeOp_String,
|
||||
[kRepeatedBase + kUpb_FieldType_Group] = kUpb_DecodeOp_SubMessage,
|
||||
[kRepeatedBase + kUpb_FieldType_Group] = kUpb_DecodeOp_UnknownField,
|
||||
[kRepeatedBase + kUpb_FieldType_Message] = kUpb_DecodeOp_SubMessage,
|
||||
[kRepeatedBase + kUpb_FieldType_Bytes] = kUpb_DecodeOp_Bytes,
|
||||
[kRepeatedBase + kUpb_FieldType_UInt32] = OP_VARPCK_LG2(2),
|
||||
|
|
|
|||
|
|
@ -471,6 +471,43 @@ TEST(DecodeTest, MaxDepthPayloadParsesSuccessfully) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(DecodeTest, DecodeGroupFieldFromDelimitedWireFormatAsUnknown) {
|
||||
upb::Arena mt_arena;
|
||||
upb::Arena msg_arena;
|
||||
|
||||
// 1. Create Parent MiniTable containing a repeated Group field directly.
|
||||
auto [parent_mt, parent_field] =
|
||||
test::MiniTable::MakeSingleFieldTable<test::field_types::Group>(
|
||||
5, kUpb_DecodeFast_Repeated, mt_arena.ptr());
|
||||
|
||||
// 2. Build length-delimited wire payload for Group field 5:
|
||||
// Tag 5 Delimited = 42 (0x2a), length = 2, child field 1 = 123 ("\x08\x7b").
|
||||
std::string payload("\x2a\x02\x08\x7b", 4);
|
||||
|
||||
// 3. Parse the payload into Parent Message.
|
||||
upb_Message* parent_msg = upb_Message_New(parent_mt, msg_arena.ptr());
|
||||
upb_DecodeStatus result =
|
||||
upb_Decode(payload.data(), payload.size(), parent_msg, parent_mt, nullptr,
|
||||
0, msg_arena.ptr());
|
||||
|
||||
// 4. Verify parsing succeeded cleanly.
|
||||
ASSERT_EQ(result, kUpb_DecodeStatus_Ok) << upb_DecodeStatus_String(result);
|
||||
|
||||
// 5. Verify repeated Group field 5 was NOT populated as a known field.
|
||||
const upb_Array* arr = upb_Message_GetArray(parent_msg, parent_field);
|
||||
EXPECT_EQ(arr, nullptr);
|
||||
|
||||
// 6. Verify the wire payload was instead preserved inside the Unknown field
|
||||
// set.
|
||||
EXPECT_TRUE(upb_Message_HasUnknown(parent_msg));
|
||||
|
||||
uintptr_t iter = kUpb_Message_UnknownBegin;
|
||||
upb_StringView data;
|
||||
ASSERT_TRUE(upb_Message_NextUnknown(parent_msg, &data, &iter));
|
||||
EXPECT_EQ(absl::string_view(data.data, data.size), payload);
|
||||
EXPECT_FALSE(upb_Message_NextUnknown(parent_msg, &data, &iter));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace test
|
||||
|
|
|
|||
|
|
@ -293,7 +293,16 @@ struct ClosedEnum {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: Group
|
||||
struct Group {
|
||||
using Value = std::string;
|
||||
static constexpr upb_FieldType kFieldType = kUpb_FieldType_Group;
|
||||
static constexpr absl::string_view kName = "Group";
|
||||
static constexpr upb_DecodeFast_Type kFastType = kUpb_DecodeFast_Message;
|
||||
|
||||
static wire_types::WireValue WireValue(std::string value) {
|
||||
return wire_types::Delimited(value);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace field_types
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ MiniTable::MakeSingleFieldTable(int field_number, upb_FieldType type,
|
|||
ABSL_CHECK(ok);
|
||||
}
|
||||
#if UPB_FASTTABLE
|
||||
if (field_number < (1 << 11)) {
|
||||
if (field_number < (1 << 11) && type != kUpb_FieldType_Group) {
|
||||
ABSL_CHECK_EQ(HasFastTableEntry(table, field),
|
||||
UPB_DECODEFAST_ISENABLED(fast_type, cardinality,
|
||||
kUpb_DecodeFast_Tag1Byte))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue