From 1058a93994571313fa581d2e3ee71859101307d6 Mon Sep 17 00:00:00 2001
From: Thomas Barlow <github@mysterymayhem.co.uk>
Date: Thu, 9 Nov 2023 18:43:05 +1100
Subject: [PATCH] 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
---
 source/blender/python/generic/idprop_py_api.cc | 2 +-
 source/blender/python/intern/bpy_rna.cc        | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/source/blender/python/generic/idprop_py_api.cc b/source/blender/python/generic/idprop_py_api.cc
index 1d089b78e261..01745568a462 100644
--- a/source/blender/python/generic/idprop_py_api.cc
+++ b/source/blender/python/generic/idprop_py_api.cc
@@ -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();
diff --git a/source/blender/python/intern/bpy_rna.cc b/source/blender/python/intern/bpy_rna.cc
index c1292f26f0be..8459def08fe6 100644
--- a/source/blender/python/intern/bpy_rna.cc
+++ b/source/blender/python/intern/bpy_rna.cc
@@ -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) {
-- 
GitLab