changeset 29234:4478ce23487a

If a buddy is deleted less than 11 seconds after they sign on or off, and there is a conversation open with that buddy, the PurpleBuddy will be dereferenced after it has been freed. This avoids that by duplicating the required details from the PurpleBuddy for use in the status_timeout callback.
author Stu Tomlinson <stu@nosnilmot.com>
date Wed, 06 Jan 2010 00:55:08 +0000
parents 5b50c5af48ab
children 5819bf02659e
files pidgin/gtkconv.c
diffstat 1 files changed, 16 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkconv.c	Wed Jan 06 00:48:50 2010 +0000
+++ b/pidgin/gtkconv.c	Wed Jan 06 00:55:08 2010 +0000
@@ -7624,16 +7624,24 @@
 	}
 }
 
+struct _status_timeout_user {
+	gchar *name;
+	PurpleAccount *account;
+};
+
 static gboolean
-update_buddy_status_timeout(PurpleBuddy *buddy)
+update_buddy_status_timeout(struct _status_timeout_user *user)
 {
 	/* To remove the signing-on/off door icon */
 	PurpleConversation *conv;
 
-	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy->name, buddy->account);
+	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, user->name, user->account);
 	if (conv)
 		pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON);
 
+	g_free(user->name);
+	g_free(user);
+
 	return FALSE;
 }
 
@@ -7642,6 +7650,7 @@
 {
 	PidginConversation *gtkconv;
 	PurpleConversation *conv;
+	struct _status_timeout_user *user;
 
 	gtkconv = get_gtkconv_with_contact(purple_buddy_get_contact(buddy));
 	if (gtkconv)
@@ -7654,8 +7663,12 @@
 			pidgin_conv_update_fields(conv, PIDGIN_CONV_MENU);
 	}
 
+	user = g_malloc(sizeof(struct _status_timeout_user));
+	user->name = g_strdup(buddy->name);
+	user->account = buddy->account;
+
 	/* In case a conversation is started after the buddy has signed-on/off */
-	purple_timeout_add_seconds(11, (GSourceFunc)update_buddy_status_timeout, buddy);
+	purple_timeout_add_seconds(11, (GSourceFunc)update_buddy_status_timeout, user);
 }
 
 static void