Fix handling of Cord fields in the table-driven parser.

PiperOrigin-RevId: 529161871
pull/12585/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 421167dae3
commit fdfb95849b
  1. 21
      src/google/protobuf/generated_message_tctable_gen.cc
  2. 4
      src/google/protobuf/generated_message_tctable_impl.h
  3. 32
      src/google/protobuf/generated_message_tctable_lite.cc

@ -694,10 +694,23 @@ uint16_t MakeTypeCardForField(
// Fill in extra information about string and bytes field representations.
if (field->type() == FieldDescriptor::TYPE_BYTES ||
field->type() == FieldDescriptor::TYPE_STRING) {
if (field->is_repeated()) {
type_card |= fl::kRepSString;
} else {
type_card |= fl::kRepAString;
switch (internal::cpp::EffectiveStringCType(field)) {
case FieldOptions::CORD:
// `Cord` is always used, even for repeated fields.
type_card |= fl::kRepCord;
break;
case FieldOptions::STRING:
if (field->is_repeated()) {
// A repeated string field uses RepeatedPtrField<std::string>
// (unless it has a ctype option; see above).
type_card |= fl::kRepSString;
} else {
// Otherwise, non-repeated string fields use ArenaStringPtr.
type_card |= fl::kRepAString;
}
break;
default:
PROTOBUF_ASSUME(false);
}
}

@ -850,6 +850,10 @@ class PROTOBUF_EXPORT TcParser final {
const TcParseTableBase* table,
const TcParseTableBase::FieldEntry& entry,
uint16_t xform_val);
static bool MpVerifyUtf8(const absl::Cord& wire_bytes,
const TcParseTableBase* table,
const TcParseTableBase::FieldEntry& entry,
uint16_t xform_val);
// For FindFieldEntry tests:
friend class FindFieldEntryTest;

@ -2100,6 +2100,15 @@ bool TcParser::MpVerifyUtf8(absl::string_view wire_bytes,
#endif // NDEBUG
return true;
}
bool TcParser::MpVerifyUtf8(const absl::Cord& wire_bytes,
const TcParseTableBase* table,
const FieldEntry& entry, uint16_t xform_val) {
switch (xform_val) {
default:
ABSL_DCHECK_EQ(xform_val, 0);
return true;
}
}
template <bool is_split>
PROTOBUF_NOINLINE const char* TcParser::MpString(PROTOBUF_TC_PARAM_DECL) {
@ -2144,10 +2153,29 @@ PROTOBUF_NOINLINE const char* TcParser::MpString(PROTOBUF_TC_PARAM_DECL) {
break;
}
case field_layout::kRepIString: {
ABSL_DCHECK(false);
case field_layout::kRepCord: {
absl::Cord* field;
if (is_oneof) {
if (need_init) {
field = new absl::Cord;
RefAt<absl::Cord*>(msg, entry.offset) = field;
Arena* arena = msg->GetArenaForAllocation();
if (arena) arena->Own(field);
} else {
field = RefAt<absl::Cord*>(msg, entry.offset);
}
} else {
field = &RefAt<absl::Cord>(base, entry.offset);
}
ptr = InlineCordParser(field, ptr, ctx);
if (!ptr) break;
is_valid = MpVerifyUtf8(*field, table, entry, xform_val);
break;
}
default:
PROTOBUF_ASSUME(false);
}
if (ptr == nullptr || !is_valid) {

Loading…
Cancel
Save