changeset 16833:52c776782b95

Protect icon with ref/unref guards since it may be freed over the course of the while() loop. I thought this would fix #398, but something else is wrong, too.
author Evan Schoenberg <evan.s@dreskin.net>
date Thu, 03 May 2007 17:50:36 +0000
parents 844ed0418744
children f0b4efc4a83a
files libpurple/buddyicon.c
diffstat 1 files changed, 9 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/buddyicon.c	Thu May 03 17:43:07 2007 +0000
+++ b/libpurple/buddyicon.c	Thu May 03 17:50:36 2007 +0000
@@ -379,13 +379,16 @@
 	account  = purple_buddy_icon_get_account(icon);
 	username = purple_buddy_icon_get_username(icon);
 
-	/* If no data exists, then call the functions below with NULL to
-	 * unset the icon.  They will then unref the icon and it should be
-	 * destroyed.  The only way it wouldn't be destroyed is if someone
+	/* If no data exists (icon->img == NULL), then call the functions below
+	 * with NULL to unset the icon.  They will then unref the icon and it should
+	 * be destroyed.  The only way it wouldn't be destroyed is if someone
 	 * else is holding a reference to it, in which case they can kill
 	 * the icon when they realize it has no data. */
 	icon_to_set = icon->img ? icon : NULL;
 
+	/* Ensure that icon remains valid throughout */
+	if (icon) purple_buddy_icon_ref(icon);
+
 	buddies = purple_find_buddies(account, username);
 	while (buddies != NULL)
 	{
@@ -393,7 +396,6 @@
 		char *old_icon;
 
 		purple_buddy_set_icon(buddy, icon_to_set);
-
 		old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy,
 		                                                 "buddy_icon"));
 		if (icon->img && purple_buddy_icons_is_caching())
@@ -431,6 +433,9 @@
 
 	if (conv != NULL)
 		purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set);
+	
+	/* icon's refcount was incremented above */
+	if (icon) purple_buddy_icon_unref(icon);
 }
 
 void