diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index e29858f994..1c0a0b1580 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -3962,11 +3962,18 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { return false; } - upb_StringView* view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); - if (!view) return false; - char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); - memcpy(copy, data, len); - view->data = copy; + upb_StringView* view; + if (alias) { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!view) return false; + view->data = data; + } else { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + memcpy(copy, data, len); + view->data = copy; + } view->size = len; upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view); diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index dc006b7119..93a219363e 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -3125,7 +3125,8 @@ void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); // Adds unknown data (serialized protobuf data) to the given message. The data // must represent one or more complete and well formed proto fields. -// The data is copied into the message instance. +// If alias is set, will keep a view to the provided data; otherwise a copy is +// made. bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, const char* data, size_t len, upb_Arena* arena, bool alias); @@ -5439,8 +5440,8 @@ extern "C" { #endif enum { - /* If set, strings will alias the input buffer instead of copying into the - * arena. */ + /* If set, strings and unknown fields will alias the input buffer instead of + * copying into the arena. */ kUpb_DecodeOption_AliasString = 1, /* If set, the parse will return failure if any message is missing any diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 90d4dbfde1..db45c7e0a7 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -3962,11 +3962,18 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { return false; } - upb_StringView* view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); - if (!view) return false; - char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); - memcpy(copy, data, len); - view->data = copy; + upb_StringView* view; + if (alias) { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!view) return false; + view->data = data; + } else { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + memcpy(copy, data, len); + view->data = copy; + } view->size = len; upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view); diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 8feb07cb3d..2d2b361c79 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -3127,7 +3127,8 @@ void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); // Adds unknown data (serialized protobuf data) to the given message. The data // must represent one or more complete and well formed proto fields. -// The data is copied into the message instance. +// If alias is set, will keep a view to the provided data; otherwise a copy is +// made. bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, const char* data, size_t len, upb_Arena* arena, bool alias); @@ -5441,8 +5442,8 @@ extern "C" { #endif enum { - /* If set, strings will alias the input buffer instead of copying into the - * arena. */ + /* If set, strings and unknown fields will alias the input buffer instead of + * copying into the arena. */ kUpb_DecodeOption_AliasString = 1, /* If set, the parse will return failure if any message is missing any