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); static const char* MpRepeatedString(PROTOBUF_TC_PARAM_DECL);
template <bool is_split> template <bool is_split>
static const char* MpMessage(PROTOBUF_TC_PARAM_DECL); 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* MpLazyMessage(PROTOBUF_TC_PARAM_DECL);
static const char* MpFallback(PROTOBUF_TC_PARAM_DECL); static const char* MpFallback(PROTOBUF_TC_PARAM_DECL);
static const char* MpMap(PROTOBUF_TC_PARAM_DECL); static const char* MpMap(PROTOBUF_TC_PARAM_DECL);

@ -37,6 +37,7 @@
#include <utility> #include <utility>
#include "absl/base/optimization.h" #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_decl.h"
#include "google/protobuf/generated_message_tctable_impl.h" #include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/inlined_string_field.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: // Check for repeated parsing:
if (card == field_layout::kFcRepeated) { 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(); 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 auto& entry = RefAt<FieldEntry>(table, data.entry_offset());
const uint16_t type_card = entry.type_card; const uint16_t type_card = entry.type_card;
ABSL_DCHECK_EQ(type_card & field_layout::kFcMask, ABSL_DCHECK_EQ(type_card & field_layout::kFcMask,
static_cast<uint16_t>(field_layout::kFcRepeated)); static_cast<uint16_t>(field_layout::kFcRepeated));
const uint32_t decoded_tag = data.tag(); const uint32_t decoded_tag = data.tag();
const uint32_t decoded_wiretype = decoded_tag & 7; 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: // Validate wiretype:
switch (rep) { if (!is_group) {
case field_layout::kRepMessage: ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
static_cast<uint16_t>(field_layout::kRepMessage));
if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { if (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
goto fallback; PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
} }
break; } else {
case field_layout::kRepGroup: ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
static_cast<uint16_t>(field_layout::kRepGroup));
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) { if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
goto fallback;
}
break;
default: {
fallback:
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS); 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); const auto aux = *table->field_aux(&entry);
if ((type_card & field_layout::kTvMask) == field_layout::kTvTable) { if ((type_card & field_layout::kTvMask) == field_layout::kTvTable) {
auto* inner_table = aux.table; auto* inner_table = aux.table;
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>( const MessageLite* default_instance = inner_table->default_instance;
inner_table->default_instance); const char* ptr2 = ptr;
if (is_group) { uint32_t next_tag;
return ctx->ParseGroup<TcParser>(value, ptr, decoded_tag, inner_table); do {
} MessageLite* value =
return ctx->ParseMessage<TcParser>(value, ptr, inner_table); 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 { } else {
const MessageLite* def; const MessageLite* default_instance;
if ((type_card & field_layout::kTvMask) == field_layout::kTvDefault) { if ((type_card & field_layout::kTvMask) == field_layout::kTvDefault) {
def = aux.message_default(); default_instance = aux.message_default();
} else { } else {
ABSL_DCHECK_EQ(type_card & field_layout::kTvMask, ABSL_DCHECK_EQ(type_card & field_layout::kTvMask,
+field_layout::kTvWeakPtr); +field_layout::kTvWeakPtr);
def = aux.message_default_weak(); default_instance = aux.message_default_weak();
} }
MessageLite* value = field.Add<GenericTypeHandler<MessageLite>>(def); const char* ptr2 = ptr;
if (is_group) { uint32_t next_tag;
return ctx->ParseGroup(value, ptr, decoded_tag); do {
} MessageLite* value =
return ctx->ParseMessage(value, ptr); 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, static void SerializeMapKey(const NodeBase* node, MapTypeCard type_card,

Loading…
Cancel
Save