# HG changeset patch # User jch@honig.net # Date 1293671163 0 # Node ID e023b0378887ccd5f722aaff3b36e87b2285ab7f # Parent 40e5d8c3accaa902013c37351b6ea9cd6e5d3153 Prevent sending ISON messages larger than 512 bytes. Fixes #9692. committer: John Bailey diff -r 40e5d8c3acca -r e023b0378887 COPYRIGHT --- a/COPYRIGHT Thu Dec 30 00:58:17 2010 +0000 +++ b/COPYRIGHT Thu Dec 30 01:06:03 2010 +0000 @@ -223,6 +223,7 @@ Andrew Hoffman Iain Holmes Joshua Honeycutt +Jeffrey Honig Nigel Horne Jensen Hornick Juanjo Molinero Horno diff -r 40e5d8c3acca -r e023b0378887 ChangeLog --- a/ChangeLog Thu Dec 30 00:58:17 2010 +0000 +++ b/ChangeLog Thu Dec 30 01:06:03 2010 +0000 @@ -1,6 +1,9 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 2.7.10 (??/??/????): + IRC: + * Don't send ISON messages longer than 512 bytes. (Jeffrey Honig) (#9692) + libpurple: * Stop sending audio when placing a call on hold. (Jakub Adam) (#13032) * Stop translating gpointers to ints in the dbus API. This removes diff -r 40e5d8c3acca -r e023b0378887 libpurple/protocols/irc/irc.c --- a/libpurple/protocols/irc/irc.c Thu Dec 30 00:58:17 2010 +0000 +++ b/libpurple/protocols/irc/irc.c Thu Dec 30 01:06:03 2010 +0000 @@ -39,7 +39,7 @@ #define PING_TIMEOUT 60 -static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string); +static void irc_ison_buddy_init(char *name, struct irc_buddy *ib, GList **list); static const char *irc_blist_icon(PurpleAccount *a, PurpleBuddy *b); static GList *irc_status_types(PurpleAccount *account); @@ -186,43 +186,62 @@ /* XXX I don't like messing directly with these buddies */ gboolean irc_blist_timeout(struct irc_conn *irc) { - GString *string; - char *list, *buf; - - if (irc->ison_outstanding) - return TRUE; - - string = g_string_sized_new(512); - - g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_append, (gpointer)string); - - list = g_string_free(string, FALSE); - if (!list || !strlen(list)) { - g_free(list); + if (irc->ison_outstanding) { return TRUE; } - buf = irc_format(irc, "vn", "ISON", list); - g_free(list); - irc_send(irc, buf); - g_free(buf); + g_hash_table_foreach(irc->buddies, (GHFunc)irc_ison_buddy_init, + (gpointer *)&irc->buddies_outstanding); - irc->ison_outstanding = TRUE; + irc_buddy_query(irc); return TRUE; } -static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string) +void irc_buddy_query(struct irc_conn *irc) { - ib->flag = FALSE; - g_string_append_printf(string, "%s ", name); + GList *lp; + GString *string; + struct irc_buddy *ib; + char *buf; + + string = g_string_sized_new(512); + + while ((lp = g_list_first(irc->buddies_outstanding))) { + ib = (struct irc_buddy *)lp->data; + if (string->len + strlen(ib->name) + 1 > 450) + break; + g_string_append_printf(string, "%s ", ib->name); + ib->new_online_status = FALSE; + irc->buddies_outstanding = g_list_remove_link(irc->buddies_outstanding, lp); + } + + if (string->len) { + buf = irc_format(irc, "vn", "ISON", string->str); + irc_send(irc, buf); + g_free(buf); + irc->ison_outstanding = TRUE; + } else + irc->ison_outstanding = FALSE; + + g_string_free(string, TRUE); +} + +static void irc_ison_buddy_init(char *name, struct irc_buddy *ib, GList **list) +{ + *list = g_list_append(*list, ib); } static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) { char *buf; - ib->flag = FALSE; + if (irc->buddies_outstanding != NULL) { + irc->buddies_outstanding = g_list_append(irc->buddies_outstanding, ib); + return; + } + + ib->new_online_status = FALSE; buf = irc_format(irc, "vn", "ISON", ib->name); irc_send(irc, buf); g_free(buf); diff -r 40e5d8c3acca -r e023b0378887 libpurple/protocols/irc/irc.h --- a/libpurple/protocols/irc/irc.h Thu Dec 30 00:58:17 2010 +0000 +++ b/libpurple/protocols/irc/irc.h Thu Dec 30 01:06:03 2010 +0000 @@ -58,6 +58,7 @@ GHashTable *buddies; gboolean ison_outstanding; + GList *buddies_outstanding; char *inbuf; int inbuflen; @@ -97,6 +98,7 @@ char *name; gboolean online; gboolean flag; + gboolean new_online_status; int ref; }; @@ -104,6 +106,7 @@ int irc_send(struct irc_conn *irc, const char *buf); gboolean irc_blist_timeout(struct irc_conn *irc); +void irc_buddy_query(struct irc_conn *irc); char *irc_escape_privmsg(const char *text, gssize length); diff -r 40e5d8c3acca -r e023b0378887 libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Thu Dec 30 00:58:17 2010 +0000 +++ b/libpurple/protocols/irc/msgs.c Thu Dec 30 01:06:03 2010 +0000 @@ -761,18 +761,19 @@ return; nicks = g_strsplit(args[1], " ", -1); - for (i = 0; nicks[i]; i++) { if ((ib = g_hash_table_lookup(irc->buddies, (gconstpointer)nicks[i])) == NULL) { continue; } - ib->flag = TRUE; + ib->new_online_status = TRUE; } - g_strfreev(nicks); - g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_status, (gpointer)irc); - irc->ison_outstanding = FALSE; + if (irc->ison_outstanding) + irc_buddy_query(irc); + + if (!irc->ison_outstanding) + g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_status, (gpointer)irc); } static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc) @@ -783,10 +784,10 @@ if (!gc || !buddy) return; - if (ib->online && !ib->flag) { + if (ib->online && !ib->new_online_status) { purple_prpl_got_user_status(irc->account, name, "offline", NULL); ib->online = FALSE; - } else if (!ib->online && ib->flag) { + } else if (!ib->online && ib->new_online_status) { purple_prpl_got_user_status(irc->account, name, "available", NULL); ib->online = TRUE; } @@ -837,7 +838,7 @@ purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), nick, userhost, PURPLE_CBFLAGS_NONE, TRUE); if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) { - ib->flag = TRUE; + ib->new_online_status = TRUE; irc_buddy_status(nick, ib, irc); } @@ -1233,7 +1234,7 @@ g_slist_foreach(gc->buddy_chats, (GFunc)irc_chat_remove_buddy, data); if ((ib = g_hash_table_lookup(irc->buddies, data[0])) != NULL) { - ib->flag = FALSE; + ib->new_online_status = FALSE; irc_buddy_status(data[0], ib, irc); } g_free(data[0]);