Fix #106696: Invalid flag combinations used in #PyObject_GetBuffer

Code using #PyObject_GetBuffer was combining the `PyBUF_FORMAT` and
`PyBUF_SIMPLE` flags, but the documentation specifies that
`PyBUF_FORMAT` can be |'d to any of the flags except `PyBUF_SIMPLE`
because the latter already implies format `B` (unsigned bytes).

The flags in such cases have been replaced with
`PyBUF_ND | PyBUF_FORMAT`, which has the additional requirement that the
buffer must provide it's `shape` field.

This fixes `memoryview` objects raising a `BufferError` when requested,
due to the invalid combination of flags making them be considered
invalid buffers when they would otherwise be valid.

Ref: !106697
This commit is contained in:
Thomas Barlow 2023-11-09 18:43:05 +11:00 committed by Campbell Barton
parent 801c3275f5
commit 1058a93994
2 changed files with 4 additions and 4 deletions

View File

@ -603,7 +603,7 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob)
bool use_buffer = false;
if (PyObject_CheckBuffer(ob)) {
if (PyObject_GetBuffer(ob, &buffer, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
if (PyObject_GetBuffer(ob, &buffer, PyBUF_ND | 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();

View File

@ -5460,7 +5460,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
if (PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | 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();
@ -5521,7 +5521,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
if (PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | 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();
@ -5665,7 +5665,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
}
Py_buffer buf;
if (PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT) == -1) {
if (PyObject_GetBuffer(seq, &buf, PyBUF_ND | PyBUF_FORMAT) == -1) {
PyErr_Clear();
switch (prop_type) {