upb: lock down upb_MiniTableSub

PiperOrigin-RevId: 586187469
pull/14882/head
Eric Salo 1 year ago committed by Copybara-Service
parent 4216972800
commit d0c85637e7
  1. 6
      upb/message/accessors.c
  2. 11
      upb/message/accessors.h
  3. 14
      upb/message/copy.c
  4. 6
      upb/message/promote.c
  5. 15
      upb/message/tagged_ptr.h
  6. 4
      upb/mini_descriptor/decode.c
  7. 9
      upb/mini_descriptor/decode.h
  8. 5
      upb/mini_descriptor/internal/encode_test.cc
  9. 15
      upb/mini_descriptor/link.c
  10. 4
      upb/mini_table/internal/extension.h
  11. 36
      upb/mini_table/internal/sub.h
  12. 12
      upb/mini_table/message.h
  13. 39
      upb/mini_table/sub.h
  14. 7
      upb/reflection/field_def.c
  15. 4
      upb/test/fuzz_util.cc
  16. 40
      upb/wire/decode.c
  17. 4
      upb/wire/decode_fast.c
  18. 15
      upb/wire/encode.c
  19. 8
      upb_generator/protoc-gen-upb_minitable.cc

@ -15,6 +15,7 @@
#include "upb/message/message.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
#include "upb/wire/encode.h"
// Must be last.
@ -22,11 +23,12 @@
upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
const upb_MiniTable* mini_table,
const upb_MiniTableField* field,
const upb_MiniTableField* f,
upb_Message* map_entry_message,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_mini_table =
mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_mini_table);
UPB_ASSERT(map_entry_mini_table->field_count == 2);
const upb_MiniTableField* map_entry_key_field =

