Revision: 48317
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48317
Author:   campbellbarton
Date:     2012-06-26 16:58:58 +0000 (Tue, 26 Jun 2012)
Log Message:
-----------
fix for a handful of memory leaks relating to parsing and allocating arbitrary 
sized vectors from python args.

Vector.dot() was always leaking memory, and would crash if args sizes didnt 
match.

These errors were introduced with n-dimensional vector support.

also fixed an error with bmesh py api allocation.

Modified Paths:
--------------
    trunk/blender/source/blender/python/bmesh/bmesh_py_utils.c
    trunk/blender/source/blender/python/mathutils/mathutils.c
    trunk/blender/source/blender/python/mathutils/mathutils_Vector.c

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_utils.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_utils.c  2012-06-26 
16:49:52 UTC (rev 48316)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_utils.c  2012-06-26 
16:58:58 UTC (rev 48317)
@@ -457,6 +457,7 @@
                                        py_vert_a->v, py_vert_b->v,
                                        (float (*)[3])coords, ncoords,
                                        &l_new, py_edge_example ? 
py_edge_example->e : NULL);
+               PyMem_Free(coords);
        }
        else {
                f_new = BM_face_split(bm, py_face->f,

Modified: trunk/blender/source/blender/python/mathutils/mathutils.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils.c   2012-06-26 
16:49:52 UTC (rev 48316)
+++ trunk/blender/source/blender/python/mathutils/mathutils.c   2012-06-26 
16:58:58 UTC (rev 48317)
@@ -133,6 +133,7 @@
        }
 }
 
+/* on error, -1 is returned and no allocation is made */
 int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, 
const char *error_prefix)
 {
        int size;
@@ -164,6 +165,7 @@
        {
                PyObject *value_fast = NULL;
                // *array = NULL;
+               int ret;
 
                /* non list/tuple cases */
                if (!(value_fast = PySequence_Fast(value, error_prefix))) {
@@ -182,7 +184,13 @@
 
                *array = PyMem_Malloc(size * sizeof(float));
 
-               return mathutils_array_parse_fast(*array, size, value_fast, 
error_prefix);
+               ret = mathutils_array_parse_fast(*array, size, value_fast, 
error_prefix);
+
+               if (ret == -1) {
+                       PyMem_Free(*array);
+               }
+
+               return ret;
        }
 }
 

Modified: trunk/blender/source/blender/python/mathutils/mathutils_Vector.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils_Vector.c    
2012-06-26 16:49:52 UTC (rev 48316)
+++ trunk/blender/source/blender/python/mathutils/mathutils_Vector.c    
2012-06-26 16:58:58 UTC (rev 48317)
@@ -81,9 +81,6 @@
                        break;
                case 1:
                        if ((size = mathutils_array_parse_alloc(&vec, 2, 
PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
-                               if (vec) {
-                                       PyMem_Free(vec);
-                               }
                                return NULL;
                        }
                        break;
@@ -93,7 +90,7 @@
                                        "more then a single arg given");
                        return NULL;
        }
-       return Vector_CreatePyObject(vec, size, Py_NEW, type);
+       return Vector_CreatePyObject_alloc(vec, size, type);
 }
 
 static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject 
*self)
@@ -301,7 +298,6 @@
        if ((value_size = mathutils_array_parse_alloc(&iter_vec, 2, value,
                                                      "Vector.Repeat(vector, 
size), invalid 'vector' arg")) == -1)
        {
-               PyMem_Free(iter_vec);
                return NULL;
        }
 
@@ -315,6 +311,7 @@
        vec = PyMem_Malloc(size * sizeof(float));
 
        if (vec == NULL) {
+               PyMem_Free(iter_vec);
                PyErr_SetString(PyExc_MemoryError,
                                "Vector.Repeat(): "
                                "problem allocating pointer space");
@@ -898,19 +895,18 @@
 static PyObject *Vector_dot(VectorObject *self, PyObject *value)
 {
        float *tvec;
+       PyObject *ret;
 
        if (BaseMath_ReadCallback(self) == -1)
                return NULL;
 
        if (mathutils_array_parse_alloc(&tvec, self->size, value, 
"Vector.dot(other), invalid 'other' arg") == -1) {
-               goto cleanup;
+               return NULL;
        }
 
-       return PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
-
-cleanup:
+       ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
        PyMem_Free(tvec);
-       return NULL;
+       return ret;
 }
 
 PyDoc_STRVAR(Vector_angle_doc,
@@ -1140,12 +1136,12 @@
        if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac))
                return NULL;
 
-       if (mathutils_array_parse_alloc(&tvec, size, value, 
"Vector.lerp(other), invalid 'other' arg") == -1) {
-               goto cleanup;
+       if (BaseMath_ReadCallback(self) == -1) {
+               return NULL;
        }
 
-       if (BaseMath_ReadCallback(self) == -1) {
-               goto cleanup;
+       if (mathutils_array_parse_alloc(&tvec, size, value, 
"Vector.lerp(other), invalid 'other' arg") == -1) {
+               return NULL;
        }
 
        vec = PyMem_Malloc(size * sizeof(float));
@@ -1165,10 +1161,6 @@
        PyMem_Free(tvec);
 
        return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self));
-
-cleanup:
-       PyMem_Free(tvec);
-       return NULL;
 }
 
 PyDoc_STRVAR(Vector_rotate_doc,
@@ -1370,7 +1362,7 @@
 
        size = (end - begin);
        if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = 
[...]") == -1) {
-               goto cleanup;
+               return -1;
        }
 
        if (vec == NULL) {
@@ -1383,16 +1375,12 @@
        /*parsed well - now set in vector*/
        memcpy(self->vec + begin, vec, size * sizeof(float));
 
+       PyMem_Free(vec);
+
        if (BaseMath_WriteCallback(self) == -1)
                return -1;
 
-       PyMem_Free(vec);
-
        return 0;
-
-cleanup:
-       PyMem_Free(vec);
-       return -1;
 }
 
 /* Numeric Protocols */

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

Reply via email to