changeset 31978:b2f6fec7b98e

jabber: Correctly handle the unsetting case for a contact's vCard avatar. Patch from Matthew (mentor) W.S. Bell. Closes #13370 committer: Paul Aurich <paul@darkrain42.org>
author matthew@bells23.org.uk
date Tue, 03 May 2011 05:02:00 +0000
parents db082e0421f6
children c832d481d021
files COPYRIGHT ChangeLog libpurple/protocols/jabber/presence.c
diffstat 3 files changed, 31 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
--- 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("");
 	}
 }