[tracker/rss-enclosures] libtracker-common: Fix memory leak when receiving partial reply plus error in DBus async call



commit 0330009bb0bff42bc9d18203585fa697ddfff633
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Mon Jul 19 23:33:34 2010 +0200

    libtracker-common: Fix memory leak when receiving partial reply plus error in DBus async call
    
     * So, we're using g_memory_output_stream_new () with a NULL destroy_function.
       This means we take ownership and control of the internal buffer if the
       GOutputStream. Then, if the async DBus query results in an error, we won't
       pass the stream->data to upper layers, so we need to explicitly free it,
       or a memleak will happen.
    
     * Could reproduce the issue easily with PDF files giving DBus-timeouts.

 src/libtracker-common/tracker-dbus.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-common/tracker-dbus.c b/src/libtracker-common/tracker-dbus.c
index 0876013..b940717 100644
--- a/src/libtracker-common/tracker-dbus.c
+++ b/src/libtracker-common/tracker-dbus.c
@@ -842,11 +842,17 @@ send_and_splice_async_callback (GObject      *source,
 	SendAndSpliceData *data = user_data;
 	DBusMessage *reply = NULL;
 	GError *error = NULL;
+	gpointer received_data;
+	gsize received_data_size;
 
 	g_output_stream_splice_finish (data->output_stream,
 	                               result,
 	                               &error);
 
+	/* Get received data pointer and size */
+	received_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream));
+	received_data_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream));
+
 	if (G_LIKELY (!error)) {
 		dbus_pending_call_block (data->call);
 		reply = dbus_pending_call_steal_reply (data->call);
@@ -854,6 +860,10 @@ send_and_splice_async_callback (GObject      *source,
 		if (G_UNLIKELY (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)) {
 			DBusError dbus_error;
 
+			/* If any error happened, we're not passing any received data, so we
+			 * need to free it */
+			g_free (received_data);
+
 			dbus_error_init (&dbus_error);
 			dbus_set_error_from_message (&dbus_error, reply);
 			dbus_set_g_error (&error, &dbus_error);
@@ -867,12 +877,16 @@ send_and_splice_async_callback (GObject      *source,
 			 * callback itself. */
 		} else {
 			dbus_pending_call_cancel (data->call);
-			(* data->callback) (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
-			                    g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
+			(* data->callback) (received_data,
+			                    received_data_size,
 			                    NULL,
 			                    data->user_data);
 		}
 	} else {
+		/* If any error happened, we're not passing any received data, so we
+		 * need to free it */
+		g_free (received_data);
+
 		(* data->callback) (NULL, -1, error, data->user_data);
 
 		g_error_free (error);



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