changeset 26931:6105fa42b60c

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 '.'
author Paul Aurich <paul@darkrain42.org>
date Fri, 22 May 2009 03:48:19 +0000
parents a667ba192449
children a8537bbcfb79
files libpurple/protocols/jabber/bosh.c
diffstat 1 files changed, 27 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- 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)