diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 6f6952d32617..e59dd07b2358 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -6044,24 +6044,32 @@ upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { return r; } -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e) { +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { char buf[EXTREG_KEY_SIZE]; extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e)); - if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false; - return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, - upb_value_constptr(e), r->arena); + + if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) { + return kUpb_ExtensionRegistryStatus_DuplicateEntry; + } + + if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, + upb_value_constptr(e), r->arena)) { + return kUpb_ExtensionRegistryStatus_OutOfMemory; + } + return kUpb_ExtensionRegistryStatus_Ok; } -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count) { +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count) { const upb_MiniTableExtension** start = e; const upb_MiniTableExtension** end = UPB_PTRADD(e, count); + upb_ExtensionRegistryStatus status = kUpb_ExtensionRegistryStatus_Ok; for (; e < end; e++) { - if (!upb_ExtensionRegistry_Add(r, *e)) goto failure; + status = upb_ExtensionRegistry_Add(r, *e); + if (status != kUpb_ExtensionRegistryStatus_Ok) goto failure; } - return true; + return kUpb_ExtensionRegistryStatus_Ok; failure: // Back out the entries previously added. @@ -6072,7 +6080,8 @@ bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, upb_MiniTableExtension_Number(ext)); upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } - return false; + UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok); + return status; } #ifdef UPB_LINKARR_DECLARE @@ -6085,7 +6094,9 @@ bool upb_ExtensionRegistry_AddAllLinkedExtensions(upb_ExtensionRegistry* r) { for (const upb_MiniTableExtension* p = start; p < stop; p++) { // Windows can introduce zero padding, so we have to skip zeroes. if (upb_MiniTableExtension_Number(p) != 0) { - if (!upb_ExtensionRegistry_Add(r, p)) return false; + if (upb_ExtensionRegistry_Add(r, p) != kUpb_ExtensionRegistryStatus_Ok) { + return false; + } } } return true; @@ -15425,9 +15436,16 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, } if (file->ext_count) { - bool ok = upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistryStatus status = upb_ExtensionRegistry_AddArray( _upb_DefPool_ExtReg(ctx->symtab), file->ext_layouts, file->ext_count); - if (!ok) _upb_DefBuilder_OomErr(ctx); + if (status != kUpb_ExtensionRegistryStatus_Ok) { + if (status == kUpb_ExtensionRegistryStatus_OutOfMemory) { + _upb_DefBuilder_OomErr(ctx); + } + + UPB_ASSERT(status == kUpb_ExtensionRegistryStatus_DuplicateEntry); + _upb_DefBuilder_Errf(ctx, "duplicate extension entry"); + } } } diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 14038f45ef5e..956177aee53f 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -5144,6 +5144,9 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ #define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#include +#include + // Must be last. @@ -5187,21 +5190,25 @@ extern "C" { typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; +typedef enum { + kUpb_ExtensionRegistryStatus_Ok = 0, + kUpb_ExtensionRegistryStatus_DuplicateEntry = 1, + kUpb_ExtensionRegistryStatus_OutOfMemory = 2, +} upb_ExtensionRegistryStatus; + // Creates a upb_ExtensionRegistry in the given arena. // The arena must outlive any use of the extreg. UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e); +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e); // Adds the given extension info for the array |e| of size |count| into the // registry. If there are any errors, the entire array is backed out. // The extensions must outlive the registry. // Possible errors include OOM or an extension number that already exists. -// TODO: There is currently no way to know the exact reason for failure. -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count); +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count); #ifdef UPB_LINKARR_DECLARE diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index c9a50024dc1b..7c2ceb9621bb 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -6044,24 +6044,32 @@ upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { return r; } -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e) { +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { char buf[EXTREG_KEY_SIZE]; extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e)); - if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false; - return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, - upb_value_constptr(e), r->arena); + + if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) { + return kUpb_ExtensionRegistryStatus_DuplicateEntry; + } + + if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, + upb_value_constptr(e), r->arena)) { + return kUpb_ExtensionRegistryStatus_OutOfMemory; + } + return kUpb_ExtensionRegistryStatus_Ok; } -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count) { +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count) { const upb_MiniTableExtension** start = e; const upb_MiniTableExtension** end = UPB_PTRADD(e, count); + upb_ExtensionRegistryStatus status = kUpb_ExtensionRegistryStatus_Ok; for (; e < end; e++) { - if (!upb_ExtensionRegistry_Add(r, *e)) goto failure; + status = upb_ExtensionRegistry_Add(r, *e); + if (status != kUpb_ExtensionRegistryStatus_Ok) goto failure; } - return true; + return kUpb_ExtensionRegistryStatus_Ok; failure: // Back out the entries previously added. @@ -6072,7 +6080,8 @@ bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, upb_MiniTableExtension_Number(ext)); upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } - return false; + UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok); + return status; } #ifdef UPB_LINKARR_DECLARE @@ -6085,7 +6094,9 @@ bool upb_ExtensionRegistry_AddAllLinkedExtensions(upb_ExtensionRegistry* r) { for (const upb_MiniTableExtension* p = start; p < stop; p++) { // Windows can introduce zero padding, so we have to skip zeroes. if (upb_MiniTableExtension_Number(p) != 0) { - if (!upb_ExtensionRegistry_Add(r, p)) return false; + if (upb_ExtensionRegistry_Add(r, p) != kUpb_ExtensionRegistryStatus_Ok) { + return false; + } } } return true; @@ -14912,9 +14923,16 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, } if (file->ext_count) { - bool ok = upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistryStatus status = upb_ExtensionRegistry_AddArray( _upb_DefPool_ExtReg(ctx->symtab), file->ext_layouts, file->ext_count); - if (!ok) _upb_DefBuilder_OomErr(ctx); + if (status != kUpb_ExtensionRegistryStatus_Ok) { + if (status == kUpb_ExtensionRegistryStatus_OutOfMemory) { + _upb_DefBuilder_OomErr(ctx); + } + + UPB_ASSERT(status == kUpb_ExtensionRegistryStatus_DuplicateEntry); + _upb_DefBuilder_Errf(ctx, "duplicate extension entry"); + } } } diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 415fc6f63a9f..4854ecbe9221 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -5146,6 +5146,9 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ #define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#include +#include + // Must be last. @@ -5189,21 +5192,25 @@ extern "C" { typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; +typedef enum { + kUpb_ExtensionRegistryStatus_Ok = 0, + kUpb_ExtensionRegistryStatus_DuplicateEntry = 1, + kUpb_ExtensionRegistryStatus_OutOfMemory = 2, +} upb_ExtensionRegistryStatus; + // Creates a upb_ExtensionRegistry in the given arena. // The arena must outlive any use of the extreg. UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e); +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e); // Adds the given extension info for the array |e| of size |count| into the // registry. If there are any errors, the entire array is backed out. // The extensions must outlive the registry. // Possible errors include OOM or an extension number that already exists. -// TODO: There is currently no way to know the exact reason for failure. -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count); +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count); #ifdef UPB_LINKARR_DECLARE