[glib-networking] gnutls: fix leaks



commit 23673249846dc263607681b9b8db42dfa68e6cde
Author: Dan Winship <danw gnome org>
Date:   Mon Apr 4 11:09:15 2011 -0400

    gnutls: fix leaks
    
    GTlsConnections were never being freed, due to circular refs.
    Additionally, certificates seen during handshaking, and a
    GSocketAddress used in the session cache code were being leaked.

 tls/gnutls/gtlsclientconnection-gnutls.c |    1 +
 tls/gnutls/gtlsconnection-gnutls.c       |    2 ++
 tls/gnutls/gtlsinputstream-gnutls.c      |   25 ++++++++++++++++++++-----
 tls/gnutls/gtlsoutputstream-gnutls.c     |   25 ++++++++++++++++++++-----
 4 files changed, 43 insertions(+), 10 deletions(-)
---
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 245fc09..2710e9c 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -156,6 +156,7 @@ g_tls_client_connection_gnutls_constructed (GObject *object)
 	  gnutls->priv->session_id = g_strdup_printf ("%s/%d", addrstr, port);
 	  g_free (addrstr);
 	}
+      g_object_unref (remote_addr);
     }
   g_object_unref (base_conn);
 
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index c0fb898..b741184 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -846,6 +846,8 @@ handshake_internal (GTlsConnectionGnutls  *gnutls,
 	  for (i = num_certs - 1; i >= 0; i--)
 	    {
 	      cert = g_tls_certificate_gnutls_new (&certs[i], chain);
+	      if (chain)
+		g_object_unref (chain);
 	      chain = cert;
 	    }
 	}
diff --git a/tls/gnutls/gtlsinputstream-gnutls.c b/tls/gnutls/gtlsinputstream-gnutls.c
index dd22be5..6970883 100644
--- a/tls/gnutls/gtlsinputstream-gnutls.c
+++ b/tls/gnutls/gtlsinputstream-gnutls.c
@@ -38,14 +38,18 @@ struct _GTlsInputStreamGnutlsPrivate
 };
 
 static void
-g_tls_input_stream_gnutls_finalize (GObject *object)
+g_tls_input_stream_gnutls_dispose (GObject *object)
 {
   GTlsInputStreamGnutls *stream = G_TLS_INPUT_STREAM_GNUTLS (object);
 
   if (stream->priv->conn)
-    g_object_unref (stream->priv->conn);
+    {
+      g_object_remove_weak_pointer (G_OBJECT (stream->priv->conn),
+				    (gpointer *)&stream->priv->conn);
+      stream->priv->conn = NULL;
+    }
 
-  G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->finalize (object);
+  G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->dispose (object);
 }
 
 static gssize
@@ -57,6 +61,8 @@ g_tls_input_stream_gnutls_read (GInputStream  *stream,
 {
   GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, -1);
+
   return g_tls_connection_gnutls_read (tls_stream->priv->conn,
 				       buffer, count, TRUE,
 				       cancellable, error);
@@ -117,6 +123,8 @@ g_tls_input_stream_gnutls_read_async (GInputStream        *stream,
   GError *error = NULL;
   GSource *source;
 
+  g_return_if_fail (tls_stream->priv->conn != NULL);
+
   simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
 				      g_tls_input_stream_gnutls_read_async);
   nread = g_tls_connection_gnutls_read (tls_stream->priv->conn,
@@ -168,6 +176,8 @@ g_tls_input_stream_gnutls_pollable_is_readable (GPollableInputStream *pollable)
 {
   GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, FALSE);
+
   return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_IN); 
 }
 
@@ -177,6 +187,8 @@ g_tls_input_stream_gnutls_pollable_create_source (GPollableInputStream *pollable
 {
   GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, NULL);
+
   return g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
 						G_IO_IN,
 						cancellable);
@@ -203,7 +215,7 @@ g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass)
 
   g_type_class_add_private (klass, sizeof (GTlsInputStreamGnutlsPrivate));
 
-  gobject_class->finalize = g_tls_input_stream_gnutls_finalize;
+  gobject_class->dispose = g_tls_input_stream_gnutls_dispose;
 
   input_stream_class->read_fn = g_tls_input_stream_gnutls_read;
   input_stream_class->read_async = g_tls_input_stream_gnutls_read_async;
