Mercurial > pidgin
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) |