Skip to content

Commit 9e1cf6f

Browse files
Check next tag in MpRepeatedMessage.
PiperOrigin-RevId: 542301567
1 parent adb2c4b commit 9e1cf6f

File tree

2 files changed

+61
-32
lines changed

2 files changed

+61
-32
lines changed

src/google/protobuf/generated_message_tctable_impl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,9 @@ class PROTOBUF_EXPORT TcParser final {
875875
static const char* MpRepeatedString(PROTOBUF_TC_PARAM_DECL);
876876
template <bool is_split>
877877
static const char* MpMessage(PROTOBUF_TC_PARAM_DECL);
878-
static const char* MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL);
878+
template <bool is_group>
879+
static const char* MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL);
880+
static const char* MpRepeatedGroup(PROTOBUF_TC_PARAM_DECL);
879881
static const char* MpLazyMessage(PROTOBUF_TC_PARAM_DECL);
880882
static const char* MpFallback(PROTOBUF_TC_PARAM_DECL);
881883
static const char* MpMap(PROTOBUF_TC_PARAM_DECL);

src/google/protobuf/generated_message_tctable_lite.cc

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <utility>
3838

3939
#include "absl/base/optimization.h"
40+
#include "absl/log/absl_check.h"
4041
#include "google/protobuf/generated_message_tctable_decl.h"
4142
#include "google/protobuf/generated_message_tctable_impl.h"
4243
#include "google/protobuf/inlined_string_field.h"
@@ -2357,7 +2358,17 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {
23572358

23582359
// Check for repeated parsing:
23592360
if (card == field_layout::kFcRepeated) {
2360-
PROTOBUF_MUSTTAIL return MpRepeatedMessage(PROTOBUF_TC_PARAM_PASS);
2361+
const uint16_t rep = type_card & field_layout::kRepMask;
2362+
switch (rep) {
2363+
case field_layout::kRepMessage:
2364+
PROTOBUF_MUSTTAIL return MpRepeatedMessageOrGroup<false>(
2365+
PROTOBUF_TC_PARAM_PASS);
2366+
case field_layout::kRepGroup:
2367+
PROTOBUF_MUSTTAIL return MpRepeatedMessageOrGroup<true>(
2368+
PROTOBUF_TC_PARAM_PASS);
2369+
default:
2370+
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
2371+
}
23612372
}
23622373

23632374
const uint32_t decoded_tag = data.tag();
@@ -2422,30 +2433,26 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {
24222433
}
24232434
}
24242435

2425-
const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {
2436+
template <bool is_group>
2437+
const char* TcParser::MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL) {
24262438
const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
24272439
const uint16_t type_card = entry.type_card;
24282440
ABSL_DCHECK_EQ(type_card & field_layout::kFcMask,
24292441
static_cast<uint16_t>(field_layout::kFcRepeated));
24302442
const uint32_t decoded_tag = data.tag();
24312443
const uint32_t decoded_wiretype = decoded_tag & 7;
2432-
const uint16_t rep = type_card & field_layout::kRepMask;
2433-
const bool is_group = rep == field_layout::kRepGroup;
24342444

24352445
// Validate wiretype:
2436-
switch (rep) {
2437-
case field_layout::kRepMessage:
2438-
if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
2439-
goto fallback;
2440-
}
2441-
break;
2442-
case field_layout::kRepGroup:
2443-
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
2444-
goto fallback;
2445-
}
2446-
break;
2447-
default: {
2448-
fallback:
2446+
if (!is_group) {
2447+
ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
2448+
static_cast<uint16_t>(field_layout::kRepMessage));
2449+
if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
2450+
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
2451+
}
2452+
} else {
2453+
ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
2454+
static_cast<uint16_t>(field_layout::kRepGroup));
2455+
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
24492456
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
24502457
}
24512458
}
@@ -2455,27 +2462,47 @@ const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {
24552462
const auto aux = *table->field_aux(&entry);
24562463
if ((type_card & field_layout::kTvMask) == field_layout::kTvTable) {
24572464
auto* inner_table = aux.table;
2458-
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>(
2459-
inner_table->default_instance);
2460-
if (is_group) {
2461-
return ctx->ParseGroup<TcParser>(value, ptr, decoded_tag, inner_table);
2462-
}
2463-
return ctx->ParseMessage<TcParser>(value, ptr, inner_table);
2465+
const MessageLite* default_instance = inner_table->default_instance;
2466+
const char* ptr2 = ptr;
2467+
uint32_t next_tag;
2468+
do {
2469+
MessageLite* value =
2470+
field.Add<GenericTypeHandler<MessageLite>>(default_instance);
2471+
ptr = is_group ? ctx->ParseGroup<TcParser>(value, ptr2, decoded_tag,
2472+
inner_table)
2473+
: ctx->ParseMessage<TcParser>(value, ptr2, inner_table);
2474+
if (ptr == nullptr) goto error;
2475+
if (!ctx->DataAvailable(ptr)) goto parse_loop;
2476+
ptr2 = ReadTag(ptr, &next_tag);
2477+
if (ptr2 == nullptr) goto error;
2478+
} while (next_tag == decoded_tag);
24642479
} else {
2465-
const MessageLite* def;
2480+
const MessageLite* default_instance;
24662481
if ((type_card & field_layout::kTvMask) == field_layout::kTvDefault) {
2467-
def = aux.message_default();
2482+
default_instance = aux.message_default();
24682483
} else {
24692484
ABSL_DCHECK_EQ(type_card & field_layout::kTvMask,
24702485
+field_layout::kTvWeakPtr);
2471-
def = aux.message_default_weak();
2486+
default_instance = aux.message_default_weak();
24722487
}
2473-
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>(def);
2474-
if (is_group) {
2475-
return ctx->ParseGroup(value, ptr, decoded_tag);
2476-
}
2477-
return ctx->ParseMessage(value, ptr);
2488+
const char* ptr2 = ptr;
2489+
uint32_t next_tag;
2490+
do {
2491+
MessageLite* value =
2492+
field.Add<GenericTypeHandler<MessageLite>>(default_instance);
2493+
ptr = is_group ? ctx->ParseGroup(value, ptr2, decoded_tag)
2494+
: ctx->ParseMessage(value, ptr2);
2495+
if (ptr == nullptr) goto error;
2496+
if (!ctx->DataAvailable(ptr)) goto parse_loop;
2497+
ptr2 = ReadTag(ptr, &next_tag);
2498+
if (ptr2 == nullptr) goto error;
2499+
} while (next_tag == decoded_tag);
24782500
}
2501+
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
2502+
parse_loop:
2503+
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
2504+
error:
2505+
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
24792506
}
24802507

24812508
static void SerializeMapKey(const NodeBase* node, MapTypeCard type_card,

0 commit comments

Comments
 (0)