[pygobject] Fix PyObject_Repr and PyObject_Str reference leaks



commit 5403149b900d1b73cbc78767dc43be2eb344c836
Author: Simon Feltman <s feltman gmail com>
Date:   Tue Jul 10 19:07:32 2012 -0700

    Fix PyObject_Repr and PyObject_Str reference leaks
    
    Fix all calls to PyObject_Repr() and PyObject_Str() to be properly DECREF'd.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=675857
    
    Signed-off-by: Martin Pitt <martinpitt gnome org>

 gi/_glib/glibmodule.c       |   10 ++++++-
 gi/_gobject/gobjectmodule.c |   17 +++++++++----
 gi/_gobject/pygobject.c     |   53 +++++++++++++++++++++++++++++-------------
 gi/pygi-marshal-from-py.c   |    9 +++++--
 4 files changed, 62 insertions(+), 27 deletions(-)
---
diff --git a/gi/_glib/glibmodule.c b/gi/_glib/glibmodule.c
index 2db764b..11b97f5 100644
--- a/gi/_glib/glibmodule.c
+++ b/gi/_glib/glibmodule.c
@@ -547,10 +547,13 @@ pyglib_get_application_name(PyObject *self)
 static PyObject*
 pyglib_set_application_name(PyObject *self, PyObject *arg)
 {
+    PyObject *repr = NULL;
     if (!PYGLIB_PyUnicode_Check(arg)) {
+	repr = PyObject_Repr(arg);
 	PyErr_Format(PyExc_TypeError,
 		     "first argument must be a string, not '%s'",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr(arg)));
+		     PYGLIB_PyUnicode_AsString(repr));
+	Py_DECREF(repr);
 	return NULL;
     }
     g_set_application_name(PYGLIB_PyUnicode_AsString(arg));
