Skip to content

Commit

Permalink
Merge pull request #17704 from protocolbuffers/cp-segv
Browse files Browse the repository at this point in the history
Fixed a SEGV when deep copying a non-reified sub-message.
  • Loading branch information
zhangskz committed Aug 5, 2024
2 parents 5d47e0a + 94a2663 commit 8a60b65
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
5 changes: 5 additions & 0 deletions python/google/protobuf/internal/reflection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
9 changes: 6 additions & 3 deletions python/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 8a60b65

Please sign in to comment.