add return codes to upb_MiniTable_SetSubMessage/Enum()

Currently these functions are hardwired to always return true, but the upstream
code now checks for failures (which will be implemented soon).

PiperOrigin-RevId: 504943663
pull/13171/head
Eric Salo 2 years ago committed by Copybara-Service
parent dd6d3b8740
commit b29761fece
  1. 18
      upb/message/accessors_test.cc
  2. 6
      upb/mini_table/decode.c
  3. 16
      upb/mini_table/decode.h
  4. 11
      upb/reflection/message_def.c
  5. 15
      upb/test/fuzz_util.cc

@ -642,9 +642,9 @@ TEST(GeneratedCode, PromoteUnknownMessage) {
upb_FindUnknownRet unknown = upb_MiniTable_FindUnknown(msg, 5);
EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
// Update mini table and promote unknown to a message.
upb_MiniTable_SetSubMessage(mini_table,
(upb_MiniTableField*)&mini_table->fields[1],
&upb_test_ModelWithExtensions_msg_init);
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[1],
&upb_test_ModelWithExtensions_msg_init));
const int decode_options =
UPB_DECODE_MAXDEPTH(100); // UPB_DECODE_ALIAS disabled.
upb_UnknownToMessageRet promote_result =
@ -691,9 +691,9 @@ TEST(GeneratedCode, PromoteUnknownRepeatedMessage) {
EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
// Update mini table and promote unknown to a message.
upb_MiniTable_SetSubMessage(mini_table,
(upb_MiniTableField*)&mini_table->fields[2],
&upb_test_ModelWithExtensions_msg_init);
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[2],
&upb_test_ModelWithExtensions_msg_init));
const int decode_options =
UPB_DECODE_MAXDEPTH(100); // UPB_DECODE_ALIAS disabled.
upb_UnknownToMessage_Status promote_result =
@ -746,9 +746,9 @@ TEST(GeneratedCode, PromoteUnknownToMap) {
EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
// Update mini table and promote unknown to a message.
upb_MiniTable_SetSubMessage(mini_table,
(upb_MiniTableField*)&mini_table->fields[1],
map_entry_mini_table);
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[1],
map_entry_mini_table));
const int decode_options =
UPB_DECODE_MAXDEPTH(100); // UPB_DECODE_ALIAS disabled.
upb_UnknownToMessage_Status promote_result =

@ -973,7 +973,7 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len,
return ret;
}
void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTableField* field,
const upb_MiniTable* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
@ -989,13 +989,15 @@ void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
}
upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
table_sub->submsg = sub;
return true;
}
void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
const upb_MiniTableEnum* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
table_sub->subenum = sub;
return true;
}

@ -61,19 +61,21 @@ UPB_API_INLINE upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
status);
}
// Links a sub-message field to a MiniTable for that sub-message. If a
// Links a sub-message field to a MiniTable for that sub-message. If a
// sub-message field is not linked, it will be treated as an unknown field
// during parsing, and setting the field will not be allowed. It is possible
// during parsing, and setting the field will not be allowed. It is possible
// to link the message field later, at which point it will no longer be treated
// as unknown. However there is no synchronization for this operation, which
// as unknown. However there is no synchronization for this operation, which
// means parallel mutation requires external synchronization.
UPB_API void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
// Returns success/failure.
UPB_API bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTableField* field,
const upb_MiniTable* sub);
// Links an enum field to a MiniTable for that enum. All enum fields must
// be linked prior to parsing.
UPB_API void upb_MiniTable_SetSubEnum(upb_MiniTable* table,
// Links an enum field to a MiniTable for that enum.
// All enum fields must be linked prior to parsing.
// Returns success/failure.
UPB_API bool upb_MiniTable_SetSubEnum(upb_MiniTable* table,
upb_MiniTableField* field,
const upb_MiniTableEnum* sub);

@ -461,13 +461,18 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
(upb_MiniTableField*)&m->layout->fields[layout_index];
if (sub_m) {
if (!mt->subs) {
_upb_DefBuilder_Errf(ctx, "invalid submsg for (%s)", m->full_name);
_upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name);
}
UPB_ASSERT(mt_f);
UPB_ASSERT(sub_m->layout);
upb_MiniTable_SetSubMessage(mt, mt_f, sub_m->layout);
if (UPB_UNLIKELY(!upb_MiniTable_SetSubMessage(mt, mt_f, sub_m->layout))) {
_upb_DefBuilder_Errf(ctx, "invalid submsg for (%s)", m->full_name);
}
} else if (_upb_FieldDef_IsClosedEnum(f)) {
upb_MiniTable_SetSubEnum(mt, mt_f, _upb_EnumDef_MiniTable(sub_e));
const upb_MiniTableEnum* mt_e = _upb_EnumDef_MiniTable(sub_e);
if (UPB_UNLIKELY(!upb_MiniTable_SetSubEnum(mt, mt_f, mt_e))) {
_upb_DefBuilder_Errf(ctx, "invalid subenum for (%s)", m->full_name);
}
}
}

@ -47,7 +47,7 @@ class Builder {
BuildMessages();
BuildEnums();
BuildExtensions(exts);
LinkMessages();
if (!LinkMessages()) return nullptr;
return mini_tables_.empty() ? nullptr : mini_tables_.front();
}
@ -56,7 +56,7 @@ class Builder {
void BuildEnums();
void BuildExtensions(upb_ExtensionRegistry** exts);
bool LinkExtension(upb_MiniTableExtension* ext);
void LinkMessages();
bool LinkMessages();
size_t NextLink() {
if (input_->links.empty()) return 0;
@ -160,7 +160,7 @@ void Builder::BuildExtensions(upb_ExtensionRegistry** exts) {
}
}
void Builder::LinkMessages() {
bool Builder::LinkMessages() {
for (auto* t : mini_tables_) {
upb_MiniTable* table = const_cast<upb_MiniTable*>(t);
// For each field that requires a sub-table, assign one as appropriate.
@ -173,19 +173,21 @@ void Builder::LinkMessages() {
const upb_MiniTable* sub = NextMiniTable();
// We should always have at least one message.
assert(sub);
upb_MiniTable_SetSubMessage(table, field, sub);
if (!upb_MiniTable_SetSubMessage(table, field, sub)) return false;
break;
}
case kUpb_FieldType_Group: {
const upb_MiniTable* sub = NextNonMapEntryMiniTable();
// sub will be nullptr if no non-map entry messages are available.
if (sub) upb_MiniTable_SetSubMessage(table, field, sub);
if (sub) {
if (!upb_MiniTable_SetSubMessage(table, field, sub)) return false;
}
break;
}
case kUpb_FieldType_Enum: {
auto* et = NextEnumTable();
if (et) {
upb_MiniTable_SetSubEnum(table, field, et);
if (!upb_MiniTable_SetSubEnum(table, field, et)) return false;
} else {
// We don't have any sub-enums. Override the field type so that it
// is not needed.
@ -195,6 +197,7 @@ void Builder::LinkMessages() {
}
}
}
return true;
}
} // namespace

Loading…
Cancel
Save