From 68806c04a8ea3be017e8a2c84d1b475fa365cfa2 Mon Sep 17 00:00:00 2001 From: deannagarcia <69992229+deannagarcia@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:11:28 -0800 Subject: [PATCH] Update UPB dep (#11782) --- php/ext/google/protobuf/php-upb.c | 167 ++++++++++++++++---------- php/ext/google/protobuf/php-upb.h | 17 +-- protobuf_deps.bzl | 4 +- ruby/ext/google/protobuf_c/ruby-upb.c | 167 ++++++++++++++++---------- ruby/ext/google/protobuf_c/ruby-upb.h | 17 +-- 5 files changed, 230 insertions(+), 142 deletions(-) diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index a56c76441e..707bad7cfa 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -7109,26 +7109,33 @@ 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 && (uintptr_t)field < (uintptr_t)(table->fields + table->field_count)); + // TODO: check these type invariants at runtime and return error to the + // caller if they are violated, instead of using an assert. + UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group); if (sub->ext & kUpb_ExtMode_IsMapEntry) { + UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message); field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; } 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; } #include @@ -8024,6 +8031,31 @@ static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { } } +static const upb_FileDef* upb_DefBuilder_AddFileToPool( + upb_DefBuilder* const builder, upb_DefPool* const s, + const UPB_DESC(FileDescriptorProto) * const file_proto, + const upb_StringView name, upb_Status* const status) { + if (UPB_SETJMP(builder->err) != 0) { + UPB_ASSERT(!upb_Status_IsOk(status)); + if (builder->file) { + remove_filedef(s, builder->file); + builder->file = NULL; + } + } else if (!builder->arena || !builder->tmp_arena) { + _upb_DefBuilder_OomErr(builder); + } else { + _upb_FileDef_Create(builder, file_proto); + upb_strtable_insert(&s->files, name.data, name.size, + upb_value_constptr(builder->file), builder->arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, builder->arena); + } + + if (builder->arena) upb_Arena_Free(builder->arena); + if (builder->tmp_arena) upb_Arena_Free(builder->tmp_arena); + return builder->file; +} + static const upb_FileDef* _upb_DefPool_AddFile( upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto, const upb_MiniTableFile* layout, upb_Status* status) { @@ -8059,25 +8091,7 @@ static const upb_FileDef* _upb_DefPool_AddFile( .tmp_arena = upb_Arena_New(), }; - if (UPB_SETJMP(ctx.err)) { - UPB_ASSERT(!upb_Status_IsOk(status)); - if (ctx.file) { - remove_filedef(s, ctx.file); - ctx.file = NULL; - } - } else if (!ctx.arena || !ctx.tmp_arena) { - _upb_DefBuilder_OomErr(&ctx); - } else { - _upb_FileDef_Create(&ctx, file_proto); - upb_strtable_insert(&s->files, name.data, name.size, - upb_value_constptr(ctx.file), ctx.arena); - UPB_ASSERT(upb_Status_IsOk(status)); - upb_Arena_Fuse(s->arena, ctx.arena); - } - - if (ctx.arena) upb_Arena_Free(ctx.arena); - if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena); - return ctx.file; + return upb_DefBuilder_AddFileToPool(&ctx, s, file_proto, name, status); } const upb_FileDef* upb_DefPool_AddFile(upb_DefPool* s, @@ -10570,13 +10584,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); + } } } @@ -12121,6 +12140,16 @@ int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { return kVarintOps[field->descriptortype]; } +UPB_FORCEINLINE +static void _upb_Decoder_CheckUnlinked(const upb_MiniTable* mt, + const upb_MiniTableField* field, + 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->submsg_index]; + if (!sub->submsg) *op = kUpb_DecodeOp_UnknownField; +} + int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt, const upb_MiniTableField* field) { enum { kRepeatedBase = 19 }; @@ -12175,13 +12204,8 @@ int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt, if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += kRepeatedBase; int op = kDelimitedOps[ndx]; - // If sub-message is not linked, treat as unknown. - if (op == kUpb_DecodeOp_SubMessage && - !(field->mode & kUpb_LabelFlags_IsExtension)) { - const upb_MiniTableSub* sub = &mt->subs[field->submsg_index]; - if (!sub->submsg) { - op = kUpb_DecodeOp_UnknownField; - } + if (op == kUpb_DecodeOp_SubMessage) { + _upb_Decoder_CheckUnlinked(mt, field, &op); } return op; @@ -12227,6 +12251,7 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, val->uint32_val = field->number; if (field->descriptortype == kUpb_FieldType_Group) { *op = kUpb_DecodeOp_SubMessage; + _upb_Decoder_CheckUnlinked(mt, field, op); } else if (field->descriptortype == kUpb_FakeFieldType_MessageSetItem) { *op = kUpb_DecodeOp_MessageSetItem; } else { @@ -12430,6 +12455,23 @@ const char* _upb_Decoder_IsDoneFallback(upb_EpsCopyInputStream* e, e, ptr, overrun, _upb_Decoder_BufferFlipCallback); } +static upb_DecodeStatus upb_Decoder_Decode(upb_Decoder* const decoder, + const char* const buf, + void* const msg, + const upb_MiniTable* const l, + upb_Arena* const arena) { + if (UPB_SETJMP(decoder->err) == 0) { + decoder->status = _upb_Decoder_DecodeTop(decoder, buf, msg, l); + } else { + UPB_ASSERT(decoder->status != kUpb_DecodeStatus_Ok); + } + + arena->head.ptr = decoder->arena.head.ptr; + arena->head.end = decoder->arena.head.end; + arena->cleanup_metadata = decoder->arena.cleanup_metadata; + return decoder->status; +} + upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, const upb_MiniTable* l, const upb_ExtensionRegistry* extreg, int options, @@ -12452,16 +12494,7 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, state.arena.parent = arena; state.status = kUpb_DecodeStatus_Ok; - if (UPB_SETJMP(state.err) == 0) { - state.status = _upb_Decoder_DecodeTop(&state, buf, msg, l); - } else { - UPB_ASSERT(state.status != kUpb_DecodeStatus_Ok); - } - - arena->head.ptr = state.arena.head.ptr; - arena->head.end = state.arena.head.end; - arena->cleanup_metadata = state.arena.cleanup_metadata; - return state.status; + return upb_Decoder_Decode(&state, buf, msg, l, arena); } #undef OP_FIXPCK_LG2 @@ -13985,6 +14018,35 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, *size = (e->limit - e->ptr) - pre_len; } +static upb_EncodeStatus upb_Encoder_Encode(upb_encstate* const encoder, + const void* const msg, + const upb_MiniTable* const l, + char** const buf, + size_t* const size) { + // Unfortunately we must continue to perform hackery here because there are + // code paths which blindly copy the returned pointer without bothering to + // check for errors until much later (b/235839510). So we still set *buf to + // NULL on error and we still set it to non-NULL on a successful empty result. + if (UPB_SETJMP(encoder->err) == 0) { + encode_message(encoder, msg, l, size); + *size = encoder->limit - encoder->ptr; + if (*size == 0) { + static char ch; + *buf = &ch; + } else { + UPB_ASSERT(encoder->ptr); + *buf = encoder->ptr; + } + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + *buf = NULL; + *size = 0; + } + + _upb_mapsorter_destroy(&encoder->sorter); + return encoder->status; +} + upb_EncodeStatus upb_Encode(const void* msg, const upb_MiniTable* l, int options, upb_Arena* arena, char** buf, size_t* size) { @@ -14000,28 +14062,7 @@ upb_EncodeStatus upb_Encode(const void* msg, const upb_MiniTable* l, e.options = options; _upb_mapsorter_init(&e.sorter); - // Unfortunately we must continue to perform hackery here because there are - // code paths which blindly copy the returned pointer without bothering to - // check for errors until much later (b/235839510). So we still set *buf to - // NULL on error and we still set it to non-NULL on a successful empty result. - if (UPB_SETJMP(e.err) == 0) { - encode_message(&e, msg, l, size); - *size = e.limit - e.ptr; - if (*size == 0) { - static char ch; - *buf = &ch; - } else { - UPB_ASSERT(e.ptr); - *buf = e.ptr; - } - } else { - UPB_ASSERT(e.status != kUpb_EncodeStatus_Ok); - *buf = NULL; - *size = 0; - } - - _upb_mapsorter_destroy(&e.sorter); - return e.status; + return upb_Encoder_Encode(&e, msg, l, buf, size); } diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 99081fae1a..4801fa9c18 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -8622,19 +8622,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); @@ -9179,6 +9181,7 @@ UPB_INLINE int upb_EpsCopyInputStream_PushLimit(upb_EpsCopyInputStream* e, int limit = size + (int)(ptr - e->end); int delta = e->limit - limit; _upb_EpsCopyInputStream_CheckLimit(e); + UPB_ASSERT(limit <= e->limit); e->limit = limit; e->limit_ptr = e->end + UPB_MIN(0, limit); _upb_EpsCopyInputStream_CheckLimit(e); diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index 90e1412cd9..6f853c8416 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -150,7 +150,7 @@ def protobuf_deps(): _github_archive( name = "upb", repo = "https://github.com/protocolbuffers/upb", - commit = "1881a390b0425f8e255df9ca95a8b5d8104c66a0", - sha256 = "d3ffcaa629893fb74a1459ef28c69f84bb2d6f51feed654941b32ead412a99a1", + commit = "4bea50c834fd714238c700bedecfd4b75bc833f3", + sha256 = "5664903676dd9b784250e0a6502f712057100e362d4bbdbc0ba3ab1f3cdb7daf", patches = ["@com_google_protobuf//build_defs:upb.patch"], ) diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index b6ce09a1b6..f9c29dc002 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -6746,26 +6746,33 @@ 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 && (uintptr_t)field < (uintptr_t)(table->fields + table->field_count)); + // TODO: check these type invariants at runtime and return error to the + // caller if they are violated, instead of using an assert. + UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message || + field->descriptortype == kUpb_FieldType_Group); if (sub->ext & kUpb_ExtMode_IsMapEntry) { + UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message); field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; } 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; } #include @@ -7661,6 +7668,31 @@ static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { } } +static const upb_FileDef* upb_DefBuilder_AddFileToPool( + upb_DefBuilder* const builder, upb_DefPool* const s, + const UPB_DESC(FileDescriptorProto) * const file_proto, + const upb_StringView name, upb_Status* const status) { + if (UPB_SETJMP(builder->err) != 0) { + UPB_ASSERT(!upb_Status_IsOk(status)); + if (builder->file) { + remove_filedef(s, builder->file); + builder->file = NULL; + } + } else if (!builder->arena || !builder->tmp_arena) { + _upb_DefBuilder_OomErr(builder); + } else { + _upb_FileDef_Create(builder, file_proto); + upb_strtable_insert(&s->files, name.data, name.size, + upb_value_constptr(builder->file), builder->arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, builder->arena); + } + + if (builder->arena) upb_Arena_Free(builder->arena); + if (builder->tmp_arena) upb_Arena_Free(builder->tmp_arena); + return builder->file; +} + static const upb_FileDef* _upb_DefPool_AddFile( upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto, const upb_MiniTableFile* layout, upb_Status* status) { @@ -7696,25 +7728,7 @@ static const upb_FileDef* _upb_DefPool_AddFile( .tmp_arena = upb_Arena_New(), }; - if (UPB_SETJMP(ctx.err)) { - UPB_ASSERT(!upb_Status_IsOk(status)); - if (ctx.file) { - remove_filedef(s, ctx.file); - ctx.file = NULL; - } - } else if (!ctx.arena || !ctx.tmp_arena) { - _upb_DefBuilder_OomErr(&ctx); - } else { - _upb_FileDef_Create(&ctx, file_proto); - upb_strtable_insert(&s->files, name.data, name.size, - upb_value_constptr(ctx.file), ctx.arena); - UPB_ASSERT(upb_Status_IsOk(status)); - upb_Arena_Fuse(s->arena, ctx.arena); - } - - if (ctx.arena) upb_Arena_Free(ctx.arena); - if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena); - return ctx.file; + return upb_DefBuilder_AddFileToPool(&ctx, s, file_proto, name, status); } const upb_FileDef* upb_DefPool_AddFile(upb_DefPool* s, @@ -10207,13 +10221,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); + } } } @@ -11758,6 +11777,16 @@ int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { return kVarintOps[field->descriptortype]; } +UPB_FORCEINLINE +static void _upb_Decoder_CheckUnlinked(const upb_MiniTable* mt, + const upb_MiniTableField* field, + 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->submsg_index]; + if (!sub->submsg) *op = kUpb_DecodeOp_UnknownField; +} + int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt, const upb_MiniTableField* field) { enum { kRepeatedBase = 19 }; @@ -11812,13 +11841,8 @@ int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt, if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += kRepeatedBase; int op = kDelimitedOps[ndx]; - // If sub-message is not linked, treat as unknown. - if (op == kUpb_DecodeOp_SubMessage && - !(field->mode & kUpb_LabelFlags_IsExtension)) { - const upb_MiniTableSub* sub = &mt->subs[field->submsg_index]; - if (!sub->submsg) { - op = kUpb_DecodeOp_UnknownField; - } + if (op == kUpb_DecodeOp_SubMessage) { + _upb_Decoder_CheckUnlinked(mt, field, &op); } return op; @@ -11864,6 +11888,7 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, val->uint32_val = field->number; if (field->descriptortype == kUpb_FieldType_Group) { *op = kUpb_DecodeOp_SubMessage; + _upb_Decoder_CheckUnlinked(mt, field, op); } else if (field->descriptortype == kUpb_FakeFieldType_MessageSetItem) { *op = kUpb_DecodeOp_MessageSetItem; } else { @@ -12067,6 +12092,23 @@ const char* _upb_Decoder_IsDoneFallback(upb_EpsCopyInputStream* e, e, ptr, overrun, _upb_Decoder_BufferFlipCallback); } +static upb_DecodeStatus upb_Decoder_Decode(upb_Decoder* const decoder, + const char* const buf, + void* const msg, + const upb_MiniTable* const l, + upb_Arena* const arena) { + if (UPB_SETJMP(decoder->err) == 0) { + decoder->status = _upb_Decoder_DecodeTop(decoder, buf, msg, l); + } else { + UPB_ASSERT(decoder->status != kUpb_DecodeStatus_Ok); + } + + arena->head.ptr = decoder->arena.head.ptr; + arena->head.end = decoder->arena.head.end; + arena->cleanup_metadata = decoder->arena.cleanup_metadata; + return decoder->status; +} + upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, const upb_MiniTable* l, const upb_ExtensionRegistry* extreg, int options, @@ -12089,16 +12131,7 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, state.arena.parent = arena; state.status = kUpb_DecodeStatus_Ok; - if (UPB_SETJMP(state.err) == 0) { - state.status = _upb_Decoder_DecodeTop(&state, buf, msg, l); - } else { - UPB_ASSERT(state.status != kUpb_DecodeStatus_Ok); - } - - arena->head.ptr = state.arena.head.ptr; - arena->head.end = state.arena.head.end; - arena->cleanup_metadata = state.arena.cleanup_metadata; - return state.status; + return upb_Decoder_Decode(&state, buf, msg, l, arena); } #undef OP_FIXPCK_LG2 @@ -13622,6 +13655,35 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, *size = (e->limit - e->ptr) - pre_len; } +static upb_EncodeStatus upb_Encoder_Encode(upb_encstate* const encoder, + const void* const msg, + const upb_MiniTable* const l, + char** const buf, + size_t* const size) { + // Unfortunately we must continue to perform hackery here because there are + // code paths which blindly copy the returned pointer without bothering to + // check for errors until much later (b/235839510). So we still set *buf to + // NULL on error and we still set it to non-NULL on a successful empty result. + if (UPB_SETJMP(encoder->err) == 0) { + encode_message(encoder, msg, l, size); + *size = encoder->limit - encoder->ptr; + if (*size == 0) { + static char ch; + *buf = &ch; + } else { + UPB_ASSERT(encoder->ptr); + *buf = encoder->ptr; + } + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + *buf = NULL; + *size = 0; + } + + _upb_mapsorter_destroy(&encoder->sorter); + return encoder->status; +} + upb_EncodeStatus upb_Encode(const void* msg, const upb_MiniTable* l, int options, upb_Arena* arena, char** buf, size_t* size) { @@ -13637,28 +13699,7 @@ upb_EncodeStatus upb_Encode(const void* msg, const upb_MiniTable* l, e.options = options; _upb_mapsorter_init(&e.sorter); - // Unfortunately we must continue to perform hackery here because there are - // code paths which blindly copy the returned pointer without bothering to - // check for errors until much later (b/235839510). So we still set *buf to - // NULL on error and we still set it to non-NULL on a successful empty result. - if (UPB_SETJMP(e.err) == 0) { - encode_message(&e, msg, l, size); - *size = e.limit - e.ptr; - if (*size == 0) { - static char ch; - *buf = &ch; - } else { - UPB_ASSERT(e.ptr); - *buf = e.ptr; - } - } else { - UPB_ASSERT(e.status != kUpb_EncodeStatus_Ok); - *buf = NULL; - *size = 0; - } - - _upb_mapsorter_destroy(&e.sorter); - return e.status; + return upb_Encoder_Encode(&e, msg, l, buf, size); } diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index bd1ce0bf33..d70baffe01 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -8262,6 +8262,7 @@ UPB_INLINE int upb_EpsCopyInputStream_PushLimit(upb_EpsCopyInputStream* e, int limit = size + (int)(ptr - e->end); int delta = e->limit - limit; _upb_EpsCopyInputStream_CheckLimit(e); + UPB_ASSERT(limit <= e->limit); e->limit = limit; e->limit_ptr = e->end + UPB_MIN(0, limit); _upb_EpsCopyInputStream_CheckLimit(e); @@ -9734,19 +9735,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);