@ -28,10 +28,10 @@
#include "upb/mini_table/extension.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
// Must be last.
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/message.h"
#include "upb/port/def.inc"
#ifdef __cplusplus
@ -346,7 +346,8 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr(
UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) ==
UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
UPB_ASSUME(upb_MiniTableField_IsScalar(field));
UPB_ASSERT(mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg);
UPB_ASSERT(upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]));
_upb_Message_SetNonExtensionField(msg, field, &sub_message);
}
@ -365,8 +366,8 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage(
UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message);
upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*);
if (!sub_message) {
const upb_MiniTable* sub_mini_table =
mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(sub_mini_table);
sub_message = _upb_Message_New(sub_mini_table, arena);
*UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message;

@ -29,6 +29,7 @@
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/size_log2.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
// Must be last.
#include "upb/port/def.inc"
@ -115,11 +116,12 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type,
static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map,
const upb_MiniTable* mini_table,
const upb_MiniTableField* field,
const upb_MiniTableField* f,
upb_Message* clone,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_table =
mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_table);
const upb_MiniTableField* key_field = &map_entry_table->fields[0];
@ -131,7 +133,7 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map,
if (!cloned_map) {
return NULL;
}
_upb_Message_SetNonExtensionField(clone, field, &cloned_map);
_upb_Message_SetNonExtensionField(clone, f, &cloned_map);
return cloned_map;
}
@ -267,9 +269,9 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
} else {
upb_Array* msg_array = (upb_Array*)msg_ext->data.ptr;
UPB_ASSERT(msg_array);
upb_Array* cloned_array =
upb_Array_DeepClone(msg_array, upb_MiniTableField_CType(field),
msg_ext->ext->UPB_PRIVATE(sub).submsg, arena);
upb_Array* cloned_array = upb_Array_DeepClone(
msg_array, upb_MiniTableField_CType(field),
upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena);
if (!cloned_array) {
return NULL;
}

@ -26,6 +26,7 @@
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
#include "upb/wire/decode.h"
#include "upb/wire/eps_copy_input_stream.h"
#include "upb/wire/internal/constants.h"
@ -324,8 +325,9 @@ upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMessageArray(
upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap(
upb_Message* msg, const upb_MiniTable* mini_table,
const upb_MiniTableField* field, int decode_options, upb_Arena* arena) {
const upb_MiniTable* map_entry_mini_table =
mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_mini_table);
UPB_ASSERT(map_entry_mini_table);
UPB_ASSERT(map_entry_mini_table->field_count == 2);

@ -5,8 +5,8 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef UPB_MINI_TABLE_TYPES_H_
#define UPB_MINI_TABLE_TYPES_H_
#ifndef UPB_MINI_TABLE_TAGGED_PTR_H_
#define UPB_MINI_TABLE_TAGGED_PTR_H_
#include <stdint.h>
@ -15,10 +15,6 @@
// Must be last.
#include "upb/port/def.inc"
#ifdef __cplusplus
extern "C" {
#endif
// When a upb_Message* is stored in a message, array, or map, it is stored in a
// tagged form. If the tag bit is set, the referenced upb_Message is of type
// _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of
@ -27,8 +23,13 @@ extern "C" {
//
// See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for
// more information.
typedef uintptr_t upb_TaggedMessagePtr;
#ifdef __cplusplus
extern "C" {
#endif
// Internal-only because empty messages cannot be created by the user.
UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr,
bool empty) {
@ -66,4 +67,4 @@ UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage(
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_TYPES_H_ */
#endif /* UPB_MINI_TABLE_TAGGED_PTR_H_ */

@ -394,7 +394,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
upb_MdDecoder_CheckOutOfMemory(&d->base, subs);
uint32_t i = 0;
for (; i < sub_counts.submsg_count; i++) {
subs[i].submsg = &_kUpb_MiniTable_Empty;
subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty;
}
if (sub_counts.subenum_count) {
upb_MiniTableField* f = d->fields;
@ -405,7 +405,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
}
}
for (; i < sub_counts.submsg_count + sub_counts.subenum_count; i++) {
subs[i].subenum = NULL;
subs[i].UPB_PRIVATE(subenum) = NULL;
}
}
d->table->subs = subs;

@ -76,8 +76,7 @@ UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build(
UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build(
const char* data, size_t len, const upb_MiniTable* extendee,
upb_Arena* arena, upb_Status* status) {
upb_MiniTableSub sub;
sub.submsg = NULL;
upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL);
return _upb_MiniTableExtension_Build(
data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status);
}
@ -85,8 +84,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build(
UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage(
const char* data, size_t len, const upb_MiniTable* extendee,
upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) {
upb_MiniTableSub sub;
sub.submsg = submsg;
upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg);
return _upb_MiniTableExtension_Build(
data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status);
}
@ -94,8 +92,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage(
UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum(
const char* data, size_t len, const upb_MiniTable* extendee,
upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) {
upb_MiniTableSub sub;
sub.subenum = subenum;
upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum);
return _upb_MiniTableExtension_Build(
data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status);
}

@ -28,6 +28,7 @@
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
// begin:google_only
// #include "testing/fuzzing/fuzztest.h"
@ -240,8 +241,8 @@ TEST_P(MiniTableTest, SubsInitializedToEmpty) {
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(table->field_count, 2);
EXPECT_EQ(table->subs[0].submsg, &_kUpb_MiniTable_Empty);
EXPECT_EQ(table->subs[1].submsg, &_kUpb_MiniTable_Empty);
EXPECT_EQ(upb_MiniTableSub_Message(table->subs[0]), &_kUpb_MiniTable_Empty);
EXPECT_EQ(upb_MiniTableSub_Message(table->subs[1]), &_kUpb_MiniTable_Empty);
}
TEST(MiniTableEnumTest, PositiveAndNegative) {

@ -7,6 +7,17 @@
#include "upb/mini_descriptor/link.h"
#include <stddef.h>
#include <stdint.h>
#include "upb/base/descriptor_constants.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h"
// Must be last.
#include "upb/port/def.inc"
@ -43,7 +54,7 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
// TODO: Add this assert back once YouTube is updated to not call
// this function repeatedly.
// UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty);
table_sub->submsg = sub;
*table_sub = upb_MiniTableSub_FromMessage(sub);
return true;
}
@ -56,7 +67,7 @@ bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
upb_MiniTableSub* table_sub =
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
table_sub->subenum = sub;
*table_sub = upb_MiniTableSub_FromEnum(sub);
return true;
}

@ -41,12 +41,12 @@ UPB_INLINE uint32_t UPB_PRIVATE(_upb_MiniTableExtension_Number)(
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(
_upb_MiniTableExtension_GetSubMessage)(
const struct upb_MiniTableExtension* e) {
return e->UPB_PRIVATE(sub).submsg;
return e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
}
UPB_INLINE void UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)(
struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) {
e->UPB_PRIVATE(sub).submsg = m;
e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m;
}
#ifdef __cplusplus

@ -12,10 +12,42 @@
#include "upb/port/def.inc"
union upb_MiniTableSub {
const struct upb_MiniTable* submsg;
const struct upb_MiniTableEnum* subenum;
const struct upb_MiniTable* UPB_PRIVATE(submsg);
const struct upb_MiniTableEnum* UPB_PRIVATE(subenum);
};
#ifdef __cplusplus
extern "C" {
#endif
UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(
const struct upb_MiniTableEnum* subenum) {
union upb_MiniTableSub out;
out.UPB_PRIVATE(subenum) = subenum;
return out;
}
UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(
const struct upb_MiniTable* submsg) {
union upb_MiniTableSub out;
out.UPB_PRIVATE(submsg) = submsg;
return out;
}
UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableSub_Enum)(
const union upb_MiniTableSub sub) {
return sub.UPB_PRIVATE(subenum);
}
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)(
const union upb_MiniTableSub sub) {
return sub.UPB_PRIVATE(submsg);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */

@ -11,7 +11,7 @@
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/sub.h"
// Must be last.
#include "upb/port/def.inc"
@ -35,8 +35,8 @@ UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(
UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message);
const upb_MiniTable* ret =
mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* ret = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSUME(ret);
return ret == &_kUpb_MiniTable_Empty ? NULL : ret;
}
@ -44,9 +44,9 @@ UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
// Returns the MiniTableEnum for this enum field. If the field is unlinked,
// returns NULL.
UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum);
return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum;
const upb_MiniTable* mini_table, const upb_MiniTableField* f) {
UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum);
return upb_MiniTableSub_Enum(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
}
// Returns true if this MiniTable field is linked to a MiniTable for the

