Mercurial > pidgin.yaz
changeset 27305:a337d7a5cd0c
merge of '22e14265a47cdddb4c9eb1ee0d2ce2989f9fce61'
and '466751d2dfe5355917927b662a6d30c4a975c42a'
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Tue, 30 Jun 2009 20:52:26 +0000 |
parents | 3d92b968d49f (current diff) c5757ea836f2 (diff) |
children | b2465d7fdeac 443eb1e24606 |
files | ChangeLog libpurple/util.c |
diffstat | 3 files changed, 94 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Jun 30 01:39:08 2009 +0000 +++ b/ChangeLog Tue Jun 30 20:52:26 2009 +0000 @@ -77,6 +77,7 @@ (Sulabh Mahajan) * Addition of MSN buddies to Yahoo accounts by adding them as 'msn/buddy@somedomain.com' is now supported. (Sulabh Mahajan) + * Farther fixes for buddy pictures, aliases etc. Pidgin: * Added -f command line option to tell Pidgin to ignore NetworkManager
--- a/libpurple/protocols/yahoo/yahoo.c Tue Jun 30 01:39:08 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Tue Jun 30 20:52:26 2009 +0000 @@ -1683,11 +1683,11 @@ #else while (split_data[++totalelements] != NULL); #endif - if (totalelements >= 5) { - response_no = strtol(split_data[1], NULL, 10); - crumb = g_strdup(split_data[2] + strlen("crumb=")); - yd->cookie_y = g_strdup(split_data[3] + strlen("Y=")); - yd->cookie_t = g_strdup(split_data[4] + strlen("T=")); + if (totalelements >= 4) { + response_no = strtol(split_data[0], NULL, 10); + crumb = g_strdup(split_data[1] + strlen("crumb=")); + yd->cookie_y = g_strdup(split_data[2] + strlen("Y=")); + yd->cookie_t = g_strdup(split_data[3] + strlen("T=")); } g_strfreev(split_data); @@ -1769,9 +1769,9 @@ #else while (split_data[++totalelements] != NULL); #endif - if(totalelements >= 5) { - response_no = strtol(split_data[1], NULL, 10); - token = g_strdup(split_data[2] + strlen("ymsgr=")); + if(totalelements >= 2) { + response_no = strtol(split_data[0], NULL, 10); + token = g_strdup(split_data[1] + strlen("ymsgr=")); } g_strfreev(split_data); @@ -2158,6 +2158,7 @@ } else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */ yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT); + g_free(who); return; } @@ -4221,7 +4222,7 @@ } } - msn = g_str_has_prefix(who, "msn/") || g_str_has_prefix(who, "MSN/"); + msn = !g_strncasecmp(who, "msn/", 4); if( strncmp(who, "+", 1) == 0 ) { /* we have an sms to be sent */ @@ -4345,7 +4346,7 @@ { struct yahoo_data *yd = gc->proto_data; struct yahoo_p2p_data *p2p_data; - gboolean msn = (g_str_has_prefix(who, "msn/") || g_str_has_prefix(who, "MSN/")); + gboolean msn = !g_strncasecmp(who, "msn/", 4); struct yahoo_packet *pkt = NULL; /* Don't do anything if sms is being typed */ @@ -4618,7 +4619,7 @@ return; f = yahoo_friend_find(gc, bname); - msn = g_str_has_prefix(bname, "msn/") || g_str_has_prefix(bname, "MSN/"); + msn = !g_strncasecmp(bname, "msn/", 4); g = purple_buddy_get_group(buddy); if (g)
--- a/libpurple/util.c Tue Jun 30 01:39:08 2009 +0000 +++ b/libpurple/util.c Tue Jun 30 20:52:26 2009 +0000 @@ -68,6 +68,7 @@ unsigned long len; unsigned long data_len; gssize max_len; + gboolean chunked; }; static char *custom_user_dir = NULL; @@ -3728,41 +3729,43 @@ return TRUE; } +static const char * +find_header_content(const char *data, size_t data_len, const char *header, size_t header_len) +{ + const char *p = NULL; + + if (header_len <= 0) + header_len = strlen(header); + + /* Note: data is _not_ nul-terminated. */ + if (data_len > header_len) { + if (header[0] == '\n') + p = (g_strncasecmp(data, header + 1, header_len - 1) == 0) ? data : NULL; + if (!p) + p = purple_strcasestr(data, header); + if (p) + p += header_len; + } + + /* If we can find the header at all, try to sscanf it. + * Response headers should end with at least \r\n, so sscanf is safe, + * if we make sure that there is indeed a \n in our header. + */ + if (p && g_strstr_len(p, data_len - (p - data), "\n")) { + return p; + } + + return NULL; +} + static size_t parse_content_len(const char *data, size_t data_len) { size_t content_len = 0; const char *p = NULL; - /* This is still technically wrong, since headers are case-insensitive - * [RFC 2616, section 4.2], though this ought to catch the normal case. - * Note: data is _not_ nul-terminated. - */ - if(data_len > 16) { - p = (strncmp(data, "Content-Length: ", 16) == 0) ? data : NULL; - if(!p) - p = (strncmp(data, "CONTENT-LENGTH: ", 16) == 0) - ? data : NULL; - if(!p) { - p = g_strstr_len(data, data_len, "\nContent-Length: "); - if (p) - p++; - } - if(!p) { - p = g_strstr_len(data, data_len, "\nCONTENT-LENGTH: "); - if (p) - p++; - } - - if(p) - p += 16; - } - - /* If we can find a Content-Length header at all, try to sscanf it. - * Response headers should end with at least \r\n, so sscanf is safe, - * if we make sure that there is indeed a \n in our header. - */ - if (p && g_strstr_len(p, data_len - (p - data), "\n")) { + p = find_header_content(data, data_len, "\nContent-Length: ", sizeof("\nContent-Length: ") - 1); + if (p) { sscanf(p, "%" G_GSIZE_FORMAT, &content_len); purple_debug_misc("util", "parsed %" G_GSIZE_FORMAT "\n", content_len); } @@ -3770,6 +3773,49 @@ return content_len; } +static gboolean +content_is_chunked(const char *data, size_t data_len) +{ + gboolean chunked = FALSE; + const char *p = find_header_content(data, data_len, "\nTransfer-Encoding: ", sizeof("\nTransfer-Encoding: ") - 1); + if (p && g_strncasecmp(p, "chunked", 7) == 0) + chunked = TRUE; + + return chunked; +} + +/* Process in-place */ +static void +process_chunked_data(char *data, gssize *len) +{ + gssize sz; + gssize nlen = 0; + char *p = data; + char *s = data; + + while (*s) { + if (sscanf(s, "%x\r\n", &sz) != 1) { + purple_debug_error("util", "Error processing chunked data. Expected data length, found: %s\n", s); + break; + } + if (sz == 0) + break; + s = strstr(s, "\r\n") + 2; + g_memmove(p, s, sz); + p += sz; + s += sz; + nlen += sz; + if (*s != '\r' && *(s + 1) != '\n') { + purple_debug_error("util", "Error processing chunked data. Expected \\r\\n, found: %s\n", s); + break; + } + s += 2; + } + *p = 0; + + if (len) + *len = nlen; +} static void url_fetch_recv_cb(gpointer url_data, gint source, PurpleInputCondition cond) @@ -3830,6 +3876,7 @@ /* No redirect. See if we can find a content length. */ content_len = parse_content_len(gfud->webdata, header_len); + gfud->chunked = content_is_chunked(gfud->webdata, header_len); if(content_len == 0) { /* We'll stick with an initial 8192 */ @@ -3902,6 +3949,11 @@ gfud->webdata = g_realloc(gfud->webdata, gfud->len + 1); gfud->webdata[gfud->len] = '\0'; + if (!gfud->include_headers && gfud->chunked) { + /* Process only if we don't want the headers. */ + process_chunked_data(gfud->webdata, &gfud->len); + } + gfud->callback(gfud, gfud->user_data, gfud->webdata, gfud->len, NULL); purple_util_fetch_url_cancel(gfud); }