Fix #107017: Missing checks for #PyObject_GetBuffer success

`PyObject_GetBuffer` was used without checking that it was successful.
This could cause the code to access an incompatible or uninitialized
`Py_buffer`.

Add the missing checks, and clears the raised `PyExc_BufferError`
to silently fall back to accessing the PyObject as a sequence.
This commit is contained in:
2023-04-14 19:36:54 +01:00
committed by Campbell Barton
parent 1d8389cd09
commit 348f57bcec
2 changed files with 42 additions and 26 deletions

View File

@@ -600,14 +600,20 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob)
bool use_buffer = false;
if (PyObject_CheckBuffer(ob)) {
PyObject_GetBuffer(ob, &buffer, PyBUF_SIMPLE | PyBUF_FORMAT);
const char format = PyC_StructFmt_type_from_str(buffer.format);
if (PyC_StructFmt_type_is_float_any(format) ||
(PyC_StructFmt_type_is_int_any(format) && buffer.itemsize == 4)) {
use_buffer = true;
if (PyObject_GetBuffer(ob, &buffer, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
/* Request failed. A `PyExc_BufferError` will have been raised,
* so clear it to silently fall back to accessing as a sequence. */
PyErr_Clear();
}
else {
PyBuffer_Release(&buffer);
const char format = PyC_StructFmt_type_from_str(buffer.format);
if (PyC_StructFmt_type_is_float_any(format) ||
(PyC_StructFmt_type_is_int_any(format) && buffer.itemsize == 4)) {
use_buffer = true;
}
else {
PyBuffer_Release(&buffer);
}
}
}