summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Aurich <darkrain42@pidgin.im>2009-05-06 18:58:47 +0000
committerPaul Aurich <darkrain42@pidgin.im>2009-05-06 18:58:47 +0000
commit2fa4a665db95966f008d49a28144251ce176ee83 (patch)
treefa92b2b13911f49f1e72bd6de02dc7a4d45c0445
parentfb0fc32e19557c694255c8edbe3c1de7e1eb40c6 (diff)
downloadpidgin-2fa4a665db95966f008d49a28144251ce176ee83.tar.gz
Fix the crash/leaks in statusbox
*** Plucked rev 0cb6e54b (darkrain42@pidgin.im): Look up the old image before we store the new one in the hash table. Looking up the new image and then unref:ing it (hence freeing the data and subsequently returning it) is not good. This was causing problems with changing buddy icons while using mystatusbox. Refs #9120. *** Plucked rev d25c9ed7 (darkrain42@pidgin.im): Don't leak image refs in gtkstatusbox and assertion failure in nullprpl purple_imgstore_new_from_file gives us a ref and pidgin_status_box_set_buddy_icon also takes a ref.
-rw-r--r--libpurple/buddyicon.c4
-rw-r--r--libpurple/protocols/null/nullprpl.c3
-rw-r--r--pidgin/gtkstatusbox.c35
3 files changed, 23 insertions, 19 deletions
diff --git a/libpurple/buddyicon.c b/libpurple/buddyicon.c
index f2567744a6..4f636c08c9 100644
--- a/libpurple/buddyicon.c
+++ b/libpurple/buddyicon.c
@@ -753,6 +753,8 @@ purple_buddy_icons_set_account_icon(PurpleAccount *account,
}
unref_filename(old_icon);
+ old_img = g_hash_table_lookup(pointer_icon_cache, account);
+
if (img)
g_hash_table_insert(pointer_icon_cache, account, img);
else
@@ -770,7 +772,7 @@ purple_buddy_icons_set_account_icon(PurpleAccount *account,
prpl_info->set_buddy_icon(gc, img);
}
- if ((old_img = g_hash_table_lookup(pointer_icon_cache, account)))
+ if (old_img)
purple_imgstore_unref(old_img);
else if (old_icon)
{
diff --git a/libpurple/protocols/null/nullprpl.c b/libpurple/protocols/null/nullprpl.c
index 6515b56865..74caa49565 100644
--- a/libpurple/protocols/null/nullprpl.c
+++ b/libpurple/protocols/null/nullprpl.c
@@ -927,7 +927,8 @@ static const char *nullprpl_normalize(const PurpleAccount *acct,
static void nullprpl_set_buddy_icon(PurpleConnection *gc,
PurpleStoredImage *img) {
purple_debug_info("nullprpl", "setting %s's buddy icon to %s\n",
- gc->account->username, purple_imgstore_get_filename(img));
+ gc->account->username,
+ img ? purple_imgstore_get_filename(img) : "(null)");
}
static void nullprpl_remove_group(PurpleConnection *gc, PurpleGroup *group) {
diff --git a/pidgin/gtkstatusbox.c b/pidgin/gtkstatusbox.c
index 53760b468a..94fcd50640 100644
--- a/pidgin/gtkstatusbox.c
+++ b/pidgin/gtkstatusbox.c
@@ -417,16 +417,15 @@ setup_icon_box(PidginStatusBox *status_box)
PurpleStoredImage *img = NULL;
if (filename != NULL)
- {
- gchar *contents;
- gsize size;
- if (g_file_get_contents(filename, &contents, &size, NULL))
- {
- img = purple_imgstore_add(contents, size, filename);
- }
- }
+ img = purple_imgstore_new_from_file(filename);
pidgin_status_box_set_buddy_icon(status_box, img);
+ if (img)
+ /*
+ * purple_imgstore_new gives us a reference and
+ * pidgin_status_box_set_buddy_icon also takes one.
+ */
+ purple_imgstore_unref(img);
}
status_box->hand_cursor = gdk_cursor_new (GDK_HAND2);
@@ -1496,6 +1495,13 @@ buddy_icon_set_cb(const char *filename, PidginStatusBox *box)
if (filename)
data = pidgin_convert_buddy_icon(plug, filename, &len);
img = purple_buddy_icons_set_account_icon(box->account, data, len);
+ if (img)
+ /*
+ * set_account_icon doesn't give us a reference, but we
+ * unref one below (for the other code path)
+ */
+ purple_imgstore_ref(img);
+
purple_account_set_buddy_icon_path(box->account, filename);
purple_account_set_bool(box->account, "use-global-buddyicon", (filename != NULL));
@@ -1515,7 +1521,7 @@ buddy_icon_set_cb(const char *filename, PidginStatusBox *box)
size_t len = 0;
if (filename)
data = pidgin_convert_buddy_icon(plug, filename, &len);
- img = purple_buddy_icons_set_account_icon(account, data, len);
+ purple_buddy_icons_set_account_icon(account, data, len);
purple_account_set_buddy_icon_path(account, filename);
}
}
@@ -1523,17 +1529,12 @@ buddy_icon_set_cb(const char *filename, PidginStatusBox *box)
/* Even if no accounts were processed, load the icon that was set. */
if (filename != NULL)
- {
- gchar *contents;
- gsize size;
- if (g_file_get_contents(filename, &contents, &size, NULL))
- {
- img = purple_imgstore_add(contents, size, filename);
- }
- }
+ img = purple_imgstore_new_from_file(filename);
}
pidgin_status_box_set_buddy_icon(box, img);
+ if (img)
+ purple_imgstore_unref(img);
}
static void