* #6893: fixes segfault in client on clean history

Caused by double free.
This commit is contained in:
Tristan Matthews
2011-09-08 16:33:33 -04:00
parent 26db78d840
commit edba1f4d52
2 changed files with 31 additions and 34 deletions

View File

@ -177,7 +177,7 @@ callable_obj_t *create_history_entry_from_serialized_form (const gchar *entry)
gint token; gint token;
for (ptr = ptr_orig, token = 0; ptr && token < 10; token++, ptr++) for (ptr = ptr_orig, token = 0; ptr && token < 10; token++, ptr++)
switch (token) { 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 1: peer_number = *ptr; break;
case 2: peer_name = *ptr; break; case 2: peer_name = *ptr; break;
case 3: time_start = *ptr; break; case 3: time_start = *ptr; break;

View File

@ -90,7 +90,7 @@ calllist_free_element(gpointer data, gpointer user_data UNUSED)
free_conference_obj_t (element->elem.conf); free_conference_obj_t (element->elem.conf);
else /* HIST_CALL */ else /* HIST_CALL */
free_callable_obj_t (element->elem.call); free_callable_obj_t (element->elem.call);
free (element); g_free (element);
} }
void void
@ -110,9 +110,9 @@ calllist_reset (calltab_t* tab)
void calllist_add_history_call (callable_obj_t *obj) void calllist_add_history_call (callable_obj_t *obj)
{ {
if (eel_gconf_get_integer (HISTORY_ENABLED)) { if (eel_gconf_get_integer (HISTORY_ENABLED)) {
QueueElement *element = malloc(sizeof(QueueElement)); QueueElement *element = g_new0(QueueElement, 1);
element->type = HIST_CALL; element->type = HIST_CALL;
element->elem.call = obj; element->elem.call = obj;
g_queue_push_tail (history->callQueue, (gpointer) element); g_queue_push_tail (history->callQueue, (gpointer) element);
calltree_add_call (history, obj, NULL); 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) void calllist_add_history_conference(conference_obj_t *obj)
{ {
if(eel_gconf_get_integer (HISTORY_ENABLED)) { if(eel_gconf_get_integer (HISTORY_ENABLED)) {
QueueElement *element = malloc(sizeof(QueueElement)); QueueElement *element = g_new0(QueueElement, 1);
element->type = HIST_CONFERENCE; element->type = HIST_CONFERENCE;
element->elem.conf = obj; element->elem.conf = obj;
g_queue_push_tail (history->callQueue, (gpointer) element); 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); DEBUG("Calllist: Add Call %s", c->_callID);
QueueElement *element = malloc(sizeof(QueueElement)); QueueElement *element = g_new0(QueueElement, 1);
element->type = HIST_CALL; element->type = HIST_CALL;
element->elem.call = c; element->elem.call = c;
g_queue_push_tail (tab->callQueue, (gpointer) element); g_queue_push_tail(tab->callQueue, (gpointer) element);
} }
void void
calllist_clean_history (void) calllist_clean_history (void)
{ {
guint size = calllist_get_size (history); guint size = calllist_get_size (history);
for (guint i = 0 ; i < size; i++) { for (guint i = 0; i < size; i++) {
QueueElement* c = calllist_get_nth (history , i); QueueElement* c = calllist_get_nth(history, i);
if(c->type == HIST_CALL) { if (c->type == HIST_CALL)
calltree_remove_call (history, c->elem.call, NULL); calltree_remove_call (history, c->elem.call, NULL);
} else if(c->type == HIST_CONFERENCE)
else if(c->type == HIST_CONFERENCE) { calltree_remove_conference (history, c->elem.conf, NULL);
calltree_remove_conference (history, c->elem.conf, NULL);
}
free(c);
} }
calllist_reset (history); calllist_reset (history);
@ -161,8 +158,8 @@ calllist_clean_history (void)
void void
calllist_remove_from_history (callable_obj_t* c) calllist_remove_from_history (callable_obj_t* c)
{ {
calllist_remove_call (history, c->_callID); calllist_remove_call(history, c->_callID);
calltree_remove_call (history, c, NULL); calltree_remove_call(history, c, NULL);
} }
void void
@ -171,28 +168,28 @@ calllist_remove_call (calltab_t* tab, const gchar * callID)
DEBUG("CallList: Remove call %s from list", callID); DEBUG("CallList: Remove call %s from list", callID);
GList *c = g_queue_find_custom (tab->callQueue, callID, is_callID_callstruct); 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); DEBUG("CallList: Could not remove call %s", callID);
return; return;
} }
QueueElement *element = (QueueElement *)c->data; 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); ERROR("CallList: Error: Element %s is not a call", callID);
return; return;
} }
g_queue_remove (tab->callQueue, element); g_queue_remove(tab->callQueue, element);
calllist_add_call (history, element->elem.call); calllist_add_call(history, element->elem.call);
calltree_add_call (history, element->elem.call, NULL); calltree_add_call(history, element->elem.call, NULL);
} }
callable_obj_t * 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; return c ? c->data : NULL;
} }
@ -212,17 +209,17 @@ callable_obj_t *
calllist_get_call (calltab_t* tab, const gchar * callID) calllist_get_call (calltab_t* tab, const gchar * callID)
{ {
DEBUG("CallList: Get call: %s", callID); DEBUG("CallList: Get call: %s", callID);
GList * c = g_queue_find_custom (tab->callQueue, callID, is_callID_callstruct); GList * c = g_queue_find_custom (tab->callQueue, callID, is_callID_callstruct);
if(c == NULL) { if (c == NULL) {
ERROR("CallList: Error: Could not find call %s", callID); ERROR("CallList: Error: Could not find call %s", callID);
return NULL; return NULL;
} }
QueueElement *element = c->data; QueueElement *element = c->data;
if(element->type != HIST_CALL) { if (element->type != HIST_CALL) {
ERROR("CallList: Error: Element %s is not a call", callID); ERROR("CallList: Error: Element %s is not a call", callID);
return NULL; return NULL;
} }
return element->elem.call; return element->elem.call;