@@ -574,10 +577,13 @@ pyglib_get_prgname(PyObject *self)
 static PyObject*
 pyglib_set_prgname(PyObject *self, PyObject *arg)
 {
+    PyObject *repr = NULL;
     if (!PYGLIB_PyUnicode_Check(arg)) {
+	repr = PyObject_Repr(arg);
 	PyErr_Format(PyExc_TypeError,
 		     "first argument must be a string, not '%s'",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr(arg)));
+		     PYGLIB_PyUnicode_AsString(repr));
+	Py_DECREF(repr);
 	return NULL;
     }
     g_set_prgname(PYGLIB_PyUnicode_AsString(arg));
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index 0d75b7e..526a8be 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -120,6 +120,7 @@ pyg_type_from_name (PyObject *self, PyObject *args)
 {
     const gchar *name;
     GType type;
+    PyObject *repr = NULL;
 #if 0
     if (PyErr_Warn(PyExc_DeprecationWarning,
 		   "gobject.type_from_name is deprecated; "
@@ -131,9 +132,11 @@ pyg_type_from_name (PyObject *self, PyObject *args)
     type = _pyg_type_from_name(name);
     if (type != 0)
 	return pyg_type_wrapper_new(type);
+    repr = PyObject_Repr((PyObject*)self);
     PyErr_Format(PyExc_RuntimeError, "%s: unknown type name: %s",
-         PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+         PYGLIB_PyUnicode_AsString(repr),
 		 name);
+    Py_DECREF(repr);
     return NULL;
 }
 
@@ -1881,7 +1884,7 @@ out:
 static PyObject *
 pyg_add_emission_hook(PyGObject *self, PyObject *args)
 {
-    PyObject *first, *callback, *extra_args, *data;
+    PyObject *first, *callback, *extra_args, *data, *repr;
     gchar *name;
     gulong hook_id;
     guint sigid;
@@ -1913,9 +1916,11 @@ pyg_add_emission_hook(PyGObject *self, PyObject *args)
     }
 
     if (!g_signal_parse_name(name, gtype, &sigid, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-			PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+			PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     extra_args = PySequence_GetSlice(args, 3, len);
@@ -1937,7 +1942,7 @@ pyg_add_emission_hook(PyGObject *self, PyObject *args)
 static PyObject *
 pyg_remove_emission_hook(PyGObject *self, PyObject *args)
 {
-    PyObject *pygtype;
+    PyObject *pygtype, *repr;
     char *name;
     guint signal_id;
     gulong hook_id;
@@ -1952,9 +1957,11 @@ pyg_remove_emission_hook(PyGObject *self, PyObject *args)
     }
 
     if (!g_signal_parse_name(name, gtype, &signal_id, NULL, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-                 PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+                 PYGLIB_PyUnicode_AsString(repr),
                  name);
+	Py_DECREF(repr);
 	return NULL;
     }
 
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 355c6d0..1b98ea0 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -1745,7 +1745,7 @@ pygobject_set_data(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_connect(PyGObject *self, PyObject *args)
 {
-    PyObject *first, *callback, *extra_args;
+    PyObject *first, *callback, *extra_args, *repr = NULL;
     gchar *name;
     guint sigid, len;
     gulong handlerid;
@@ -1773,9 +1773,11 @@ pygobject_connect(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
 			     &sigid, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     extra_args = PySequence_GetSlice(args, 2, len);
@@ -1796,7 +1798,7 @@ pygobject_connect(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_connect_after(PyGObject *self, PyObject *args)
 {
-    PyObject *first, *callback, *extra_args;
+    PyObject *first, *callback, *extra_args, *repr = NULL;
     gchar *name;
     guint sigid;
     gulong handlerid;
@@ -1826,9 +1828,11 @@ pygobject_connect_after(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
 			     &sigid, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     extra_args = PySequence_GetSlice(args, 2, len);
@@ -1849,7 +1853,7 @@ pygobject_connect_after(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_connect_object(PyGObject *self, PyObject *args)
 {
-    PyObject *first, *callback, *extra_args, *object;
+    PyObject *first, *callback, *extra_args, *object, *repr = NULL;
     gchar *name;
     guint sigid;
     gulong handlerid;
@@ -1879,9 +1883,11 @@ pygobject_connect_object(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
 			     &sigid, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     extra_args = PySequence_GetSlice(args, 3, len);
@@ -1902,7 +1908,7 @@ pygobject_connect_object(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_connect_object_after(PyGObject *self, PyObject *args)
 {
-    PyObject *first, *callback, *extra_args, *object;
+    PyObject *first, *callback, *extra_args, *object, *repr = NULL;
     gchar *name;
     guint sigid;
     gulong handlerid;
@@ -1932,9 +1938,11 @@ pygobject_connect_object_after(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
 			     &sigid, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     extra_args = PySequence_GetSlice(args, 3, len);
@@ -2013,7 +2021,7 @@ pygobject_emit(PyGObject *self, PyObject *args)
     guint signal_id, i;
     Py_ssize_t len;
     GQuark detail;
-    PyObject *first, *py_ret;
+    PyObject *first, *py_ret, *repr = NULL;
     gchar *name;
     GSignalQuery query;
     GValue *params, ret = { 0, };
@@ -2034,9 +2042,11 @@ pygobject_emit(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj),
 			     &signal_id, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     name);
+	Py_DECREF(repr);
 	return NULL;
     }
     g_signal_query(signal_id, &query);
@@ -2102,6 +2112,7 @@ pygobject_stop_emission(PyGObject *self, PyObject *args)
     gchar *signal;
     guint signal_id;
     GQuark detail;
+    PyObject *repr = NULL;
 
     if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
 	return NULL;
@@ -2110,9 +2121,11 @@ pygobject_stop_emission(PyGObject *self, PyObject *args)
     
     if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
 			     &signal_id, &detail, TRUE)) {
+	repr = PyObject_Repr((PyObject*)self);
 	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)self)),
+		     PYGLIB_PyUnicode_AsString(repr),
 		     signal);
+	Py_DECREF(repr);
 	return NULL;
     }
     g_signal_stop_emission(self->obj, signal_id, detail);
@@ -2242,7 +2255,7 @@ pygobject_deepcopy(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
 {
-    PyObject *pyfunc = NULL;
+    PyObject *pyfunc = NULL, *repr = NULL;
     GClosure *closure = NULL;
     guint retval;
     
@@ -2258,8 +2271,10 @@ pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
 
     closure = gclosure_from_pyfunc(self, pyfunc);
     if (!closure) {
+	repr = PyObject_Repr((PyObject*)pyfunc);
 	PyErr_Format(PyExc_TypeError, "nothing connected to %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
+		     PYGLIB_PyUnicode_AsString(repr));
+	Py_DECREF(repr);
 	return NULL;
     }
     
@@ -2274,7 +2289,7 @@ pygobject_disconnect_by_func(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
 {
-    PyObject *pyfunc = NULL;
+    PyObject *pyfunc = NULL, *repr = NULL;
     GClosure *closure = NULL;
     guint retval;
     
@@ -2290,8 +2305,10 @@ pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
 
     closure = gclosure_from_pyfunc(self, pyfunc);
     if (!closure) {
+	repr = PyObject_Repr((PyObject*)pyfunc);
 	PyErr_Format(PyExc_TypeError, "nothing connected to %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
+		     PYGLIB_PyUnicode_AsString(repr));
+	Py_DECREF(repr);
 	return NULL;
     }
     
@@ -2306,7 +2323,7 @@ pygobject_handler_block_by_func(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
 {
-    PyObject *pyfunc = NULL;
+    PyObject *pyfunc = NULL, *repr = NULL;
     GClosure *closure = NULL;
     guint retval;
     
@@ -2322,8 +2339,10 @@ pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
 
     closure = gclosure_from_pyfunc(self, pyfunc);
     if (!closure) {
+	repr = PyObject_Repr((PyObject*)pyfunc);
 	PyErr_Format(PyExc_TypeError, "nothing connected to %s",
-		     PYGLIB_PyUnicode_AsString(PyObject_Repr((PyObject*)pyfunc)));
+		     PYGLIB_PyUnicode_AsString(repr));
+	Py_DECREF(repr);
 	return NULL;
     }
     
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index adb7152..abdc49e 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -401,6 +401,8 @@ _pygi_marshal_from_py_int64 (PyGIInvokeState   *state,
 
         if (PyUnicode_Check (py_str)) {
             PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
+            Py_DECREF (py_str);
+
             if (py_bytes == NULL)
                 return FALSE;
 
@@ -413,9 +415,9 @@ _pygi_marshal_from_py_int64 (PyGIInvokeState   *state,
             Py_DECREF (py_bytes);
         } else {
             long_str = g_strdup (PYGLIB_PyBytes_AsString(py_str));
+            Py_DECREF (py_str);
         }
 
-        Py_DECREF (py_str);
         PyErr_Format (PyExc_ValueError, "%s not in range %ld to %ld",
                       long_str, G_MININT64, G_MAXINT64);
 
@@ -479,6 +481,8 @@ _pygi_marshal_from_py_uint64 (PyGIInvokeState   *state,
 
         if (PyUnicode_Check (py_str)) {
             PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
+            Py_DECREF (py_str);
+
             if (py_bytes == NULL)
                 return FALSE;
 
@@ -491,10 +495,9 @@ _pygi_marshal_from_py_uint64 (PyGIInvokeState   *state,
             Py_DECREF (py_bytes);
         } else {
             long_str = g_strdup (PYGLIB_PyBytes_AsString (py_str));
+            Py_DECREF (py_str);
         }
 
-        Py_DECREF (py_str);
-
         PyErr_Format (PyExc_ValueError, "%s not in range %d to %lu",
                       long_str, 0, G_MAXUINT64);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]