From edba1f4d52801faa62f799c87ca35f05f891ac23 Mon Sep 17 00:00:00 2001
From: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
Date: Thu, 8 Sep 2011 16:33:33 -0400
Subject: [PATCH] * #6893: fixes segfault in client on clean history

Caused by double free.
---
 gnome/src/callable_obj.c      |  2 +-
 gnome/src/contacts/calllist.c | 63 +++++++++++++++++------------------
 2 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/gnome/src/callable_obj.c b/gnome/src/callable_obj.c
index 16fa869d53..79b2e1647d 100644
--- a/gnome/src/callable_obj.c
+++ b/gnome/src/callable_obj.c
@@ -177,7 +177,7 @@ callable_obj_t *create_history_entry_from_serialized_form (const gchar *entry)
     gint token;
     for (ptr = ptr_orig, token = 0; ptr && token < 10; token++, ptr++)
         switch (token) {
-            case 0:     history_state = get_history_state_from_id (*ptr); break;
+            case 0:     history_state = get_history_state_from_id(*ptr); break;
             case 1:     peer_number = *ptr;     break;
             case 2:     peer_name = *ptr;       break;
             case 3:     time_start = *ptr;      break;
diff --git a/gnome/src/contacts/calllist.c b/gnome/src/contacts/calllist.c
index 3cd3cbcc47..ff0bb05d45 100644
--- a/gnome/src/contacts/calllist.c
+++ b/gnome/src/contacts/calllist.c
@@ -90,7 +90,7 @@ calllist_free_element(gpointer data, gpointer user_data UNUSED)
         free_conference_obj_t (element->elem.conf);
     else /* HIST_CALL */
         free_callable_obj_t (element->elem.call);
-    free (element);
+    g_free (element);
 }
 
 void
@@ -110,9 +110,9 @@ calllist_reset (calltab_t* tab)
 void calllist_add_history_call (callable_obj_t *obj)
 {
     if (eel_gconf_get_integer (HISTORY_ENABLED)) {
-        QueueElement *element = malloc(sizeof(QueueElement));
-	element->type = HIST_CALL;
-	element->elem.call = obj;  
+        QueueElement *element = g_new0(QueueElement, 1);
+        element->type = HIST_CALL;
+        element->elem.call = obj;
         g_queue_push_tail (history->callQueue, (gpointer) element);
         calltree_add_call (history, obj, NULL);
     }
@@ -121,11 +121,11 @@ void calllist_add_history_call (callable_obj_t *obj)
 void calllist_add_history_conference(conference_obj_t *obj)
 {
     if(eel_gconf_get_integer (HISTORY_ENABLED)) {
-        QueueElement *element = malloc(sizeof(QueueElement));
-	element->type = HIST_CONFERENCE;
-	element->elem.conf = obj;
+        QueueElement *element = g_new0(QueueElement, 1);
+        element->type = HIST_CONFERENCE;
+        element->elem.conf = obj;
         g_queue_push_tail (history->callQueue, (gpointer) element);
-	calltree_add_conference (history, obj);
+        calltree_add_conference (history, obj);
     }
 }
 
@@ -134,25 +134,22 @@ calllist_add_call (calltab_t* tab, callable_obj_t * c)
 {
     DEBUG("Calllist: Add Call %s", c->_callID);
 
-    QueueElement *element = malloc(sizeof(QueueElement));
+    QueueElement *element = g_new0(QueueElement, 1);
     element->type = HIST_CALL;
     element->elem.call = c;
-    g_queue_push_tail (tab->callQueue, (gpointer) element);
+    g_queue_push_tail(tab->callQueue, (gpointer) element);
 }
 
 void
 calllist_clean_history (void)
 {
     guint size = calllist_get_size (history);
-    for (guint i = 0 ; i < size; i++) {
-        QueueElement* c = calllist_get_nth (history , i);
-	if(c->type == HIST_CALL) {
+    for (guint i = 0; i < size; i++) {
+        QueueElement* c = calllist_get_nth(history, i);
+        if (c->type == HIST_CALL)
             calltree_remove_call (history, c->elem.call, NULL);
-        }
-	else if(c->type == HIST_CONFERENCE) {
-	    calltree_remove_conference (history, c->elem.conf, NULL);
-	}
-    	free(c);
+        else if(c->type == HIST_CONFERENCE)
+            calltree_remove_conference (history, c->elem.conf, NULL);
     }
 
     calllist_reset (history);
@@ -161,8 +158,8 @@ calllist_clean_history (void)
 void
 calllist_remove_from_history (callable_obj_t* c)
 {
-    calllist_remove_call (history, c->_callID);
-    calltree_remove_call (history, c, NULL);
+    calllist_remove_call(history, c->_callID);
+    calltree_remove_call(history, c, NULL);
 }
 
 void
@@ -171,28 +168,28 @@ calllist_remove_call (calltab_t* tab, const gchar * callID)
     DEBUG("CallList: Remove call %s from list", callID);
 
     GList *c = g_queue_find_custom (tab->callQueue, callID, is_callID_callstruct);
-    if(c == NULL) {
+    if (c == NULL) {
         DEBUG("CallList: Could not remove call %s", callID);
     	return;
     }
 
     QueueElement *element = (QueueElement *)c->data;
-    if(element->type != HIST_CALL) {
+    if (element->type != HIST_CALL) {
         ERROR("CallList: Error: Element %s is not a call", callID);
         return;
     }
 
-    g_queue_remove (tab->callQueue, element);
+    g_queue_remove(tab->callQueue, element);
 
-    calllist_add_call (history, element->elem.call);
-    calltree_add_call (history, element->elem.call, NULL);
+    calllist_add_call(history, element->elem.call);
+    calltree_add_call(history, element->elem.call, NULL);
 }
 
 
 callable_obj_t *
-calllist_get_by_state (calltab_t* tab, call_state_t state)
+calllist_get_by_state(calltab_t* tab, call_state_t state)
 {
-    GList * c = g_queue_find_custom (tab->callQueue, &state, get_state_callstruct);
+    GList * c = g_queue_find_custom(tab->callQueue, &state, get_state_callstruct);
     return c ? c->data : NULL;
 }
 
@@ -212,17 +209,17 @@ callable_obj_t *
 calllist_get_call (calltab_t* tab, const gchar * callID)
 {
     DEBUG("CallList: Get call: %s", callID);
-    
+
     GList * c = g_queue_find_custom (tab->callQueue, callID, is_callID_callstruct);
-    if(c == NULL) {
-	ERROR("CallList: Error: Could not find call %s", callID);
+    if (c == NULL) {
+        ERROR("CallList: Error: Could not find call %s", callID);
         return NULL;
     }
 
     QueueElement *element = c->data;
-    if(element->type != HIST_CALL) {
-	ERROR("CallList: Error: Element %s is not a call", callID);
-	return NULL;
+    if (element->type != HIST_CALL) {
+        ERROR("CallList: Error: Element %s is not a call", callID);
+        return NULL;
     }
 
     return element->elem.call;
-- 
GitLab