Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-07-29 02:55:34 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-07-29 03:49:34 +0300
commit376e4c945ee862bb7cd7d22d677a5e59b8eeeb36 (patch)
tree7cc70f314b4ac2d9ad4327f2aac0ceb1f0adf18d /source
parentd226a4ba6df516147ee7a6f7fc40c9afad92fa49 (diff)
Fix leak in BPy_BMElem_PySeq_As_Array
Also add BPy_BMElem_PySeq_As_Array_FAST
Diffstat (limited to 'source')
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c152
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h5
2 files changed, 88 insertions, 69 deletions
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index f63381d7a7d..1b2382831b1 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 630afcb32c0..e6f0976965c 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,