From 94a26630e362a4771b5ec80eac49f494988ca408 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 23 Jan 2024 17:10:27 -0800 Subject: [PATCH] Fixed a SEGV when deep copying a non-reified sub-message. PiperOrigin-RevId: 600951523 --- python/google/protobuf/internal/reflection_test.py | 5 +++++ python/message.c | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 2230d0c94d4e..bc4e8a3fe275 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -789,6 +789,11 @@ def testDeepCopy(self, message_module): messages.remove(messages[0]) self.assertEqual(len(messages), 0) + def testEmptyDeepCopy(self, message_module): + proto1 = message_module.TestAllTypes() + nested2 = copy.deepcopy(proto1.optional_nested_message) + self.assertEqual(0, nested2.bb) + # TODO: Implement deepcopy for extension dict def testDisconnectingBeforeClear(self, message_module): diff --git a/python/message.c b/python/message.c index 0777e7ed5f3c..f56294ccc0b6 100644 --- a/python/message.c +++ b/python/message.c @@ -1610,10 +1610,13 @@ static PyObject* PyUpb_Message_WhichOneof(PyObject* _self, PyObject* name) { PyObject* DeepCopy(PyObject* _self, PyObject* arg) { PyUpb_Message* self = (void*)_self; const upb_MessageDef* def = PyUpb_Message_GetMsgdef(_self); - + const upb_MiniTable* mini_table = upb_MessageDef_MiniTable(def); + upb_Message* msg = PyUpb_Message_GetIfReified(_self); PyObject* arena = PyUpb_Arena_New(); - upb_Message* clone = upb_Message_DeepClone( - self->ptr.msg, upb_MessageDef_MiniTable(def), PyUpb_Arena_Get(arena)); + upb_Arena* upb_arena = PyUpb_Arena_Get(arena); + + upb_Message* clone = msg ? upb_Message_DeepClone(msg, mini_table, upb_arena) + : upb_Message_New(mini_table, upb_arena); PyObject* ret = PyUpb_Message_Get(clone, def, arena); Py_DECREF(arena);