[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48317] trunk/blender/source/blender/ python: fix for a handful of memory leaks relating to parsing and allocating arbitrary sized vectors from python args .

Campbell Barton ideasman42 at gmail.com
Tue Jun 26 18:58:59 CEST 2012


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 */




More information about the Bf-blender-cvs mailing list