2
0
Эх сурвалжийг харах

Fix memory leak in C implementation of sorted_tree_items.

The tuples created by PyTuple_Pack did not have their refcounts
decreased before raising an exception.

Change-Id: Ic7b62c0fb008129d648d2c3bacfbc2d47260229b
Dave Borowitz 15 жил өмнө
parent
commit
f24570658f
2 өөрчлөгдсөн 20 нэмэгдсэн , 6 устгасан
  1. 4 0
      NEWS
  2. 16 6
      dulwich/_objects.c

+ 4 - 0
NEWS

@@ -1,5 +1,9 @@
 0.6.1	UNRELEASED
 
+ BUG FIXES
+
+  * Fix memory leak in C implementation of sorted_tree_items. (Dave Borowitz)
+
  TESTS
 
   * Add tests for sorted_tree_items and C implementation. (Dave Borowitz)

+ 16 - 6
dulwich/_objects.c

@@ -136,6 +136,14 @@ int cmp_tree_item(const void *_a, const void *_b)
 	return strcmp(remain_a, remain_b);
 }
 
+static void free_tree_items(struct tree_item *items, int num) {
+	int i;
+	for (i = 0; i < num; i++) {
+		Py_DECREF(items[i].tuple);
+	}
+	free(items);
+}
+
 static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
 {
 	struct tree_item *qsort_entries;
@@ -162,13 +170,13 @@ static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
 
 		if (!PyString_Check(key)) {
 			PyErr_SetString(PyExc_TypeError, "Name is not a string");
-			free(qsort_entries);
+			free_tree_items(qsort_entries, i);
 			return NULL;
 		}
 
 		if (PyTuple_Size(value) != 2) {
 			PyErr_SetString(PyExc_ValueError, "Tuple has invalid size");
-			free(qsort_entries);
+			free_tree_items(qsort_entries, i);
 			return NULL;
 		}
 
@@ -176,19 +184,21 @@ static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
 		py_int_mode = PyNumber_Int(py_mode);
 		if (!py_int_mode) {
 			PyErr_SetString(PyExc_TypeError, "Mode is not an integral type");
-			free(qsort_entries);
+			free_tree_items(qsort_entries, i);
 			return NULL;
 		}
 
 		py_sha = PyTuple_GET_ITEM(value, 1);
 		if (!PyString_Check(py_sha)) {
 			PyErr_SetString(PyExc_TypeError, "SHA is not a string");
-			free(qsort_entries);
+			Py_DECREF(py_int_mode);
+			free_tree_items(qsort_entries, i);
 			return NULL;
 		}
 		qsort_entries[i].name = PyString_AS_STRING(key);
 		qsort_entries[i].mode = PyInt_AS_LONG(py_mode);
-		qsort_entries[i].tuple = PyTuple_Pack(3, key, py_mode, py_sha);
+		qsort_entries[i].tuple = PyTuple_Pack(3, key, py_int_mode, py_sha);
+		Py_DECREF(py_int_mode);
 		i++;
 	}
 
@@ -196,7 +206,7 @@ static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries)
 
 	ret = PyList_New(num);
 	if (ret == NULL) {
-		free(qsort_entries);
+		free_tree_items(qsort_entries, i);
 		PyErr_NoMemory();
 		return NULL;
 	}