@ -10,6 +10,43 @@
#include "upb/mini_table/internal/sub.h"
// Must be last.
#include "upb/port/def.inc"
typedef union upb_MiniTableSub upb_MiniTableSub;
#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */
#ifdef __cplusplus
extern "C" {
#endif
// Constructors
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) {
return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum);
}
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) {
return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg);
}
// Getters
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_SUB_H_ */

@ -22,6 +22,7 @@
#include "upb/mini_descriptor/decode.h"
#include "upb/mini_descriptor/internal/encode.h"
#include "upb/mini_descriptor/internal/modifiers.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/extension.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/message.h"
@ -934,9 +935,11 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx,
upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext;
upb_MiniTableSub sub = {NULL};
if (upb_FieldDef_IsSubMessage(f)) {
sub.submsg = upb_MessageDef_MiniTable(f->sub.msgdef);
const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef);
sub = upb_MiniTableSub_FromMessage(submsg);
} else if (_upb_FieldDef_IsClosedEnum(f)) {
sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef);
const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef);
sub = upb_MiniTableSub_FromEnum(subenum);
}
bool ok2 = upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext,
upb_MessageDef_MiniTable(f->msgdef),

@ -101,12 +101,12 @@ bool Builder::LinkExtension(upb_MiniTableExtension* ext) {
if (upb_MiniTableField_CType(field) == kUpb_CType_Message) {
auto mt = NextMiniTable();
if (!mt) field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32;
ext->UPB_PRIVATE(sub).submsg = mt;
ext->UPB_PRIVATE(sub) = upb_MiniTableSub_FromMessage(mt);
}
if (upb_MiniTableField_IsClosedEnum(field)) {
auto et = NextEnumTable();
if (!et) field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32;
ext->UPB_PRIVATE(sub).subenum = et;
ext->UPB_PRIVATE(sub) = upb_MiniTableSub_FromEnum(et);
}
return true;
}

