Skip to content

Commit

Permalink
Check next tag in MpRepeatedMessage.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 542301567
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Jun 21, 2023
1 parent adb2c4b commit 9e1cf6f
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 32 deletions.
4 changes: 3 additions & 1 deletion src/google/protobuf/generated_message_tctable_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
89 changes: 58 additions & 31 deletions src/google/protobuf/generated_message_tctable_lite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 (decoded_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
goto fallback;
}
break;
case field_layout::kRepGroup:
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
goto fallback;
}
break;
default: {
fallback:
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) {
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
} else {
ABSL_DCHECK_EQ(type_card & field_layout::kRepMask,
static_cast<uint16_t>(field_layout::kRepGroup));
if (decoded_wiretype != WireFormatLite::WIRETYPE_START_GROUP) {
PROTOBUF_MUSTTAIL return table->fallback(PROTOBUF_TC_PARAM_PASS);
}
}
Expand All @@ -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,
Expand Down

0 comments on commit 9e1cf6f

Please sign in to comment.