Python: Allow de-serializing bytearray (#868) Fix for https://github.com/protocolbuffers/protobuf/issues/10774 Closes #868 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/upb/pull/868 from ajasmin:bugfix/pythondeserialize-bytearray 5afeb11831fd6f2f80d032cfc54fb2e7bbe902ca PiperOrigin-RevId: 524857599
diff --git a/python/message.c b/python/message.c index 2fe5126..7d48b12 100644 --- a/python/message.c +++ b/python/message.c
@@ -1233,19 +1233,12 @@ PyObject* PyUpb_Message_MergeFromString(PyObject* _self, PyObject* arg) { PyUpb_Message* self = (void*)_self; - char* buf; - Py_ssize_t size; - PyObject* bytes = NULL; + Py_buffer data; - if (PyMemoryView_Check(arg)) { - bytes = PyBytes_FromObject(arg); - // Cannot fail when passed something of the correct type. - int err = PyBytes_AsStringAndSize(bytes, &buf, &size); - (void)err; - assert(err >= 0); - } else if (PyBytes_AsStringAndSize(arg, &buf, &size) < 0) { - return NULL; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) { + return 0; } + Py_ssize_t len = data.len; PyUpb_Message_EnsureReified(self); const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self); @@ -1259,14 +1252,14 @@ state->allow_oversize_protos ? UINT16_MAX : kUpb_WireFormat_DefaultDepthLimit); upb_DecodeStatus status = - upb_Decode(buf, size, self->ptr.msg, layout, extreg, options, arena); - Py_XDECREF(bytes); + upb_Decode(data.buf, len, self->ptr.msg, layout, extreg, options, arena); + PyBuffer_Release(&data); if (status != kUpb_DecodeStatus_Ok) { PyErr_Format(state->decode_error_class, "Error parsing message"); return NULL; } PyUpb_Message_SyncSubobjs(self); - return PyLong_FromSsize_t(size); + return PyLong_FromSsize_t(len); } static PyObject* PyUpb_Message_Clear(PyUpb_Message* self, PyObject* args);