@ -87,6 +87,25 @@ typedef union {
uint32_t size;
} wireval;
// Ideally these two functions should take the owning MiniTable pointer as a
// first argument, then we could just put them in mini_table/message.h as nice
// clean getters. But we don't have that so instead we gotta write these
// Frankenfunctions that take an array of subtables.
// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
static const upb_MiniTable* _upb_MiniTableSubs_MessageByField(
const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
return upb_MiniTableSub_Message(subs[field->UPB_PRIVATE(submsg_index)]);
}
// Returns the MiniTableEnum corresponding to a given MiniTableField
// from an array of MiniTableSub.
static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField(
const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
return upb_MiniTableSub_Enum(subs[field->UPB_PRIVATE(submsg_index)]);
}
static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable* layout);
@ -223,7 +242,7 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
upb_TaggedMessagePtr* target) {
const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
upb_Message* msg = _upb_Message_New(subl, &d->arena);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
@ -247,7 +266,7 @@ static upb_Message* _upb_Decoder_ReuseSubMessage(
upb_Decoder* d, const upb_MiniTableSub* subs,
const upb_MiniTableField* field, upb_TaggedMessagePtr* target) {
upb_TaggedMessagePtr tagged = *target;
const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) {
return _upb_TaggedMessagePtr_GetMessage(tagged);
@ -298,7 +317,7 @@ static const char* _upb_Decoder_DecodeSubMessage(
upb_Decoder* d, const char* ptr, upb_Message* submsg,
const upb_MiniTableSub* subs, const upb_MiniTableField* field, int size) {
int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size);
const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP);
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta);
@ -329,7 +348,7 @@ UPB_FORCEINLINE
static const char* _upb_Decoder_DecodeKnownGroup(
upb_Decoder* d, const char* ptr, upb_Message* submsg,
const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, field->number);
}
@ -382,7 +401,7 @@ static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr,
const upb_MiniTableSub* subs,
const upb_MiniTableField* field,
wireval* val) {
const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum;
const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field);
if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr;
void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
arr->size++;
@ -453,7 +472,7 @@ static const char* _upb_Decoder_DecodeEnumPacked(
upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
const upb_MiniTableSub* subs, const upb_MiniTableField* field,
wireval* val) {
const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum;
const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field);
int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size);
char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
while (!_upb_Decoder_IsDone(d, &ptr)) {
@ -593,7 +612,7 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
upb_Map* map = *map_p;
upb_MapEntry ent;
UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message);
const upb_MiniTable* entry = subs[field->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(entry);
UPB_ASSERT(entry->field_count == 2);
@ -653,7 +672,7 @@ static const char* _upb_Decoder_DecodeToSubMessage(
if (UPB_UNLIKELY(op == kUpb_DecodeOp_Enum) &&
!_upb_Decoder_CheckEnum(d, ptr, msg,
subs[field->UPB_PRIVATE(submsg_index)].subenum,
_upb_MiniTableSubs_EnumByField(subs, field),
field, val)) {
return ptr;
}
@ -971,9 +990,10 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
int* op) {
// If sub-message is not linked, treat as unknown.
if (field->mode & kUpb_LabelFlags_IsExtension) return;
const upb_MiniTableSub* sub = &mt->subs[field->UPB_PRIVATE(submsg_index)];
const upb_MiniTable* mt_sub =
_upb_MiniTableSubs_MessageByField(mt->subs, field);
if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) ||
sub->submsg != &_kUpb_MiniTable_Empty) {
mt_sub != &_kUpb_MiniTable_Empty) {
return;
}
#ifndef NDEBUG

@ -20,6 +20,7 @@
#include "upb/message/array.h"
#include "upb/message/internal/array.h"
#include "upb/message/internal/types.h"
#include "upb/mini_table/sub.h"
#include "upb/wire/internal/decode.h"
// Must be last.
@ -914,7 +915,8 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e,
upb_Message** dst; \
uint32_t submsg_idx = (data >> 16) & 0xff; \
const upb_MiniTable* tablep = decode_totablep(table); \
const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \
const upb_MiniTable* subtablep = \
upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \
fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
fastdecode_arr farr; \
\

@ -271,7 +271,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem,
case kUpb_FieldType_Group: {
size_t size;
upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem;
const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subm =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
if (submsg == 0) {
return;
}
@ -285,7 +286,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem,
case kUpb_FieldType_Message: {
size_t size;
upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem;
const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subm =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
if (submsg == 0) {
return;
}
@ -374,7 +376,8 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
case kUpb_FieldType_Group: {
const upb_TaggedMessagePtr* start = _upb_array_constptr(arr);
const upb_TaggedMessagePtr* ptr = start + arr->size;
const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subm =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);
do {
size_t size;
@ -389,7 +392,8 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
case kUpb_FieldType_Message: {
const upb_TaggedMessagePtr* start = _upb_array_constptr(arr);
const upb_TaggedMessagePtr* ptr = start + arr->size;
const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* subm =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);
do {
size_t size;
@ -428,7 +432,8 @@ static void encode_map(upb_encstate* e, const upb_Message* msg,
const upb_MiniTableSub* subs,
const upb_MiniTableField* f) {
const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*);
const upb_MiniTable* layout = subs[f->UPB_PRIVATE(submsg_index)].submsg;
const upb_MiniTable* layout =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(layout->field_count == 2);
if (map == NULL) return;

@ -385,16 +385,18 @@ void WriteMessageField(upb::FieldDefPtr field,
std::string GetSub(upb::FieldDefPtr field) {
if (auto message_def = field.message_type()) {
return absl::Substitute("{.submsg = &$0}", MessageInitName(message_def));
return absl::Substitute("{.UPB_PRIVATE(submsg) = &$0}",
MessageInitName(message_def));
}
if (auto enum_def = field.enum_subdef()) {
if (enum_def.is_closed()) {
return absl::Substitute("{.subenum = &$0}", EnumInit(enum_def));
return absl::Substitute("{.UPB_PRIVATE(subenum) = &$0}",
EnumInit(enum_def));
}
}
return std::string("{.submsg = NULL}");
return std::string("{.UPB_PRIVATE(submsg) = NULL}");
}
// Writes a single message into a .upb.c source file.

Loading…
Cancel
Save