changeset 23691:c31dfae66134

Hopefully fix the XMPP contact flipping/swapping between groups bug described at http://trac.adiumx.com/ticket/8834 and http://pidgin.im/pipermail/devel/2008-June/006191.html See the comment I added at the top of roster.c for details.
author Mark Doliner <mark@kingant.net>
date Tue, 05 Aug 2008 23:22:36 +0000
parents 0044b8f3727a
children 2ecd716746e6 bfbad8f78ec6
files libpurple/protocols/jabber/roster.c
diffstat 1 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/roster.c	Tue Aug 05 01:43:42 2008 +0000
+++ b/libpurple/protocols/jabber/roster.c	Tue Aug 05 23:22:36 2008 +0000
@@ -31,6 +31,36 @@
 
 #include <string.h>
 
+/*
+ * This boolean was added to eliminate a heinous bug where we would
+ * get into a loop with the server and move a buddy back and forth
+ * from one group to another.
+ *
+ * The sequence goes something like this:
+ * 1. Our resource and another resource both approve an authorization
+ *    request at the exact same time.  We put the buddy in group A and
+ *    the other resource put the buddy in group B.
+ * 2. The server receives the roster add for group B and sends us a
+ *    roster push.
+ * 3. We receive this roster push and modify our local blist.  This
+ *    triggers us to send a roster add for group B.
+ * 4. The server recieves our earlier roster add for group A and sends
+ *    us a roster push.
+ * 5. We receive this roster push and modify our local blist.  This
+ *    triggers us to send a roster add for group A.
+ * 6. The server receives our earlier roster add for group B and sends
+ *    us a roster push.
+ * (repeat steps 3 through 6 ad infinitum)
+ *
+ * This boolean is used to short-circuit the sending of a roster add
+ * when we receive a roster push.
+ *
+ * See these bug reports:
+ * http://trac.adiumx.com/ticket/8834
+ * http://developer.pidgin.im/ticket/5484
+ * http://developer.pidgin.im/ticket/6188
+ */
+static gboolean parsing_from_server = FALSE;
 
 void jabber_roster_request(JabberStream *js)
 {
@@ -169,6 +199,8 @@
 	if(!query)
 		return;
 
+	parsing_from_server = TRUE;
+
 	for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item))
 	{
 		const char *jid, *name, *subscription, *ask;
@@ -251,6 +283,8 @@
 		}
 	}
 
+	parsing_from_server = FALSE;
+
 	/* if we're just now parsing the roster for the first time,
 	 * then now would be the time to send our initial presence */
 	if(!js->roster_parsed) {
@@ -269,6 +303,9 @@
 	JabberIq *iq;
 	xmlnode *query, *item, *group;
 
+	if (parsing_from_server)
+		return;
+
 	if(!(b = purple_find_buddy(js->gc->account, name)))
 		return;