@@ -230,6 +242,9 @@ g_tls_input_stream_gnutls_new (GTlsConnectionGnutls *conn)
   GTlsInputStreamGnutls *tls_stream;
 
   tls_stream = g_object_new (G_TYPE_TLS_INPUT_STREAM_GNUTLS, NULL);
-  tls_stream->priv->conn = g_object_ref (conn);
+  tls_stream->priv->conn = conn;
+  g_object_add_weak_pointer (G_OBJECT (conn),
+			     (gpointer *)&tls_stream->priv->conn);
+
   return G_INPUT_STREAM (tls_stream);
 }
diff --git a/tls/gnutls/gtlsoutputstream-gnutls.c b/tls/gnutls/gtlsoutputstream-gnutls.c
index 462d74e..2e101e4 100644
--- a/tls/gnutls/gtlsoutputstream-gnutls.c
+++ b/tls/gnutls/gtlsoutputstream-gnutls.c
@@ -38,14 +38,18 @@ struct _GTlsOutputStreamGnutlsPrivate
 };
 
 static void
-g_tls_output_stream_gnutls_finalize (GObject *object)
+g_tls_output_stream_gnutls_dispose (GObject *object)
 {
   GTlsOutputStreamGnutls *stream = G_TLS_OUTPUT_STREAM_GNUTLS (object);
 
   if (stream->priv->conn)
-    g_object_unref (stream->priv->conn);
+    {
+      g_object_remove_weak_pointer (G_OBJECT (stream->priv->conn),
+				    (gpointer *)&stream->priv->conn);
+      stream->priv->conn = NULL;
+    }
 
-  G_OBJECT_CLASS (g_tls_output_stream_gnutls_parent_class)->finalize (object);
+  G_OBJECT_CLASS (g_tls_output_stream_gnutls_parent_class)->dispose (object);
 }
 
 static gssize
@@ -57,6 +61,8 @@ g_tls_output_stream_gnutls_write (GOutputStream  *stream,
 {
   GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (stream);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, -1);
+
   return g_tls_connection_gnutls_write (tls_stream->priv->conn,
 					buffer, count, TRUE,
 					cancellable, error);
@@ -117,6 +123,8 @@ g_tls_output_stream_gnutls_write_async (GOutputStream        *stream,
   GError *error = NULL;
   GSource *source;
 
+  g_return_if_fail (tls_stream->priv->conn != NULL);
+
   simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
 				      g_tls_output_stream_gnutls_write_async);
   nwrote = g_tls_connection_gnutls_write (tls_stream->priv->conn,
@@ -168,6 +176,8 @@ g_tls_output_stream_gnutls_pollable_is_writable (GPollableOutputStream *pollable
 {
   GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, FALSE);
+
   return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_OUT); 
 }
 
@@ -177,6 +187,8 @@ g_tls_output_stream_gnutls_pollable_create_source (GPollableOutputStream *pollab
 {
   GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable);
 
+  g_return_val_if_fail (tls_stream->priv->conn != NULL, NULL);
+
   return g_tls_connection_gnutls_create_source (tls_stream->priv->conn,
 						G_IO_OUT,
 						cancellable);
@@ -203,7 +215,7 @@ g_tls_output_stream_gnutls_class_init (GTlsOutputStreamGnutlsClass *klass)
 
   g_type_class_add_private (klass, sizeof (GTlsOutputStreamGnutlsPrivate));
 
-  gobject_class->finalize = g_tls_output_stream_gnutls_finalize;
+  gobject_class->dispose = g_tls_output_stream_gnutls_dispose;
 
   output_stream_class->write_fn = g_tls_output_stream_gnutls_write;
   output_stream_class->write_async = g_tls_output_stream_gnutls_write_async;
@@ -230,6 +242,9 @@ g_tls_output_stream_gnutls_new (GTlsConnectionGnutls *conn)
   GTlsOutputStreamGnutls *tls_stream;
 
   tls_stream = g_object_new (G_TYPE_TLS_OUTPUT_STREAM_GNUTLS, NULL);
-  tls_stream->priv->conn = g_object_ref (conn);
+  tls_stream->priv->conn = conn;
+  g_object_add_weak_pointer (G_OBJECT (conn),
+			     (gpointer *)&tls_stream->priv->conn);
+
   return G_OUTPUT_STREAM (tls_stream);
 }



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