--- a/ChangeLog Mon Jan 20 07:39:26 2014 +0530
+++ b/ChangeLog Mon Jan 20 00:02:17 2014 -0800
@@ -67,30 +67,80 @@
Python 3. (Ashish Gupta) (#15624)
+ * Fix potential crash if libpurple gets an error attempting to read a + reply from a STUN server. (Discovered by Coverity static analysis) + * Fix potential crash parsing a malformed HTTP response. (Discovered by + Jacob Appelbaum of the Tor Project) (CVE-2013-6479) + * Fix buffer overflow when parsing a malformed HTTP response with + chunked Transfer-Encoding. (Discovered by Matt Jones, Volvent) + * Better handling of HTTP proxy responses with negative Content-Lengths. + (Discovered by Matt Jones, Volvent) * Fix handling of SSL certificates without subjects when using libnss.
* Fix handling of SSL certificates with timestamps in the distant future
when using libnss. (#15586)
+ * Impose maximum download size for all HTTP fetches. + * Fix crash displaying tooltip of long URLs. (CVE-2013-6478) * Better handling of URLs longer than 1000 letters.
* Fix handling of multibyte UTF-8 characters in smiley themes. (#15756)
Windows-Specific Changes:
+ * When clicking file:// links, show the file in Explorer rather than + attempting to run the file. This reduces the chances of a user + clicking on a link and mistakenly running a malicious file. + (Originally discovered by James Burton, Insomnia Security. Rediscovered + by Yves Younan of Sourcefire VRT.) (CVE-2013-6486) * Fix Tcl scripts. (#15520)
* Fix crash-on-startup when ASLR is always on. (#15521)
* Updates to dependencies:
- * NSS 3.15.3 and NSPR 4.10.2
+ * NSS 3.15.4 and NSPR 4.10.2 + * Fix untrusted certificate error. + * Fix a possible crash when receiving a malformed message in a Direct IM + * Fix buffer overflow with remote code execution potential. Only + triggerable by a Gadu-Gadu server or a man-in-the-middle. + (Discovered by Yves Younan and Ryan Pentney of Sourcefire VRT) * Disabled buddy list import/export from/to server (it didn't work
anymore). Buddy list synchronization will be implemented in 3.0.0.
+ * Disabled new account registration and password change options, as it + didn't work either. Account registration also caused a crash. Both + functions are available using official Gadu-Gadu website. + * Fix bug where a malicious server or man-in-the-middle could trigger + a crash by not sending enough arguments with various messages. + (Discovered by Daniel Atallah) (CVE-2014-0020) * Fix bug where initial IRC status would not be set correctly.
* Fix bug where IRC wasn't available when libpurple was compiled with
Cyrus SASL support. (#15517)
+ * Fix NULL pointer dereference parsing headers in MSN. + (Discovered by Fabian Yamaguchi and Christian Wressnegger of the + University of Goettingen) (CVE-2013-6482) + * Fix NULL pointer dereference parsing OIM data in MSN. + (Discovered by Fabian Yamaguchi and Christian Wressnegger of the + University of Goettingen) (CVE-2013-6482) + * Fix NULL pointer dereference parsing SOAP data in MSN. + (Discovered by Fabian Yamaguchi and Christian Wressnegger of the + University of Goettingen) (CVE-2013-6482) + * Fix possible crash when sending very long messages. Not + remotely-triggerable. (Discovered by Matt Jones, Volvent) + * Fix buffer overflow with remote code execution potential. + (Discovered by Yves Younan and Pawel Janic of Sourcefire VRT) * Fix sporadic crashes that can happen after user is disconnected.
* Fix crash when attempting to add a contact via search results.
* Show error message if file transfer fails.
@@ -100,7 +150,17 @@
* Correctly set whiteboard dimensions in whiteboard sessions.
+ * Fix buffer overflow with remote code execution potential. + (Discovered by Yves Younan of Sourcefire VRT) (CVE-2013-6487) + * Prevent spoofing of iq replies by verifying that the 'from' address + matches the 'to' address of the iq request. (Discovered by Fabian + Yamaguchi and Christian Wressnegger of the University of Goettingen) + * Fix crash on some systems when receiving fake delay timestamps with + extreme values. (Discovered by Jaime Breva Ribes) (CVE-2013-6477) * Fix possible crash or other erratic behavior when selecting a very
small file for your own buddy icon.
* Fix crash if the user tries to initiate a voice/video session with a
@@ -108,6 +168,14 @@
* Fix login errors when the first two available auth mechanisms fail but
a subsequent mechanism would otherwise work when using Cyrus SASL.
+ * Fix dropping incoming stanzas on BOSH connections when we receive + multiple HTTP responses at once. (#15684) + * Fix possible crashes handling incoming strings that are not UTF-8. + (Discovered by Thijs Alkemade and Robert Vehse) (CVE-2012-6152) + * Fix a bug reading a peer to peer message where a remote user could + trigger a crash. (CVE-2013-6481) * Fix crash in contact availability plugin.
--- a/libpurple/protocols/irc/msgs.c Mon Jan 20 07:39:26 2014 +0530
+++ b/libpurple/protocols/irc/msgs.c Mon Jan 20 00:02:17 2014 -0800
@@ -20,6 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ * Note: If you change any of these functions to use additional args you + * MUST ensure the arg count is correct in parse.c. Otherwise it may be + * possible for a malicious server or man-in-the-middle to trigger a crash. #include "conversation.h"
@@ -201,9 +207,6 @@
- if (!args || !args[0] || !args[1])
features = g_strsplit(args[1], " ", -1);
for (i = 0; features[i]; i++) {
@@ -218,9 +221,6 @@
void irc_msg_luser(struct irc_conn *irc, const char *name, const char *from, char **args)
if (!strcmp(name, "251")) {
/* 251 is required, so we pluck our nick from here and
@@ -236,9 +236,6 @@
if (irc->whois.nick && !purple_utf8_strcasecmp(irc->whois.nick, args[1])) {
/* We're doing a whois, show this in the whois dialog */
irc_msg_whois(irc, name, from, args);
@@ -257,8 +254,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[1] || !gc)
purple_notify_error(gc, NULL, _("Bad mode"), args[1],
purple_request_cpar_from_connection(gc));
@@ -268,16 +264,12 @@
PurpleChatConversation *chat;
- if (!args || !args[0] || !args[1])
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
if (!strcmp(name, "367")) {
+ g_return_if_fail(args[2]); if (args[3] && args[4]) {
/* This is an extended syntax, not in RFC 1459 */
@@ -313,8 +305,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[1] || !gc)
buf = g_strdup_printf(_("You are banned from %s."), args[1]);
purple_notify_error(gc, _("Banned"), _("Banned"), buf,
@@ -327,9 +318,6 @@
PurpleChatConversation *chat;
- if (!args || !args[0] || !args[1] || !args[2])
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
@@ -348,9 +336,6 @@
PurpleChatConversation *chat;
- if (!args || !args[1] || !args[2])
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
if (!chat) /* XXX punt on channels we are not in for now */
@@ -482,13 +467,6 @@
PurpleChatUserFlags flags;
- if (!args || !args[0] || !args[1] || !args[2] || !args[3]
- || !args[4] || !args[5] || !args[6] || !args[7]) {
- purple_debug(PURPLE_DEBUG_ERROR, "irc",
- "Got a WHO response with not enough arguments\n");
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
purple_debug(PURPLE_DEBUG_ERROR, "irc","Got a WHO response for %s, which doesn't exist\n", args[1]);
@@ -551,9 +529,6 @@
PurpleRoomlistRoom *room;
- if (!args[0] || !args[1] || !args[2] || !args[3])
if (!purple_roomlist_get_in_progress(irc->roomlist)) {
purple_debug_warning("irc", "Buggy server didn't send RPL_LISTSTART.\n");
purple_roomlist_set_in_progress(irc->roomlist, TRUE);
@@ -575,13 +550,13 @@
PurpleChatConversation *chat;
if (!strcmp(name, "topic")) {
- if (!args[0] || !args[1])
+ g_return_if_fail(args[0]); + g_return_if_fail(args[1]); topic = irc_mirc2txt (args[1]);
- if (!args[0] || !args[1] || !args[2])
+ g_return_if_fail(args[1]); + g_return_if_fail(args[2]); topic = irc_mirc2txt (args[2]);
@@ -634,9 +609,6 @@
char *msg, *timestamp, *datestamp;
- if (!args || !args[1] || !args[2] || !args[3])
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
@@ -666,8 +638,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[1] || !gc)
buf = g_strdup_printf(_("Unknown message '%s'"), args[1]);
purple_notify_error(gc, _("Unknown message"), buf, _("The IRC server "
@@ -758,9 +729,6 @@
if (!strcmp(name, "375")) {
g_string_free(irc->motd, TRUE);
@@ -800,8 +768,8 @@
gc = purple_account_get_connection(irc->account);
- if (gc == NULL || args == NULL || args[2] == NULL)
purple_notify_message(gc, PURPLE_NOTIFY_MSG_INFO, _("Time Response"),
_("The IRC server's local time is:"), args[2], NULL, NULL,
@@ -812,8 +780,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (gc == NULL || args == NULL || args[1] == NULL)
purple_notify_error(gc, NULL, _("No such channel"), args[1],
purple_request_cpar_from_connection(gc));
@@ -877,9 +844,6 @@
PurpleChatConversation *chat;
- if (!args || !args[1] || !args[2])
chat = purple_conversations_find_chat_with_account(args[1], irc->account);
@@ -893,8 +857,7 @@
- if (!args || !args[1] || !gc)
components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
nick = irc_mask_nick(from);
@@ -910,8 +873,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[1] || !gc)
buf = g_strdup_printf(_("Joining %s requires an invitation."), args[1]);
purple_notify_error(gc, _("Invitation only"), _("Invitation only"), buf,
@@ -925,9 +887,6 @@
nicks = g_strsplit(args[1], " ", -1);
for (i = 0; nicks[i]; i++) {
if ((ib = g_hash_table_lookup(irc->buddies, (gconstpointer)nicks[i])) == NULL) {
@@ -967,14 +926,13 @@
PurpleChatConversation *chat;
- char *nick = irc_mask_nick(from), *userhost, *buf;
+ char *nick, *userhost, *buf;
+ nick = irc_mask_nick(from); if (!purple_utf8_strcasecmp(nick, purple_connection_get_display_name(gc))) {
/* We are joining a channel for the first time */
@@ -1030,12 +988,11 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
PurpleChatConversation *chat = purple_conversations_find_chat_with_account(args[0], irc->account);
- char *nick = irc_mask_nick(from), *buf;
+ nick = irc_mask_nick(from); purple_debug(PURPLE_DEBUG_ERROR, "irc", "Received a KICK for unknown channel %s\n", args[0]);
@@ -1181,9 +1138,6 @@
char *newnick, *buf, *end;
PurpleConnection *gc = purple_account_get_connection(irc->account);
if (gc && purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED) {
/* We only want to do the following dance if the connection
has not been successfully completed. If it has, just
@@ -1222,9 +1176,6 @@
void irc_msg_notice(struct irc_conn *irc, const char *name, const char *from, char **args)
- if (!args || !args[0] || !args[1])
irc_msg_handle_privmsg(irc, name, from, args[0], args[1], TRUE);
@@ -1232,8 +1183,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[2] || !gc)
purple_notify_error(gc, _("Cannot change nick"),
_("Could not change nick"), args[2],
@@ -1246,8 +1196,7 @@
PurpleChatConversation *chat;
char *nick, *msg, *channel;
- if (!args || !args[0] || !gc)
/* Undernet likes to :-quote the channel name, for no good reason
* that I can see. This catches that. */
@@ -1280,8 +1229,6 @@
void irc_msg_ping(struct irc_conn *irc, const char *name, const char *from, char **args)
buf = irc_format(irc, "v:", "PONG", args[0]);
@@ -1295,9 +1242,6 @@
parts = g_strsplit(args[1], " ", 2);
if (!parts[0] || !parts[1]) {
@@ -1329,9 +1273,6 @@
void irc_msg_privmsg(struct irc_conn *irc, const char *name, const char *from, char **args)
- if (!args || !args[0] || !args[1])
irc_msg_handle_privmsg(irc, name, from, args[0], args[1], FALSE);
@@ -1384,8 +1325,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[1] || !args[2] || !gc)
if (purple_conversations_find_chat_with_account(args[1], irc->account)) {
/* This is a channel we're already in; for some reason,
@@ -1407,8 +1347,7 @@
- if (!args || !args[0] || !gc)
data[0] = irc_mask_nick(from);
@@ -1429,9 +1368,6 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
purple_notify_error(gc, NULL, _("Nick or channel is temporarily "
"unavailable."), args[1],
purple_request_cpar_from_connection(gc));
@@ -1442,8 +1378,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
- if (!args || !args[0] || !gc)
nick = irc_mask_nick(from);
msg = g_strdup_printf (_("Wallops from %s"), nick);
@@ -1621,7 +1556,7 @@
PurpleConnection *gc = purple_account_get_connection(irc->account);
const char *mech_list = NULL;
- if (!args[1] || !args[2] || strncmp(args[2], "sasl ", 6))
+ if (strncmp(args[2], "sasl ", 6)) if (strncmp(args[1], "ACK", 4)) {
const char *tmp = _("SASL authentication failed: Server does not support SASL authentication.");
@@ -1724,7 +1659,10 @@
- authinfo = purple_base64_encode((const guchar*)c_out, clen);
+ authinfo = purple_base64_encode((const guchar*)c_out, clen); + authinfo = g_strdup("+"); buf = irc_format(irc, "vv", "AUTHENTICATE", authinfo);
--- a/libpurple/protocols/jabber/iq.c Mon Jan 20 07:39:26 2014 +0530
+++ b/libpurple/protocols/jabber/iq.c Mon Jan 20 00:02:17 2014 -0800
@@ -49,6 +49,18 @@
static GHashTable *iq_handlers = NULL;
static GHashTable *signal_iq_handlers = NULL;
+struct _JabberIqCallbackData { + JabberIqCallback *callback; +void jabber_iq_callbackdata_free(JabberIqCallbackData *jcd) + jabber_id_free(jcd->to); JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
@@ -98,11 +110,6 @@
-typedef struct _JabberCallbackData {
- JabberIqCallback *callback;
jabber_iq_set_callback(JabberIq *iq, JabberIqCallback *callback, gpointer data)
@@ -125,15 +132,17 @@
void jabber_iq_send(JabberIq *iq)
- JabberCallbackData *jcd;
+ JabberIqCallbackData *jcd; g_return_if_fail(iq != NULL);
jabber_send(iq->js, iq->node);
if(iq->id && iq->callback) {
- jcd = g_new0(JabberCallbackData, 1);
+ jcd = g_new0(JabberIqCallbackData, 1); jcd->callback = iq->callback;
jcd->data = iq->callback_data;
+ jcd->to = jabber_id_new(purple_xmlnode_get_attrib(iq->node, "to")); g_hash_table_insert(iq->js->iq_callbacks, g_strdup(iq->id), jcd);
@@ -276,18 +285,30 @@
void jabber_iq_parse(JabberStream *js, PurpleXmlNode *packet)
- JabberCallbackData *jcd;
+ JabberIqCallbackData *jcd; PurpleXmlNode *child, *error, *x;
const char *iq_type, *id, *from;
JabberIqType type = JABBER_IQ_NONE;
from = purple_xmlnode_get_attrib(packet, "from");
id = purple_xmlnode_get_attrib(packet, "id");
iq_type = purple_xmlnode_get_attrib(packet, "type");
+ * Ensure the 'from' attribute is valid. No point in handling a stanza + * of which we don't understand where it came from. + from_id = jabber_id_new(from); + if (from && !from_id) { + purple_debug_error("jabber", "Received an iq with an invalid from: %s\n", from); * child will be either the first tag child or NULL if there is no child.
* Historically, we used just the 'query' subchild, but newer XEPs use
* differently named children. Grabbing the first child is (for the time
@@ -312,6 +333,7 @@
if (type == JABBER_IQ_NONE) {
purple_debug_error("jabber", "IQ with invalid type ('%s') - ignoring.\n",
iq_type ? iq_type : "(null)");
+ jabber_id_free(from_id); @@ -342,20 +364,38 @@
purple_debug_error("jabber", "IQ of type '%s' missing id - ignoring.\n",
+ jabber_id_free(from_id); signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_connection_get_prpl(js->gc),
"jabber-receiving-iq", js->gc, iq_type, id, from, packet));
+ jabber_id_free(from_id); /* First, lets see if a special callback got registered */
if(type == JABBER_IQ_RESULT || type == JABBER_IQ_ERROR) {
if((jcd = g_hash_table_lookup(js->iq_callbacks, id))) {
- jcd->callback(js, from, type, id, packet, jcd->data);
- jabber_iq_remove_callback_by_id(js, id);
+ if(jabber_id_equal(js, jcd->to, from_id)) { + jcd->callback(js, from, type, id, packet, jcd->data); + jabber_iq_remove_callback_by_id(js, id); + jabber_id_free(from_id); + expected_to = jabber_id_get_full_jid(jcd->to); + expected_to = jabber_id_get_bare_jid(js->user); + purple_debug_error("jabber", "Got a result iq with id %s from %s instead of expected %s!\n", id, from ? from : "(null)", expected_to); @@ -372,12 +412,15 @@
signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_connection_get_prpl(js->gc), "jabber-watched-iq",
js->gc, iq_type, id, from, child));
+ jabber_id_free(from_id); jih(js, from, type, id, child);
+ jabber_id_free(from_id); @@ -404,6 +447,8 @@
+ jabber_id_free(from_id); void jabber_iq_register_handler(const char *node, const char *xmlns, JabberIqHandler *handlerfunc)
--- a/libpurple/protocols/yahoo/libymsg.c Mon Jan 20 07:39:26 2014 +0530
+++ b/libpurple/protocols/yahoo/libymsg.c Mon Jan 20 00:02:17 2014 -0800
@@ -21,6 +21,12 @@
+ * Note: When handling the list of struct yahoo_pair's from an incoming + * packet the value might not be UTF-8. You should either validate that + * it is UTF-8 using g_utf8_validate() or use yahoo_string_decode(). @@ -598,14 +604,24 @@
yd->current_list15_grp = yahoo_string_decode(gc, pair->value, FALSE);
case 7: /* buddy's s/n */
- temp = g_strdup(purple_normalize(account, pair->value));
+ if (g_utf8_validate(pair->value, -1, NULL)) { + temp = g_strdup(purple_normalize(account, pair->value)); + purple_debug_warning("yahoo", "yahoo_process_list_15 " + "got non-UTF-8 string for key %d\n", pair->key); case 241: /* user on federated network */
fed = strtol(pair->value, NULL, 10);
case 59: /* somebody told cookies come here too, but im not sure */
- yahoo_process_cookie(yd, pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + yahoo_process_cookie(yd, pair->value); + purple_debug_warning("yahoo", "yahoo_process_list_15 " + "got non-UTF-8 string for key %d\n", pair->key); case 317: /* Stealth Setting */
stealth = strtol(pair->value, NULL, 10);
@@ -667,22 +683,42 @@
g_string_append(yd->tmp_serv_blist, pair->value);
- if (!yd->tmp_serv_ilist)
- yd->tmp_serv_ilist = g_string_new(pair->value);
- g_string_append(yd->tmp_serv_ilist, pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + if (!yd->tmp_serv_ilist) + yd->tmp_serv_ilist = g_string_new(pair->value); + g_string_append(yd->tmp_serv_ilist, pair->value); + purple_debug_warning("yahoo", "yahoo_process_list " + "got non-UTF-8 string for key %d\n", pair->key); - yd->profiles = g_strsplit(pair->value, ",", -1);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + yd->profiles = g_strsplit(pair->value, ",", -1); + purple_debug_warning("yahoo", "yahoo_process_list " + "got non-UTF-8 string for key %d\n", pair->key); case 59: /* cookies, yum */
- yahoo_process_cookie(yd, pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + yahoo_process_cookie(yd, pair->value); + purple_debug_warning("yahoo", "yahoo_process_list " + "got non-UTF-8 string for key %d\n", pair->key); case YAHOO_SERVICE_PRESENCE_PERM:
- if (!yd->tmp_serv_plist)
- yd->tmp_serv_plist = g_string_new(pair->value);
- g_string_append(yd->tmp_serv_plist, pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + if (!yd->tmp_serv_plist) + yd->tmp_serv_plist = g_string_new(pair->value); + g_string_append(yd->tmp_serv_plist, pair->value); + purple_debug_warning("yahoo", "yahoo_process_list " + "got non-UTF-8 string for key %d\n", pair->key); @@ -705,6 +741,12 @@
grp = yahoo_string_decode(gc, split[0], FALSE);
buddies = g_strsplit(split[1], ",", -1);
for (bud = buddies; bud && *bud; bud++) {
+ if (!g_utf8_validate(*bud, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_list " + "got non-UTF-8 string for bud\n"); norm_bud = g_strdup(purple_normalize(account, *bud));
f = yahoo_friend_find_or_new(gc, norm_bud);
@@ -798,14 +840,26 @@
struct yahoo_pair *pair = l->data;
- if (pair->key == 4 || pair->key == 1)
+ if (pair->key == 4 || pair->key == 1) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_notify " + "got non-UTF-8 string for key %d\n", pair->key);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_notify " + "got non-UTF-8 string for key %d\n", pair->key); val_11 = strtol(pair->value, NULL, 10);
@@ -909,10 +963,15 @@
struct yahoo_pair *pair = l->data;
- sms = g_new0(struct _yahoo_im, 1);
- sms->from = g_strdup_printf("+%s", pair->value);
- sms->time = time(NULL);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + sms = g_new0(struct _yahoo_im, 1); + sms->from = g_strdup_printf("+%s", pair->value); + sms->time = time(NULL); + purple_debug_warning("yahoo", "yahoo_process_sms_message " + "got non-UTF-8 string for key %d\n", pair->key); @@ -921,8 +980,14 @@
g_hash_table_insert(yd->sms_carrier, g_strdup(sms->from), g_strdup(pair->value));
- server_msg = pair->value;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + server_msg = pair->value; + purple_debug_warning("yahoo", "yahoo_process_sms_message " + "got non-UTF-8 string for key %d\n", pair->key); @@ -979,13 +1044,18 @@
struct yahoo_pair *pair = l->data;
if (pair->key == 4 || pair->key == 1) {
- im = g_new0(struct _yahoo_im, 1);
- list = g_slist_append(list, im);
- im->from = pair->value;
- im->fed = YAHOO_FEDERATION_NONE;
- im->fed_from = g_strdup(im->from);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + im = g_new0(struct _yahoo_im, 1); + list = g_slist_append(list, im); + im->from = pair->value; + im->fed = YAHOO_FEDERATION_NONE; + im->fed_from = g_strdup(im->from); + purple_debug_warning("yahoo", "yahoo_process_message " + "got non-UTF-8 string for key %d\n", pair->key); if (im && pair->key == 5)
im->active_id = pair->value;
@@ -1041,7 +1111,7 @@
- if (im && pair->key == 63)
+ if (im && pair->key == 63 && g_utf8_validate(pair->value, -1, NULL)) /* Check for the Doodle IMV, no IMvironment for federated buddies */
if (im->from != NULL && im->fed == YAHOO_FEDERATION_NONE)
@@ -1178,10 +1248,22 @@
struct yahoo_pair *pair = l->data;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_sysmessage " + "got non-UTF-8 string for key %d\n", pair->key); + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_sysmessage " + "got non-UTF-8 string for key %d\n", pair->key); @@ -1325,7 +1407,12 @@
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 " + "got non-UTF-8 string for key %d\n", pair->key); response = strtol(pair->value, NULL, 10);
@@ -1380,22 +1467,42 @@
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 " + "got non-UTF-8 string for key %d\n", pair->key); - add_req->id = g_strdup(pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + add_req->id = g_strdup(pair->value); + purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 " + "got non-UTF-8 string for key %d\n", pair->key); - firstname = pair->value;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + firstname = pair->value; + purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 " + "got non-UTF-8 string for key %d\n", pair->key); add_req->fed = strtol(pair->value, NULL, 10);
- lastname = pair->value;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + lastname = pair->value; + purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 " + "got non-UTF-8 string for key %d\n", pair->key); @@ -1476,10 +1583,20 @@
- add_req->id = g_strdup(pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + add_req->id = g_strdup(pair->value); + purple_debug_warning("yahoo", "yahoo_buddy_added_us " + "got non-UTF-8 string for key %d\n", pair->key); - add_req->who = g_strdup(pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + add_req->who = g_strdup(pair->value); + purple_debug_warning("yahoo", "yahoo_buddy_added_us " + "got non-UTF-8 string for key %d\n", pair->key); case 15: /* time, for when they add us and we're offline */
@@ -1531,10 +1648,20 @@
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_buddy_denied_our_add_old " + "got non-UTF-8 string for key %d\n", pair->key);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_buddy_denied_our_add_old " + "got non-UTF-8 string for key %d\n", pair->key); @@ -1631,12 +1758,28 @@
struct yahoo_pair *pair = l->data;
count = strtol(pair->value, NULL, 10);
- else if (pair->key == 43)
- else if (pair->key == 42)
- else if (pair->key == 18)
+ else if (pair->key == 43) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_mail " + "got non-UTF-8 string for key %d\n", pair->key); + } else if (pair->key == 42) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_mail " + "got non-UTF-8 string for key %d\n", pair->key); + } else if (pair->key == 18) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_mail " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2025,8 +2168,14 @@
struct yahoo_pair *pair = l->data;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_auth " + "got non-UTF-8 string for key %d\n", pair->key); /* (pair->key == 1) -> sn */
@@ -2099,7 +2248,12 @@
struct yahoo_pair *pair = l->data;
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_ignore " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2196,8 +2350,14 @@
err = strtol(pair->value, NULL, 10);
- else if (pair->key == 20)
+ else if (pair->key == 20) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_authresp " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2276,7 +2436,12 @@
err = strtol(pair->value, NULL, 10);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_addbuddy " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2436,11 +2601,16 @@
- if(strncmp(who, p2p_data->host_username, strlen(p2p_data->host_username)) != 0) {
- /* from whom are we receiving the packets ?? */
- purple_debug_warning("yahoo","p2p: received data from wrong user\n");
+ if (g_utf8_validate(pair->value, -1, NULL)) { + if(strncmp(who, p2p_data->host_username, strlen(p2p_data->host_username)) != 0) { + /* from whom are we receiving the packets ?? */ + purple_debug_warning("yahoo","p2p: received data from wrong user\n"); + purple_debug_warning("yahoo", "yahoo_p2p_process_p2pfilexfer " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2507,7 +2677,7 @@
struct yahoo_packet *pkt;
struct yahoo_p2p_data *p2p_data;
@@ -2529,19 +2699,29 @@
+ /* TODO: It looks like there's a bug here (and above) where an incorrect + * assumtion is being made that the buffer will be added to when this + * is next called, but that's not really the case! */ if(len < YAHOO_PACKET_HDRLEN)
- if(strncmp((char *)buf, "YMSG", MIN(4, len)) != 0) {
+ if(strncmp((char *)buf, "YMSG", 4) != 0) { + purple_debug_warning("yahoo", "p2p: Got something other than YMSG packet\n"); + start = (guchar *) g_strstr_len((char *) buf + 1, len - 1 ,"YMSG"); + /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ + if (g_hash_table_lookup(yd->peers, p2p_data->host_username)) + g_hash_table_remove(yd->peers, p2p_data->host_username); + yahoo_p2p_disconnect_destroy_data(data); purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n");
- start = memchr(buf + 1, 'Y', len - 1);
- g_memmove(buf, start, len - (start - buf));
+ g_memmove(buf, start, len); @@ -2549,7 +2729,17 @@
pktlen = yahoo_get16(buf + pos); pos += 2;
- purple_debug_misc("yahoo", "p2p: %d bytes to read\n", len);
+ if (len < (YAHOO_PACKET_HDRLEN + pktlen)) { + purple_debug_error("yahoo", "p2p: packet length(%d) > buffer length(%d)\n", + /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ + if (g_hash_table_lookup(yd->peers, p2p_data->host_username)) + g_hash_table_remove(yd->peers, p2p_data->host_username); + yahoo_p2p_disconnect_destroy_data(data); + purple_debug_misc("yahoo", "p2p: %d bytes to read\n", pktlen); pkt = yahoo_packet_new(0, 0, 0);
pkt->service = yahoo_get16(buf + pos); pos += 2;
@@ -2809,15 +2999,25 @@
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_p2p " + "got non-UTF-8 string for key %d\n", pair->key); /* who again, the master identity this time? */
- /* so, this is an ip address. in base64. decoded it's in ascii.
- after strtol, it's in reversed byte order. Who thought this up?*/
+ if (g_utf8_validate(pair->value, -1, NULL)) { + /* so, this is an ip address. in base64. decoded it's in ascii. + after strtol, it's in reversed byte order. Who thought this up?*/ + purple_debug_warning("yahoo", "yahoo_process_p2p " + "got non-UTF-8 string for key %d\n", pair->key); val_13 = strtol(pair->value, NULL, 10);
@@ -2906,7 +3106,12 @@
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_audible " + "got non-UTF-8 string for key %d\n", pair->key); @@ -2914,11 +3119,21 @@
/* the audible, in foo.locale.bar.baz format
eg: base.tw.smiley.smiley43 */
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_audible " + "got non-UTF-8 string for key %d\n", pair->key); /* the text of the audible */
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_audible " + "got non-UTF-8 string for key %d\n", pair->key); /* SHA-1 hash of audible SWF file (eg: 4e8691499d9c0fb8374478ff9720f4a9ea4a4915) */
--- a/libpurple/protocols/yahoo/yahoochat.c Mon Jan 20 07:39:26 2014 +0530
+++ b/libpurple/protocols/yahoo/yahoochat.c Mon Jan 20 00:02:17 2014 -0800
@@ -156,15 +156,25 @@
room = yahoo_string_decode(gc, pair->value, FALSE);
- g_string_append_printf(members, "%s\n", who);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + g_string_append_printf(members, "%s\n", who); + purple_debug_warning("yahoo", "yahoo_process_conference_invite " + "got non-UTF-8 string for key %d\n", pair->key); case 51: /* This user is being invited to the conference. Comes with status = 11, so we wont reach here */
case 52: /* Invited users. Assuming us invited, since we got this packet */
break; /* break needed, or else we add the users to the conference before they accept the invitation */
case 53: /* members who have already joined the conference */
- g_string_append_printf(members, "%s\n", pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + g_string_append_printf(members, "%s\n", pair->value); + purple_debug_warning("yahoo", "yahoo_process_conference_invite " + "got non-UTF-8 string for key %d\n", pair->key); @@ -220,7 +230,12 @@
room = yahoo_string_decode(gc, pair->value, FALSE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_conference_decline " + "got non-UTF-8 string for key %d\n", pair->key); @@ -278,7 +293,12 @@
room = yahoo_string_decode(gc, pair->value, FALSE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_conference_logon " + "got non-UTF-8 string for key %d\n", pair->key); @@ -310,7 +330,12 @@
room = yahoo_string_decode(gc, pair->value, FALSE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_conference_logoff " + "got non-UTF-8 string for key %d\n", pair->key); @@ -341,7 +366,12 @@
room = yahoo_string_decode(gc, pair->value, FALSE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_conference_message " + "got non-UTF-8 string for key %d\n", pair->key); @@ -533,7 +563,12 @@
info about individual room members, (including us) */
case 109: /* the yahoo id */
- members = g_list_append(members, pair->value);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + members = g_list_append(members, pair->value); + purple_debug_warning("yahoo", "yahoo_process_chat_join " + "got non-UTF-8 string for key %d\n", pair->key); @@ -630,8 +665,14 @@
room = yahoo_string_decode(gc, pair->value, TRUE);
+ if (pair->key == 109) { + if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_chat_exit " + "got non-UTF-8 string for key %d\n", pair->key); @@ -664,10 +705,20 @@
room = yahoo_string_decode(gc, pair->value, TRUE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_chat_message " + "got non-UTF-8 string for key %d\n", pair->key);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_chat_message " + "got non-UTF-8 string for key %d\n", pair->key); msgtype = strtol(pair->value, NULL, 10);
@@ -730,7 +781,12 @@
msg = yahoo_string_decode(gc, pair->value, FALSE);
+ if (g_utf8_validate(pair->value, -1, NULL)) { + purple_debug_warning("yahoo", "yahoo_process_chat_addinvite " + "got non-UTF-8 string for key %d\n", pair->key);