# HG changeset patch # User Paul Aurich # Date 1242964099 0 # Node ID 6105fa42b60c8bc06f25d63280cc9f9320e1f6ac # Parent a667ba19244975ed4b9544997a69a89da3a393c8 Various BOSH fixes Corner case where a packet arrives that includes "Content-Lenght: " but not the end of the line (extreme corner case). Don't crash if the BOSH version doesn't include a '.' diff -r a667ba192449 -r 6105fa42b60c libpurple/protocols/jabber/bosh.c --- a/libpurple/protocols/jabber/bosh.c Fri May 22 00:21:49 2009 +0000 +++ b/libpurple/protocols/jabber/bosh.c Fri May 22 03:48:19 2009 +0000 @@ -448,11 +448,14 @@ if (version) { const char *dot = strstr(version, "."); - int major = atoi(version); - int minor = atoi(dot + 1); + int major, minor = 0; purple_debug_info("jabber", "BOSH connection manager version %s\n", version); + major = atoi(version); + if (dot) + minor = atoi(dot + 1); + if (major != 1 || minor < 6) { purple_connection_error_reason(conn->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, @@ -627,12 +630,23 @@ if (!conn->headers_done) { const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); - const char *end_of_headers = purple_strcasestr(cursor, "\r\n\r\n"); + const char *end_of_headers = strstr(cursor, "\r\n\r\n"); /* Make sure Content-Length is in headers, not body */ - if (content_length && content_length < end_of_headers) { - char *sep = strstr(content_length, ": "); - int len = atoi(sep + 2); + if (content_length && (!end_of_headers || content_length < end_of_headers)) { + const char *sep; + const char *eol; + int len; + + if ((sep = strstr(content_length, ": ")) == NULL || + (eol = strstr(sep, "\r\n")) == NULL) + /* + * The packet ends in the middle of the Content-Length line. + * We'll try again later when we have more. + */ + return; + + len = atoi(sep + 2); if (len == 0) purple_debug_warning("jabber", "Found mangled Content-Length header.\n"); @@ -688,20 +702,17 @@ if (!conn->buf) conn->buf = g_string_new(NULL); - /* Read once to prime cnt before the loop */ - if (conn->psc) - cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer)); - else - cnt = read(conn->fd, buffer, sizeof(buffer)); - while (cnt > 0) { - count += cnt; - g_string_append_len(conn->buf, buffer, cnt); - + do { if (conn->psc) cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer)); else cnt = read(conn->fd, buffer, sizeof(buffer)); - } + + if (cnt > 0) { + count += cnt; + g_string_append_len(conn->buf, buffer, cnt); + } + } while (cnt > 0); if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { if (cnt < 0)