Commit: 376e4c945ee862bb7cd7d22d677a5e59b8eeeb36
Author: Campbell Barton
Date:   Wed Jul 29 09:55:34 2015 +1000
Branches: master
https://developer.blender.org/rB376e4c945ee862bb7cd7d22d677a5e59b8eeeb36

Fix leak in BPy_BMElem_PySeq_As_Array

Also add BPy_BMElem_PySeq_As_Array_FAST

===================================================================

M       source/blender/python/bmesh/bmesh_py_types.c
M       source/blender/python/bmesh/bmesh_py_types.h

===================================================================

diff --git a/source/blender/python/bmesh/bmesh_py_types.c 
b/source/blender/python/bmesh/bmesh_py_types.c
index f63381d..1b23828 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -3759,106 +3759,120 @@ void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
  *
  * The 'bm_r' value is assigned when empty, and used when set.
  */
-void *BPy_BMElem_PySeq_As_Array(
-        BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, 
Py_ssize_t *r_size,
+void *BPy_BMElem_PySeq_As_Array_FAST(
+        BMesh **r_bm, PyObject *seq_fast, Py_ssize_t min, Py_ssize_t max, 
Py_ssize_t *r_size,
         const char htype,
         const bool do_unique_check, const bool do_bm_check,
         const char *error_prefix)
 {
        BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
-       PyObject *seq_fast;
+       const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+       Py_ssize_t i;
+
+       BPy_BMElem *item;
+       BMElem **alloc;
+
        *r_size = 0;
 
-       if (!(seq_fast = PySequence_Fast(seq, error_prefix))) {
+       if (seq_len < min || seq_len > max) {
+               PyErr_Format(PyExc_TypeError,
+                            "%s: sequence incorrect size, expected [%d - %d], 
given %d",
+                            error_prefix, min, max, seq_len);
                return NULL;
        }
-       else {
-               Py_ssize_t seq_len;
-               Py_ssize_t i;
 
-               BPy_BMElem *item;
-               BMElem **alloc;
+       /* from now on, use goto */
+       alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
 
-               seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+       for (i = 0; i < seq_len; i++) {
+               item = (BPy_BMElem *)PySequence_Fast_GET_ITEM(seq_fast, i);
 
-               if (seq_len < min || seq_len > max) {
+               if (!BPy_BMElem_CheckHType(Py_TYPE(item), htype)) {
                        PyErr_Format(PyExc_TypeError,
-                                    "%s: sequence incorrect size, expected [%d 
- %d], given %d",
-                                    error_prefix, min, max, seq_len);
-                       return NULL;
+                                    "%s: expected %.200s, not '%.200s'",
+                                    error_prefix, 
BPy_BMElem_StringFromHType(htype), Py_TYPE(item)->tp_name);
+                       goto err_cleanup;
+               }
+               else if (!BPY_BM_IS_VALID(item)) {
+                       PyErr_Format(PyExc_TypeError,
+                                    "%s: %d %s has been removed",
+                                    error_prefix, i, Py_TYPE(item)->tp_name);
+                       goto err_cleanup;
+               }
+               /* trick so we can ensure all items have the same mesh,
+                * and allows us to pass the 'bm' as NULL. */
+               else if (do_bm_check && (bm && bm != item->bm)) {
+                       PyErr_Format(PyExc_ValueError,
+                                    "%s: %d %s is from another mesh",
+                                    error_prefix, i, 
BPy_BMElem_StringFromHType(htype));
+                       goto err_cleanup;
                }
 
+               if (bm == NULL) {
+                       bm = item->bm;
+               }
 
-               /* from now on, use goto */
-               alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
-
-               for (i = 0; i < seq_len; i++) {
-                       item = (BPy_BMElem *)PySequence_Fast_GET_ITEM(seq_fast, 
i);
+               alloc[i] = item->ele;
 
-                       if (!BPy_BMElem_CheckHType(Py_TYPE(item), htype)) {
-                               PyErr_Format(PyExc_TypeError,
-                                            "%s: expected %.200s, not 
'%.200s'",
-                                            error_prefix, 
BPy_BMElem_StringFromHType(htype), Py_TYPE(item)->tp_name);
-                               goto err_cleanup;
-                       }
-                       else if (!BPY_BM_IS_VALID(item)) {
-                               PyErr_Format(PyExc_TypeError,
-                                            "%s: %d %s has been removed",
-                                            error_prefix, i, 
Py_TYPE(item)->tp_name);
-                               goto err_cleanup;
-                       }
-                       /* trick so we can ensure all items have the same mesh,
-                        * and allows us to pass the 'bm' as NULL. */
-                       else if (do_bm_check && (bm && bm != item->bm)) {
-                               PyErr_Format(PyExc_ValueError,
-                                            "%s: %d %s is from another mesh",
-                                            error_prefix, i, 
BPy_BMElem_StringFromHType(htype));
-                               goto err_cleanup;
-                       }
+               if (do_unique_check) {
+                       BM_elem_flag_enable(item->ele, BM_ELEM_INTERNAL_TAG);
+               }
+       }
 
-                       if (bm == NULL) {
-                               bm = item->bm;
+       if (do_unique_check) {
+               /* check for double verts! */
+               bool ok = true;
+               for (i = 0; i < seq_len; i++) {
+                       if (UNLIKELY(BM_elem_flag_test(alloc[i], 
BM_ELEM_INTERNAL_TAG) == false)) {
+                               ok = false;
                        }
 
-                       alloc[i] = item->ele;
+                       /* ensure we don't leave this enabled */
+                       BM_elem_flag_disable(alloc[i], BM_ELEM_INTERNAL_TAG);
+               }
 
-                       if (do_unique_check) {
-                               BM_elem_flag_enable(item->ele, 
BM_ELEM_INTERNAL_TAG);
-                       }
+               if (ok == false) {
+                       PyErr_Format(PyExc_ValueError,
+                                    "%s: found the same %.200s used multiple 
times",
+                                    error_prefix, 
BPy_BMElem_StringFromHType(htype));
+                       goto err_cleanup;
                }
+       }
 
-               if (do_unique_check) {
-                       /* check for double verts! */
-                       bool ok = true;
-                       for (i = 0; i < seq_len; i++) {
-                               if (UNLIKELY(BM_elem_flag_test(alloc[i], 
BM_ELEM_INTERNAL_TAG) == false)) {
-                                       ok = false;
-                               }
+       *r_size = seq_len;
+       if (r_bm) *r_bm = bm;
+       return alloc;
 
-                               /* ensure we don't leave this enabled */
-                               BM_elem_flag_disable(alloc[i], 
BM_ELEM_INTERNAL_TAG);
-                       }
+err_cleanup:
+       PyMem_FREE(alloc);
+       return NULL;
 
-                       if (ok == false) {
-                               PyErr_Format(PyExc_ValueError,
-                                            "%s: found the same %.200s used 
multiple times",
-                                            error_prefix, 
BPy_BMElem_StringFromHType(htype));
-                               goto err_cleanup;
-                       }
-               }
+}
 
-               Py_DECREF(seq_fast);
-               *r_size = seq_len;
-               if (r_bm) *r_bm = bm;
-               return alloc;
+void *BPy_BMElem_PySeq_As_Array(
+        BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, 
Py_ssize_t *r_size,
+        const char htype,
+        const bool do_unique_check, const bool do_bm_check,
+        const char *error_prefix)
+{
+       PyObject *seq_fast;
+       PyObject *ret;
 
-err_cleanup:
-               Py_DECREF(seq_fast);
-               PyMem_FREE(alloc);
+       if (!(seq_fast = PySequence_Fast(seq, error_prefix))) {
                return NULL;
        }
+
+       ret = BPy_BMElem_PySeq_As_Array_FAST(
+               r_bm, seq_fast, min, max, r_size,
+               htype,
+               do_unique_check, do_bm_check,
+               error_prefix);
+
+       Py_DECREF(seq_fast);
+       return ret;
 }
 
+
 PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t 
elem_len)
 {
        Py_ssize_t i;
diff --git a/source/blender/python/bmesh/bmesh_py_types.h 
b/source/blender/python/bmesh/bmesh_py_types.h
index 630afcb..e6f0976 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -158,6 +158,11 @@ PyObject *BPy_BMIter_CreatePyObject(BMesh *bm);
 
 PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks 
type and creates v/e/f/l */
 
+void *BPy_BMElem_PySeq_As_Array_FAST(
+        BMesh **r_bm, PyObject *seq_fast, Py_ssize_t min, Py_ssize_t max, 
Py_ssize_t *r_size,
+        const char htype,
+        const bool do_unique_check, const bool do_bm_check,
+        const char *error_prefix);
 void *BPy_BMElem_PySeq_As_Array(
         BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, 
Py_ssize_t *r_size,
         const char htype,

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to