comparison libpurple/buddyicon.c @ 16822: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 9862a82206ba
comparison
equal deleted inserted replaced
16821:844ed0418744 16822:52c776782b95
377 g_return_if_fail(icon != NULL); 377 g_return_if_fail(icon != NULL);
378 378
379 account = purple_buddy_icon_get_account(icon); 379 account = purple_buddy_icon_get_account(icon);
380 username = purple_buddy_icon_get_username(icon); 380 username = purple_buddy_icon_get_username(icon);
381 381
382 /* If no data exists, then call the functions below with NULL to 382 /* If no data exists (icon->img == NULL), then call the functions below
383 * unset the icon. They will then unref the icon and it should be 383 * with NULL to unset the icon. They will then unref the icon and it should
384 * destroyed. The only way it wouldn't be destroyed is if someone 384 * be destroyed. The only way it wouldn't be destroyed is if someone
385 * else is holding a reference to it, in which case they can kill 385 * else is holding a reference to it, in which case they can kill
386 * the icon when they realize it has no data. */ 386 * the icon when they realize it has no data. */
387 icon_to_set = icon->img ? icon : NULL; 387 icon_to_set = icon->img ? icon : NULL;
388 388
389 /* Ensure that icon remains valid throughout */
390 if (icon) purple_buddy_icon_ref(icon);
391
389 buddies = purple_find_buddies(account, username); 392 buddies = purple_find_buddies(account, username);
390 while (buddies != NULL) 393 while (buddies != NULL)
391 { 394 {
392 PurpleBuddy *buddy = (PurpleBuddy *)buddies->data; 395 PurpleBuddy *buddy = (PurpleBuddy *)buddies->data;
393 char *old_icon; 396 char *old_icon;
394 397
395 purple_buddy_set_icon(buddy, icon_to_set); 398 purple_buddy_set_icon(buddy, icon_to_set);
396
397 old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy, 399 old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy,
398 "buddy_icon")); 400 "buddy_icon"));
399 if (icon->img && purple_buddy_icons_is_caching()) 401 if (icon->img && purple_buddy_icons_is_caching())
400 { 402 {
401 const char *filename = purple_imgstore_get_filename(icon->img); 403 const char *filename = purple_imgstore_get_filename(icon->img);
429 431
430 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account); 432 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);
431 433
432 if (conv != NULL) 434 if (conv != NULL)
433 purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set); 435 purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set);
436
437 /* icon's refcount was incremented above */
438 if (icon) purple_buddy_icon_unref(icon);
434 } 439 }
435 440
436 void 441 void
437 purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data, 442 purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data,
438 size_t len, const char *checksum) 443 size_t len, const char *checksum)