diff libpurple/proxy.c @ 17922:43a55528ff26

propagate from branch 'im.pidgin.pidgin' (head b5c55520ae8ff7186733fd82db23a6e4452976cc) to branch 'im.pidgin.soc.2007.finchfeat' (head 93037197c5356731d62e75b4050ca7d01b1017d6)
author Eric Polino <aluink@pidgin.im>
date Mon, 04 Jun 2007 15:12:50 +0000
parents 79ecaab86f91
children 57d350900136 941965d6fd88
line wrap: on
line diff
--- a/libpurple/proxy.c	Mon Jun 04 05:05:42 2007 +0000
+++ b/libpurple/proxy.c	Mon Jun 04 15:12:50 2007 +0000
@@ -559,7 +559,7 @@
 	int len, headers_len, status = 0;
 	gboolean error;
 	PurpleProxyConnectData *connect_data = data;
-	guchar *p;
+	char *p;
 	gsize max_read;
 
 	if (connect_data->read_buffer == NULL)
@@ -569,7 +569,7 @@
 		connect_data->read_len = 0;
 	}
 
-	p = connect_data->read_buffer + connect_data->read_len;
+	p = (char *)connect_data->read_buffer + connect_data->read_len;
 	max_read = connect_data->read_buf_len - connect_data->read_len - 1;
 
 	len = read(connect_data->fd, p, max_read);
@@ -596,11 +596,11 @@
 	connect_data->read_len += len;
 	p[len] = '\0';
 
-	p = (guchar *)g_strstr_len((const gchar *)connect_data->read_buffer,
+	p = g_strstr_len((const gchar *)connect_data->read_buffer,
 			connect_data->read_len, "\r\n\r\n");
 	if (p != NULL) {
 		*p = '\0';
-		headers_len = (p - connect_data->read_buffer) + 4;
+		headers_len = (p - (char *)connect_data->read_buffer) + 4;
 	} else if(len == max_read)
 		headers_len = len;
 	else
@@ -610,34 +610,34 @@
 	if (!error)
 	{
 		int major;
-		p = connect_data->read_buffer + 5;
-		major = strtol((const char *)p, (char**)&p, 10);
+		p = (char *)connect_data->read_buffer + 5;
+		major = strtol(p, &p, 10);
 		error = (major == 0) || (*p != '.');
 		if(!error) {
 			int minor;
 			p++;
-			minor = strtol((const char *)p, (char **)&p, 10);
+			minor = strtol(p, &p, 10);
 			error = (*p != ' ');
 			if(!error) {
 				p++;
-				status = strtol((const char *)p, (char **)&p, 10);
+				status = strtol(p, &p, 10);
 				error = (*p != ' ');
 			}
 		}
 	}
 
 	/* Read the contents */
-	p = (guchar *)g_strrstr((const gchar *)connect_data->read_buffer, "Content-Length: ");
+	p = g_strrstr((const gchar *)connect_data->read_buffer, "Content-Length: ");
 	if (p != NULL)
 	{
 		gchar *tmp;
 		int len = 0;
 		char tmpc;
 		p += strlen("Content-Length: ");
-		tmp = strchr((const char *)p, '\r');
+		tmp = strchr(p, '\r');
 		if(tmp)
 			*tmp = '\0';
-		len = atoi((const char *)p);
+		len = atoi(p);
 		if(tmp)
 			*tmp = '\r';
 
@@ -1059,6 +1059,22 @@
 	}
 }
 
+static gboolean
+s5_ensure_buffer_length(PurpleProxyConnectData *connect_data, int len)
+{
+	if(connect_data->read_len < len) {
+		if(connect_data->read_buf_len < len) {
+			/* it's not just that we haven't read enough, it's that we haven't tried to read enough yet */
+			purple_debug_info("s5", "reallocing from %d to %d\n", connect_data->read_buf_len, len);
+			connect_data->read_buf_len = len;
+			connect_data->read_buffer = g_realloc(connect_data->read_buffer, connect_data->read_buf_len);
+		}
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static void
 s5_canread_again(gpointer data, gint source, PurpleInputCondition cond)
 {
@@ -1067,7 +1083,7 @@
 	int len;
 
 	if (connect_data->read_buffer == NULL) {
-		connect_data->read_buf_len = 512;
+		connect_data->read_buf_len = 4;
 		connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
 		connect_data->read_len = 0;
 	}
@@ -1075,8 +1091,6 @@
 	dest = connect_data->read_buffer + connect_data->read_len;
 	buf = connect_data->read_buffer;
 
-	purple_debug_info("socks5 proxy", "Able to read again.\n");
-
 	len = read(connect_data->fd, dest, (connect_data->read_buf_len - connect_data->read_len));
 
 	if (len == 0)
@@ -1119,33 +1133,31 @@
 	/* Skip past BND.ADDR */
 	switch(buf[3]) {
 		case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */
-			if(connect_data->read_len < 4 + 4)
+			if(!s5_ensure_buffer_length(connect_data, 4 + 4))
 				return;
 			buf += 4 + 4;
 			break;
 		case 0x03: /* the address field contains a fully-qualified domain name.  The first
 					  octet of the address field contains the number of octets of name that
 					  follow, there is no terminating NUL octet. */
-			if(connect_data->read_len < 4 + 1)
+			if(!s5_ensure_buffer_length(connect_data, 4 + 1))
 				return;
-			buf += 4 + 1;
-			if(connect_data->read_len < 4 + 1 + buf[0])
+			buf += 4;
+			if(!s5_ensure_buffer_length(connect_data, 4 + 1 + buf[0]))
 				return;
-			buf += buf[0];
+			buf += buf[0] + 1;
 			break;
 		case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */
-			if(connect_data->read_len < 4 + 16)
+			if(!s5_ensure_buffer_length(connect_data, 4 + 16))
 				return;
 			buf += 4 + 16;
 			break;
 	}
 
-	if(connect_data->read_len < (buf - connect_data->read_buffer) + 2)
+	/* Skip past BND.PORT */
+	if(!s5_ensure_buffer_length(connect_data, (buf - connect_data->read_buffer) + 2))
 		return;
 
-	/* Skip past BND.PORT */
-	buf += 2;
-
 	purple_proxy_connect_data_connected(connect_data);
 }