pyldb: Fix reference leaks
authorPetr Viktorin <pviktori@redhat.com>
Tue, 3 Mar 2015 21:29:10 +0000 (22:29 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 3 Mar 2015 22:20:06 +0000 (23:20 +0100)
The parse_ldif and MessageElement.__iter__ functions leaked references
to intermediate lists whose iterators they return.

The MessageElement repr used the undocumented macro PyObject_REPR, which
leaks references. (It was used internally in CPython before fatal errors,
and will be removed in Python 3.5.)

Signed-off-by: Petr Viktorin <pviktori@redhat.com>
Reviewed-by: Jelmer Vernooij <jelmer@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/pyldb.c

index 67a35771862eea732a3dfd628025f0888542a40b..adcde0cac11036cad8f9708c9cb60f7b13677b24 100644 (file)
@@ -1546,7 +1546,7 @@ static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
 
 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
 {
 
 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
 {
-       PyObject *list;
+       PyObject *list, *ret;
        struct ldb_ldif *ldif;
        const char *s;
 
        struct ldb_ldif *ldif;
        const char *s;
 
@@ -1573,7 +1573,9 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
                }
        }
        talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
                }
        }
        talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
-       return PyObject_GetIter(list);
+       ret = PyObject_GetIter(list);
+       Py_DECREF(list);
+       return ret;
 }
 
 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
 }
 
 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
@@ -2450,7 +2452,9 @@ static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
 {
        PyObject *el = ldb_msg_element_to_set(NULL,
                                              pyldb_MessageElement_AsMessageElement(self));
 {
        PyObject *el = ldb_msg_element_to_set(NULL,
                                              pyldb_MessageElement_AsMessageElement(self));
-       return PyObject_GetIter(el);
+       PyObject *ret = PyObject_GetIter(el);
+       Py_DECREF(el);
+       return ret;
 }
 
 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
 }
 
 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
@@ -2562,14 +2566,16 @@ static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
        char *element_str = NULL;
        Py_ssize_t i;
        struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
        char *element_str = NULL;
        Py_ssize_t i;
        struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
-       PyObject *ret;
+       PyObject *ret, *repr;
 
        for (i = 0; i < el->num_values; i++) {
                PyObject *o = py_ldb_msg_element_find(self, i);
 
        for (i = 0; i < el->num_values; i++) {
                PyObject *o = py_ldb_msg_element_find(self, i);
+               repr = PyObject_Repr(o);
                if (element_str == NULL)
                if (element_str == NULL)
-                       element_str = talloc_strdup(NULL, PyObject_REPR(o));
+                       element_str = talloc_strdup(NULL, PyString_AsString(repr));
                else
                else
-                       element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
+                       element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
+               Py_DECREF(repr);
        }
 
        if (element_str != NULL) {
        }
 
        if (element_str != NULL) {