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);