diff --git a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs deleted file mode 100644 index 208ce1fcb6..0000000000 --- a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs +++ /dev/null @@ -1,17 +0,0 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd -#endregion - -namespace Google.Protobuf.Reflection; - -internal sealed partial class FeatureSetDescriptor -{ - // Canonical serialized form of the edition defaults, generated by embed_edition_defaults. - private const string DefaultsBase64 = - "ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH"; -} diff --git a/upb/message/internal/message.h b/upb/message/internal/message.h index b371bbe0c8..8f1b09bc47 100644 --- a/upb/message/internal/message.h +++ b/upb/message/internal/message.h @@ -83,12 +83,21 @@ UPB_INLINE struct upb_Message* _upb_Message_New(const upb_MiniTable* m, // Discards the unknown fields for this message only. void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); -// Adds unknown data (serialized protobuf data) to the given message. +// 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. bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, const char* data, size_t len, upb_Arena* arena); +// Adds unknown data (serialized protobuf data) to the given message. +// The data is copied into the message instance. Data when concatenated together +// must represent one or more complete and well formed proto fields, but the +// individual spans may point only to partial fields. +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], size_t count); + bool UPB_PRIVATE(_upb_Message_Realloc)(struct upb_Message* msg, size_t need, upb_Arena* arena); diff --git a/upb/message/message.c b/upb/message/message.c index 41485c57b3..b4ce505f5d 100644 --- a/upb/message/message.c +++ b/upb/message/message.c @@ -7,6 +7,7 @@ #include "upb/message/message.h" +#include #include #include #include @@ -38,6 +39,8 @@ upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* a) { bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, size_t len, upb_Arena* arena) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, len, arena)) return false; upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); memcpy(UPB_PTR_AT(in, in->unknown_end, char), data, len); @@ -45,6 +48,28 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, return true; } +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], + size_t count) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(count > 0); + size_t total_len = 0; + for (size_t i = 0; i < count; i++) { + total_len += data[i].size; + } + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, total_len, arena)) return false; + + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + for (size_t i = 0; i < count; i++) { + memcpy(UPB_PTR_AT(in, in->unknown_end, char), data[i].data, data[i].size); + in->unknown_end += data[i].size; + } + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field + return true; +} + void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); diff --git a/upb/wire/decode.c b/upb/wire/decode.c index 2cb1a44913..a3e3612d2e 100644 --- a/upb/wire/decode.c +++ b/upb/wire/decode.c @@ -376,18 +376,6 @@ static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) { return ptr; } -static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, - uint32_t val1, uint32_t val2) { - char buf[20]; - char* end = buf; - end = upb_Decoder_EncodeVarint32(val1, end); - end = upb_Decoder_EncodeVarint32(val2, end); - - if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, &d->arena)) { - _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - } -} - UPB_FORCEINLINE bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTableEnum* e, @@ -404,7 +392,15 @@ bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Message* unknown_msg = field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; - _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); + char buf[20]; + char* end = buf; + end = upb_Decoder_EncodeVarint32(tag, end); + end = upb_Decoder_EncodeVarint32(v, end); + + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(unknown_msg, buf, end - buf, + &d->arena)) { + _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); + } return false; } @@ -675,8 +671,16 @@ static const char* _upb_Decoder_DecodeToMap( if (status != kUpb_EncodeStatus_Ok) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } - _upb_Decoder_AddUnknownVarints(d, msg, tag, size); - if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, size, &d->arena)) { + char delim_buf[20]; + char* delim_end = delim_buf; + delim_end = upb_Decoder_EncodeVarint32(tag, delim_end); + delim_end = upb_Decoder_EncodeVarint32(size, delim_end); + upb_StringView unknown[] = { + {delim_buf, delim_end - delim_buf}, + {buf, size}, + }; + + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 2)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } else { @@ -846,12 +850,12 @@ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d, ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr); char* end = ptr; - - if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, split - buf, &d->arena) || - !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, message_data, message_size, - &d->arena) || - !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, split, end - split, - &d->arena)) { + upb_StringView unknown[] = { + {buf, split - buf}, + {message_data, message_size}, + {split, end - split}, + }; + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 3)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } }