[evolution-data-server] Bug #677530 - Memory leaks in imapx code



commit 635cc35db49ecbcbcec0adde7f6d5dbc32008710
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 19 22:09:46 2012 +0200

    Bug #677530 - Memory leaks in imapx code

 camel/camel-folder-summary.c     |    9 +++++
 camel/camel-imapx-conn-manager.c |    2 +-
 camel/camel-imapx-server.c       |   68 ++++++++++++++++++++++++++++---------
 camel/camel-imapx-store.c        |    3 +-
 4 files changed, 63 insertions(+), 19 deletions(-)
---
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index fb0c673..cc87103 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -3401,9 +3401,16 @@ camel_folder_summary_remove_uids (CamelFolderSummary *summary,
 		gpointer ptr_uid = NULL, ptr_flags = NULL;
 		if (g_hash_table_lookup_extended (summary->priv->uids, l->data, &ptr_uid, &ptr_flags)) {
 			const gchar *uid_copy = camel_pstring_strdup (l->data);
+			CamelMessageInfo *mi;
+
 			folder_summary_update_counts_by_flags (summary, GPOINTER_TO_UINT (ptr_flags), UPDATE_COUNTS_SUB);
 			g_hash_table_remove (summary->priv->uids, uid_copy);
+
+			mi = g_hash_table_lookup (summary->priv->loaded_infos, uid_copy);
 			g_hash_table_remove (summary->priv->loaded_infos, uid_copy);
+
+			if (mi)
+				camel_message_info_free (mi);
 			camel_pstring_free (uid_copy);
 		}
 	}
@@ -3486,6 +3493,8 @@ content_info_new_from_parser (CamelFolderSummary *summary,
 	case CAMEL_MIME_PARSER_STATE_MULTIPART:
 		ci = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary)->content_info_new_from_header (summary, camel_mime_parser_headers_raw (mp));
 		if (ci) {
+			if (ci->type)
+				camel_content_type_unref (ci->type);
 			ci->type = camel_mime_parser_content_type (mp);
 			camel_content_type_ref (ci->type);
 		}
diff --git a/camel/camel-imapx-conn-manager.c b/camel/camel-imapx-conn-manager.c
index f406300..1a721f6 100644
--- a/camel/camel-imapx-conn-manager.c
+++ b/camel/camel-imapx-conn-manager.c
@@ -295,7 +295,7 @@ imapx_conn_manager_remove_info (CamelIMAPXConnManager *con_man,
 	link = g_list_find (list, cinfo);
 
 	if (link != NULL) {
-		list = g_list_remove_link (list, link);
+		list = g_list_delete_link (list, link);
 		connection_info_unref (cinfo);
 		removed = TRUE;
 	}
diff --git a/camel/camel-imapx-server.c b/camel/camel-imapx-server.c
index a9a52ae..f1b611f 100644
--- a/camel/camel-imapx-server.c
+++ b/camel/camel-imapx-server.c
@@ -470,9 +470,29 @@ get_message_data_free (GetMessageData *data)
 }
 
 static void
+refresh_info_data_infos_free (RefreshInfoData *data)
+{
+	gint ii;
+
+	if (!data || !data->infos)
+		return;
+
+	for (ii = 0; ii < data->infos->len; ii++) {
+		struct _refresh_info *r = &g_array_index (data->infos, struct _refresh_info, ii);
+
+		camel_flag_list_free (&r->server_user_flags);
+		g_free (r->uid);
+	}
+
+	g_array_free (data->infos, TRUE);
+	data->infos = NULL;
+}
+
+static void
 refresh_info_data_free (RefreshInfoData *data)
 {
 	camel_folder_change_info_free (data->changes);
+	refresh_info_data_infos_free (data);
 
 	g_slice_free (RefreshInfoData, data);
 }
@@ -1140,6 +1160,7 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
                                 gboolean unsolicited)
 {
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) is->select_folder;
+	CamelMessageInfo *mi;
 
 	if (unsolicited && ifolder->exists_on_server)
 		ifolder->exists_on_server--;
@@ -1147,7 +1168,12 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
 	if (is->changes == NULL)
 		is->changes = camel_folder_change_info_new ();
 
-	camel_folder_summary_remove_uid (is->select_folder->summary, uid);
+	mi = camel_folder_summary_get (is->select_folder->summary, uid);
+	if (mi) {
+		camel_folder_summary_remove (is->select_folder->summary, mi);
+		camel_message_info_free (mi);
+	}
+
 	is->expunged = g_list_prepend (is->expunged, uid);
 
 	camel_folder_change_info_remove_uid (is->changes, uid);
@@ -1361,6 +1387,8 @@ imapx_untagged_namespace (CamelIMAPXServer *is,
 
 	imapx_store = (CamelIMAPXStore *) is->store;
 
+	if (imapx_store->summary->namespaces)
+		camel_imapx_namespace_list_clear (imapx_store->summary->namespaces);
 	imapx_store->summary->namespaces = nsl;
 	camel_store_summary_touch ((CamelStoreSummary *) imapx_store->summary);
 
@@ -1639,6 +1667,8 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
 
 					cnt = (camel_folder_summary_count (job->folder->summary) * 100 ) / ifolder->exists_on_server;
 					camel_operation_progress (job->cancellable, cnt ? cnt : 1);
+				} else {
+					camel_message_info_free (mi);
 				}
 
 				if (free_user_flags && server_user_flags)
@@ -4220,13 +4250,7 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
 	isum->uidnext = ifolder->uidnext_on_server;
 
  cleanup:
-	for (i = 0; i < data->infos->len; i++) {
-		struct _refresh_info *r = &g_array_index (data->infos, struct _refresh_info, i);
-
-		camel_flag_list_free (&r->server_user_flags);
-		g_free (r->uid);
-	}
-	g_array_free (data->infos, TRUE);
+	refresh_info_data_infos_free (data);
 
 	imapx_unregister_job (is, job);
 	camel_imapx_command_unref (ic);
@@ -4269,7 +4293,6 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 	CamelSettings *settings;
 	RefreshInfoData *data;
 	guint uidset_size;
-	gint i;
 	gboolean success = TRUE;
 	gboolean mobile_mode;
 
@@ -4425,12 +4448,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 		}
 	}
 
-	for (i = 0; i < data->infos->len; i++) {
-		struct _refresh_info *r = &g_array_index (data->infos, struct _refresh_info, i);
-
-		camel_flag_list_free (&r->server_user_flags);
-		g_free (r->uid);
-	}
+	refresh_info_data_infos_free (data);
 
 	/* There's no sane way to get the server-side unseen count on the
 	 * select mailbox. So just work it out from the flags if its not in
@@ -4440,7 +4458,6 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 	if (!mobile_mode)
 		((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
 
-	g_array_free (data->infos, TRUE);
 	imapx_unregister_job (is, job);
 	camel_imapx_command_unref (ic);
 
@@ -4487,6 +4504,7 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
 
 	data->scan_changes = TRUE;
 	ic->pri = job->pri;
+	refresh_info_data_infos_free (data);
 	data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
 	imapx_command_queue (is, ic);
 	g_free (uid);
@@ -4628,6 +4646,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
 			is, "FETCH", job->folder,
 			"UID FETCH %s:* (UID FLAGS)", uid);
 		imapx_uidset_init (&data->uidset, uidset_size, 0);
+		refresh_info_data_infos_free (data);
 		data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
 		ic->pri = job->pri;
 
@@ -4734,6 +4753,7 @@ imapx_job_fetch_messages_start (CamelIMAPXJob *job,
 			"UID FETCH %s:* (UID FLAGS)", uid);
 
 		imapx_uidset_init (&data->uidset, uidset_size, 0);
+		refresh_info_data_infos_free (data);
 		data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
 		ic->pri = job->pri;
 
@@ -5036,8 +5056,14 @@ imapx_command_expunge_done (CamelIMAPXServer *is,
 			changes = camel_folder_change_info_new ();
 			for (i = 0; i < uids->len; i++) {
 				gchar *uid = uids->pdata[i];
+				CamelMessageInfo *mi;
+
+				mi = camel_folder_summary_get (folder->summary, uid);
+				if (mi) {
+					camel_folder_summary_remove (folder->summary, mi);
+					camel_message_info_free (mi);
+				}
 
-				camel_folder_summary_remove_uid (folder->summary, uid);
 				camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
 				removed = g_list_prepend (removed, (gpointer) uids->pdata[i]);
 			}
@@ -5873,6 +5899,14 @@ imapx_server_finalize (GObject *object)
 	CamelIMAPXServer *is = CAMEL_IMAPX_SERVER (object);
 	CamelIMAPXServerPrivate *priv = CAMEL_IMAPX_SERVER_GET_PRIVATE (is);
 
+	camel_imapx_command_queue_free (is->queue);
+	camel_imapx_command_queue_free (is->active);
+	camel_imapx_command_queue_free (is->done);
+
+	is->queue = NULL;
+	is->active = NULL;
+	is->done = NULL;
+
 	g_static_rec_mutex_free (&is->queue_lock);
 	g_static_rec_mutex_free (&is->ostream_lock);
 	g_mutex_free (is->fetch_mutex);
diff --git a/camel/camel-imapx-store.c b/camel/camel-imapx-store.c
index c38d356..2875649 100644
--- a/camel/camel-imapx-store.c
+++ b/camel/camel-imapx-store.c
@@ -979,12 +979,13 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore,
 			ns = ns->next;
 		}
 	}
-	g_list_free (namespaces);
  out:
+	g_list_free (namespaces);
 	g_object_unref (server);
 	return folders;
 
 exception:
+	g_list_free (namespaces);
 	g_object_unref (server);
 	g_hash_table_destroy (folders);
 	return NULL;



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