# HG changeset patch # User matthew@bells23.org.uk # Date 1304398920 0 # Node ID b2f6fec7b98e40105dd1aa5a7b9a68980c6f789f # Parent db082e0421f6d161e3cfff6356127666fd70cd68 jabber: Correctly handle the unsetting case for a contact's vCard avatar. Patch from Matthew (mentor) W.S. Bell. Closes #13370 committer: Paul Aurich diff -r db082e0421f6 -r b2f6fec7b98e COPYRIGHT --- a/COPYRIGHT Tue May 03 02:26:35 2011 +0000 +++ b/COPYRIGHT Tue May 03 05:02:00 2011 +0000 @@ -48,6 +48,7 @@ Stefan Becker Carlos Bederian Dave Bell +Matthew W.S. Bell Igor Belyi David Benjamin Brian Bernas diff -r db082e0421f6 -r b2f6fec7b98e ChangeLog --- a/ChangeLog Tue May 03 02:26:35 2011 +0000 +++ b/ChangeLog Tue May 03 05:02:00 2011 +0000 @@ -86,6 +86,8 @@ XMPP: * Remember the previously entered user directory when searching. (Keith Moyer) (#12451) + * Correctly handle a buddy's unsetting his/her vCard-based avatar. + (Matthew W.S. Bell) (#13370) Plugins: * The Voice/Video Settings plugin now includes the ability to test diff -r db082e0421f6 -r b2f6fec7b98e libpurple/protocols/jabber/presence.c --- a/libpurple/protocols/jabber/presence.c Tue May 03 02:26:35 2011 +0000 +++ b/libpurple/protocols/jabber/presence.c Tue May 03 05:02:00 2011 +0000 @@ -450,21 +450,23 @@ g_free(nickname); } - if ((photo = xmlnode_get_child(vcard, "PHOTO")) && - (binval = xmlnode_get_child(photo, "BINVAL")) && - (text = xmlnode_get_data(binval))) { - guchar *data; - gsize size; + if ((photo = xmlnode_get_child(vcard, "PHOTO"))) { + guchar *data = NULL; + gchar *hash = NULL; + gsize size = 0; - data = purple_base64_decode(text, &size); - if (data) { - gchar *hash = jabber_calculate_data_hash(data, size, "sha1"); - purple_buddy_icons_set_for_user(js->gc->account, from, data, - size, hash); - g_free(hash); + if ((binval = xmlnode_get_child(photo, "BINVAL")) && + (text = xmlnode_get_data(binval))) { + data = purple_base64_decode(text, &size); + g_free(text); + + if (data) + hash = jabber_calculate_data_hash(data, size, "sha1"); } - g_free(text); + purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash); + + g_free(hash); } } } @@ -840,20 +842,22 @@ } } - if(b && presence->vcard_avatar_hash) { - const char *avatar_hash2 = purple_buddy_icons_get_checksum_for_user(b); - if(!avatar_hash2 || strcmp(presence->vcard_avatar_hash, avatar_hash2)) { - JabberIq *iq; - xmlnode *vcard; - + if (b && presence->vcard_avatar_hash) { + const char *ah = presence->vcard_avatar_hash[0] != '\0' ? + presence->vcard_avatar_hash : NULL; + const char *ah2 = purple_buddy_icons_get_checksum_for_user(b); + if (!purple_strequal(ah, ah2)) { /* XXX this is a crappy way of trying to prevent * someone from spamming us with presence packets * and causing us to DoS ourselves...what we really * need is a queue system that can throttle itself, * but i'm too tired to write that right now */ if(!g_slist_find(js->pending_avatar_requests, presence->jb)) { + JabberIq *iq; + xmlnode *vcard; - js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, presence->jb); + js->pending_avatar_requests = + g_slist_prepend(js->pending_avatar_requests, presence->jb); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", buddy_name); @@ -1206,9 +1210,13 @@ parse_vcard_avatar(JabberStream *js, JabberPresence *presence, xmlnode *x) { xmlnode *photo = xmlnode_get_child(x, "photo"); + char *hash_tmp; + if (photo) { g_free(presence->vcard_avatar_hash); - presence->vcard_avatar_hash = xmlnode_get_data(photo); + hash_tmp = xmlnode_get_data(photo); + presence->vcard_avatar_hash = + hash_tmp ? hash_tmp : g_strdup(""); } }