diff --git a/upb/message/copy.c b/upb/message/copy.c index a8c331567d..570e6c1c72 100644 --- a/upb/message/copy.c +++ b/upb/message/copy.c @@ -146,6 +146,9 @@ upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, if (!cloned_array) { return NULL; } + if (!_upb_Array_ResizeUninitialized(cloned_array, size, arena)) { + return NULL; + } for (int i = 0; i < size; ++i) { upb_MessageValue val = upb_Array_Get(array, i); if (!upb_Clone_MessageValue(&val, value_type, sub, arena)) { diff --git a/upb/message/copy_test.cc b/upb/message/copy_test.cc index 304cfa4609..befcf10067 100644 --- a/upb/message/copy_test.cc +++ b/upb/message/copy_test.cc @@ -33,6 +33,9 @@ #include "upb/message/copy.h" +#include +#include + #include "gtest/gtest.h" #include "google/protobuf/test_messages_proto2.upb.h" #include "google/protobuf/test_messages_proto3.upb.h" @@ -136,6 +139,35 @@ TEST(GeneratedCode, DeepCloneMessageSubMessage) { upb_Arena_Free(arena); } +TEST(GeneratedCode, DeepCloneMessageArrayField) { + upb_Arena* source_arena = upb_Arena_New(); + protobuf_test_messages_proto2_TestAllTypesProto2* msg = + protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena); + std::vector array_test_values = {3, 4, 5}; + for (int32_t value : array_test_values) { + ASSERT_TRUE( + protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32( + msg, value, source_arena)); + } + upb_Arena* arena = upb_Arena_New(); + protobuf_test_messages_proto2_TestAllTypesProto2* clone = + (protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_DeepClone( + msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init, + arena); + protobuf_test_messages_proto2_TestAllTypesProto2_clear_repeated_sint32(msg); + upb_Arena_Free(source_arena); + size_t cloned_size = 0; + const int32_t* cloned_values = + protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32( + clone, &cloned_size); + EXPECT_EQ(cloned_size, array_test_values.size()); + int index = 0; + for (int32_t value : array_test_values) { + EXPECT_EQ(cloned_values[index++], value); + } + upb_Arena_Free(arena); +} + TEST(GeneratedCode, DeepCloneMessageMapField) { upb_Arena* source_arena = upb_Arena_New(); protobuf_test_messages_proto2_TestAllTypesProto2* msg =