Check next tag in MpRepeatedMessage.

PiperOrigin-RevId: 542301567
pull/13109/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent adb2c4b415
commit 9e1cf6fe9c
  1. 4
      src/google/protobuf/generated_message_tctable_impl.h
  2. 83
      src/google/protobuf/generated_message_tctable_lite.cc

@ -875,7 +875,9 @@ class PROTOBUF_EXPORT TcParser final {
static const char* MpRepeatedString(PROTOBUF_TC_PARAM_DECL);
template <bool is_split>
static const char* MpMessage(PROTOBUF_TC_PARAM_DECL);
static const char* MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL);
template <bool is_group>
static const char* MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL);
static const char* MpRepeatedGroup(PROTOBUF_TC_PARAM_DECL);
static const char* MpLazyMessage(PROTOBUF_TC_PARAM_DECL);
static const char* MpFallback(PROTOBUF_TC_PARAM_DECL);
static const char* MpMap(PROTOBUF_TC_PARAM_DECL);

@ -37,6 +37,7 @@
#include <utility>
#include "absl/base/optimization.h"
#include "absl/log/absl_check.h"
#include "google/protobuf/generated_message_tctable_decl.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/inlined_string_field.h"
@ -2357,7 +2358,17 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {
// Check for repeated parsing:
if (card == field_layout::kFcRepeated) {
PROTOBUF_MUSTTAIL return MpRepeatedMessage(PROTOBUF_TC_PARAM_PASS);
const uint16_t rep = type_card & field_layout::kRepMask;
switch (rep) {
case field_layout::kRepMessage:
PROTOBUF_MUSTTAIL return MpRepeatedMessageOrGroup<false>(
PROTOBUF_TC_PARAM_PASS);
case field_layout::kRepGroup:
PROTOBUF_MUSTTAIL return MpRepeatedMessageOrGroup<true>(
PROTOBUF_TC_PARAM_PASS);
default:
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
}
const uint32_t decoded_tag = data.tag();
@ -2422,30 +2433,26 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {
}
}
const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {
template <bool is_group>
const char* TcParser::MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL) {
const auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
const uint16_t type_card = entry.type_card;
ABSL_DCHECK_EQ(type_card & field_layout::kFcMask,
static_cast<uint16_t>(field_layout::kFcRepeated));
const uint32_t decoded_tag = data.tag();
const uint32_t decoded_wiretype = decoded_tag & 7;
const uint16_t rep = type_card & field_layout::kRepMask;
const bool is_group = rep == field_layout::kRepGroup;
// Validate wiretype:
switch (rep) {
case field_layout::kRepMessage:
if (!is_group) {
ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
static_cast<uint16_t>(field_layout::kRepMessage));
if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
goto fallback;
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
break;
case field_layout::kRepGroup:
} else {
ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
static_cast<uint16_t>(field_layout::kRepGroup));
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
goto fallback;
}
break;
default: {
fallback:
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
}
@ -2455,27 +2462,47 @@ const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {
const auto aux = *table->field_aux(&entry);
if ((type_card & field_layout::kTvMask) == field_layout::kTvTable) {
auto* inner_table = aux.table;
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>(
inner_table->default_instance);
if (is_group) {
return ctx->ParseGroup<TcParser>(value, ptr, decoded_tag, inner_table);
}
return ctx->ParseMessage<TcParser>(value, ptr, inner_table);
const MessageLite* default_instance = inner_table->default_instance;
const char* ptr2 = ptr;
uint32_t next_tag;
do {
MessageLite* value =
field.Add<GenericTypeHandler<MessageLite>>(default_instance);
ptr = is_group ? ctx->ParseGroup<TcParser>(value, ptr2, decoded_tag,
inner_table)
: ctx->ParseMessage<TcParser>(value, ptr2, inner_table);
if (ptr == nullptr) goto error;
if (!ctx->DataAvailable(ptr)) goto parse_loop;
ptr2 = ReadTag(ptr, &next_tag);
if (ptr2 == nullptr) goto error;
} while (next_tag == decoded_tag);
} else {
const MessageLite* def;
const MessageLite* default_instance;
if ((type_card & field_layout::kTvMask) == field_layout::kTvDefault) {
def = aux.message_default();
default_instance = aux.message_default();
} else {
ABSL_DCHECK_EQ(type_card & field_layout::kTvMask,
+field_layout::kTvWeakPtr);
def = aux.message_default_weak();
default_instance = aux.message_default_weak();
}
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>(def);
if (is_group) {
return ctx->ParseGroup(value, ptr, decoded_tag);
}
return ctx->ParseMessage(value, ptr);
const char* ptr2 = ptr;
uint32_t next_tag;
do {
MessageLite* value =
field.Add<GenericTypeHandler<MessageLite>>(default_instance);
ptr = is_group ? ctx->ParseGroup(value, ptr2, decoded_tag)
: ctx->ParseMessage(value, ptr2);
if (ptr == nullptr) goto error;
if (!ctx->DataAvailable(ptr)) goto parse_loop;
ptr2 = ReadTag(ptr, &next_tag);
if (ptr2 == nullptr) goto error;
} while (next_tag == decoded_tag);
}
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
parse_loop:
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
error:
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
}
static void SerializeMapKey(const NodeBase* node, MapTypeCard type_card,

Loading…
Cancel
Save