changeset 8118:52089b055c12

[gaim-migrate @ 8822] "Hi over there... just found another overflow while creating patches for gaim-cvs and 0.75 for all vulnerabilities I have found. The new overflow is in gaim_url_parse a sscanf without sizechecks into stackbuffers. I think you can apply the patches directly and all vulnerabilities are gone..." -- Stefan Esser " Using 0.75, looking at the logs for conversations I've had since upgrading, I discovered that the formating (font, color, size) of the text was not showing up. Looking at the actual HTML in the log files I discovered that the use of tags has replaced with tags and inline CSS, this formatting shows up fine when viewing the logs using a browser such as Mozilla, but not in the Gaim log viewer. Here, I fixed my own bug in 0.75 and then fixed it in 0.76cvs so I could give you the diff. Actually tested it in 0.76cvs, apparently all the font handling stuff is a bit screwy, but you might as well add my work so when it's back to normal the log viewer is consistent with the log files." --Douglas (douglaswth) Thrift (18:10:53) Me: look at that html patch (18:11:02) seanegn: I did last night (18:11:06) Me: and? (18:12:35) Me: can it go in? (18:17:33) ***Me senses he is being ignored (18:18:50) seanegn: haha, no. (18:18:59) seanegn: It looked like it should be good. Do you want to commit it? (18:19:04) Me: i can do that yes (18:19:14) Me: i'm looking at if the overflow patch compiles currently (18:19:24) seanegn: do that one too (18:19:27) Me: :-) (18:19:48) seanegn: Why do I have a feeling that this conversation (including this line) is going to be part of a commit log message? (18:19:53) seanegn: Hi, gaim-commits! (18:19:56) Me: lol (18:20:25) Me: *inocently* would i do that? (18:20:31) Me: :-P committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Thu, 15 Jan 2004 23:26:07 +0000
parents e280d73ed07f
children 4acdd763e1ac
files COPYRIGHT src/gtkimhtml.c src/protocols/yahoo/yahoo.c src/proxy.c src/util.c
diffstat 5 files changed, 198 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Thu Jan 15 23:11:46 2004 +0000
+++ b/COPYRIGHT	Thu Jan 15 23:26:07 2004 +0000
@@ -99,8 +99,9 @@
 Stu Somlinson
 Brian Tarricone
 Peter Teichman
+Philip Tellis
 Arun A. Tharuvai
-Philip Tellis
+Douglas (douglaswth) Thrift
 Bill Tompkins
 Tom Tromey
 Junichi Uekawa
--- a/src/gtkimhtml.c	Thu Jan 15 23:11:46 2004 +0000
+++ b/src/gtkimhtml.c	Thu Jan 15 23:26:07 2004 +0000
@@ -1025,7 +1025,7 @@
 	char *close;
 	*type = 1;
 
-	
+
 	if (!(close = strchr (string, '>')))
 		return FALSE;
 
@@ -1101,8 +1101,8 @@
 			*tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->"));
 			return TRUE;
 		}
-	} 
-	
+	}
+
 	*type = -1;
 	*len = close - string + 1;
 	*tag = g_strndup(string, *len - 1);
@@ -1168,6 +1168,69 @@
 	return val;
 }
 
+/* Inline CSS Support - Douglas Thrift */
+static gchar*
+gtk_imhtml_get_css_opt (gchar       *style,
+			 const gchar *opt)
+{
+	gchar *t = style;
+	gchar *e, *a;
+	gchar *val;
+	gint len;
+	gchar *c;
+	GString *ret;
+
+	while (g_ascii_strncasecmp (t, opt, strlen (opt))) {
+//		gboolean quote = FALSE;
+		if (*t == '\0') break;
+		while (*t && !((*t == ' ') /*&& !quote*/)) {
+/*			if (*t == '\"')
+				quote = ! quote;*/
+			t++;
+		}
+		while (*t && (*t == ' ')) t++;
+	}
+
+	if (!g_ascii_strncasecmp (t, opt, strlen (opt))) {
+		t += strlen (opt);
+	} else {
+		return NULL;
+	}
+
+/*	if ((*t == '\"') || (*t == '\'')) {
+		e = a = ++t;
+		while (*e && (*e != *(t - 1))) e++;
+		if  (*e == '\0') {
+			return NULL;
+		} else
+			val = g_strndup(a, e - a);
+	} else {
+		e = a = t;
+		while (*e && !isspace ((gint) *e)) e++;
+		val = g_strndup(a, e - a);
+	}*/
+
+	e = a = t;
+	while (*e && *e != ';') e++;
+	val = g_strndup(a, e - a);
+
+	ret = g_string_new("");
+	e = val;
+	while(*e) {
+		if(gtk_imhtml_is_amp_escape(e, &c, &len)) {
+			ret = g_string_append(ret, c);
+			e += len;
+		} else {
+			ret = g_string_append_c(ret, *e);
+			e++;
+		}
+	}
+
+	g_free(val);
+	val = ret->str;
+	g_string_free(ret, FALSE);
+	return val;
+}
 
 GString* gtk_imhtml_append_text_with_images (GtkIMHtml        *imhtml,
 					     const gchar      *text,
@@ -1429,7 +1492,7 @@
 						gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins);
 					}
 					break;
-					
+
 				case 29:	/* P */
 				case 30:	/* /P */
 				case 31:	/* H3 */
@@ -1569,7 +1632,100 @@
 				case 50:	/* CITE */
 				case 51:	/* /CITE */
 				case 56:	/* SPAN (opt) */
+					/* Inline CSS Support - Douglas Thrift
+					 *
+					 * color
+					 * font-family
+					 * font-size
+					 */
+					{
+						gchar *style, *color, *family, *size;
+						GtkIMHtmlFontDetail *font, *oldfont = NULL;
+						style = gtk_imhtml_get_html_opt (tag, "style=");
+
+						if (!style) break;
+
+						color = gtk_imhtml_get_css_opt (style, "color: ");
+						family = gtk_imhtml_get_css_opt (style,
+							"font-family: ");
+						size = gtk_imhtml_get_css_opt (style, "font-size: ");
+
+						if (!(color || family || size)) break;
+
+						if (url)
+							gtk_imhtml_insert_link(imhtml, url, ws);
+						else
+							gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos);
+						ws[0] = '\0'; wpos = 0;
+						//NEW_BIT (NEW_TEXT_BIT);
+
+						font = g_new0 (GtkIMHtmlFontDetail, 1);
+						if (fonts)
+							oldfont = fonts->data;
+
+						if (color && !(options & GTK_IMHTML_NO_COLOURS))
+							font->fore = color;
+						else if (oldfont && oldfont->fore)
+							font->fore = g_strdup(oldfont->fore);
+
+						if (oldfont && oldfont->back)
+							font->back = g_strdup(oldfont->back);
+
+						if (family && !(options & GTK_IMHTML_NO_FONTS))
+							font->face = family;
+						else if (oldfont && oldfont->face)
+							font->face = g_strdup(oldfont->face);
+						if (font->face && (atoi(font->face) > 100)) {
+							g_free(font->face);
+							font->face = g_strdup("100");
+						}
+
+						if (oldfont && oldfont->sml)
+							font->sml = g_strdup(oldfont->sml);
+
+						if (size && !(options & GTK_IMHTML_NO_SIZES)) {
+							if (g_ascii_strcasecmp(size, "smaller") == 0)
+							{
+								font->size = 2;
+							}
+							else if (g_ascii_strcasecmp(size, "larger") == 0)
+							{
+								font->size = 4;
+							}
+							else
+							{
+								font->size = 3;
+							}
+						} else if (oldfont)
+							font->size = oldfont->size;
+
+						g_free(style);
+						g_free(size);
+						fonts = g_slist_prepend (fonts, font);
+					}
+					break;
 				case 57:	/* /SPAN */
+					/* Inline CSS Support - Douglas Thrift */
+					if (fonts) {
+						GtkIMHtmlFontDetail *font = fonts->data;
+						if (url)
+							gtk_imhtml_insert_link(imhtml, url, ws);
+						else
+							gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos);
+						ws[0] = '\0'; wpos = 0;
+						//NEW_BIT (NEW_TEXT_BIT);
+						fonts = g_slist_remove (fonts, font);
+						if (font->face)
+							g_free (font->face);
+						if (font->fore)
+							g_free (font->fore);
+						if (font->back)
+							g_free (font->back);
+						if (font->sml)
+							g_free (font->sml);
+						g_free (font);
+					}
+					break;
 				case 60:    /* SPAN */
 					break;
 				case 62:	/* comment */
--- a/src/protocols/yahoo/yahoo.c	Thu Jan 15 23:11:46 2004 +0000
+++ b/src/protocols/yahoo/yahoo.c	Thu Jan 15 23:26:07 2004 +0000
@@ -131,8 +131,15 @@
 		while (pos + 1 < len) {
 			if (data[pos] == 0xc0 && data[pos + 1] == 0x80)
 				break;
+			if (x >= sizeof(key)-1) {
+				x++;
+				continue;
+			}
 			key[x++] = data[pos++];
 		}
+		if (x >= sizeof(key)-1) {
+			x = 0;
+		}
 		key[x] = 0;
 		pos += 2;
 		pair->key = strtol(key, NULL, 10);
@@ -873,12 +880,13 @@
 static char *yahoo_decode(const char *text)
 {
 	char *converted;
-	char *p, *n, *new;
+	char *p, *n, *new, *end;
 	int i;
 	
 	n = new = g_malloc(strlen (text) + 1);
-
-	for (p = (char *)text; *p; p++, n++) {
+	end = text + strlen(text);
+
+	for (p = (char *)text; p < end; p++, n++) {
 		if (*p == '\\') {
 			sscanf(p + 1, "%3o\n", &i);
 			*n = (char)i;
@@ -1908,20 +1916,27 @@
 	GaimConnection *gc = data;
 	GaimAccount *account = gaim_connection_get_account(gc);
 	struct yahoo_data *yd = gc->proto_data;
-	char buf[1024], buf2[256], *i = buf, *r = buf2;
+	char buf[1024], buf2[256], *i = buf, *r = buf2, *rend;
 	int len, o = 0;
 
-	len = read(source, buf, sizeof(buf));
+	len = read(source, buf, sizeof(buf)-1);
 	if (len <= 0  || strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302"))) {
 		gaim_connection_error(gc, _("Unable to read"));
 		return;
 	}
+	buf[sizeof(buf)-1] = '\0';
+	buf2[0] = '\0';
+	rend = r + sizeof(buf2);
 	
-	while ((i = strstr(i, "Set-Cookie: ")) && 0 < 2) {
+	while ((i = strstr(i, "Set-Cookie: ")) && o < 2) {
 		i += strlen("Set-Cookie: "); 
-		for (;*i != ';'; r++, i++) {
+		for (;*i != ';' && r < rend; r++, i++) {
 			*r = *i;
 		}
+		if (r >= rend-2) {
+			*r = '\0';
+			r = buf2;
+		}
 		*r=';';
 		r++;
 		*r=' ';
@@ -1929,7 +1944,9 @@
 		o++;
 	}
 	/* Get rid of that "; " */
-	*(r-2) = '\0';
+	if (r > buf2) {
+		*(r-2) = '\0';
+	}
 	yd->auth = g_strdup(buf2);
 	gaim_input_remove(gc->inpa);
 	close(source);
@@ -1976,15 +1993,17 @@
 	const char *c = buf;
 	char *d;
 	char name[64], value[64];
+	int count = sizeof(name)-1;
 	while ((c < (buf + len)) && (c = strstr(c, "<input "))) {
 		c = strstr(c, "name=\"") + strlen("name=\"");
-		for (d = name; *c!='"'; c++, d++) 
+		for (d = name; *c!='"' && count; c++, d++, count--) 
 			*d = *c;
 		*d = '\0';
+		count = sizeof(value)-1;
 		d = strstr(c, "value=\"") + strlen("value=\"");
 		if (strchr(c, '>') < d)
 			break;
-		for (c = d, d = value; *c!='"'; c++, d++)
+		for (c = d, d = value; *c!='"' && count; c++, d++, count--)
 			*d = *c;
 		*d = '\0';
 		g_hash_table_insert(hash, g_strdup(name), g_strdup(value));
--- a/src/proxy.c	Thu Jan 15 23:11:46 2004 +0000
+++ b/src/proxy.c	Thu Jan 15 23:26:07 2004 +0000
@@ -974,7 +974,7 @@
 
 	gaim_input_remove(phb->inpa);
 
-	while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
+	while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
 		if (inputline[pos - 1] == '\n')
 			nlc++;
 		else if (inputline[pos - 1] != '\r')
--- a/src/util.c	Thu Jan 15 23:11:46 2004 +0000
+++ b/src/util.c	Thu Jan 15 23:26:07 2004 +0000
@@ -250,12 +250,13 @@
 void
 gaim_quotedp_decode(const char *str, char **ret_str, int *ret_len)
 {
-	char *p, *n, *new;
+	char *p, *n, *new, *end;
 	int i;
 
 	n = new = g_malloc(strlen (str) + 1);
+	end = str + strlen(str);
 
-	for (p = (char *)str; *p; p++, n++) {
+	for (p = (char *)str; p < end; p++, n++) {
 		if (*p == '=') {
 			sscanf(p + 1, "%2x\n", &i);
 			*n = (char)i;
@@ -1890,7 +1891,7 @@
 			   char **ret_path)
 {
 	char scan_info[255];
-	char port_str[5];
+	char port_str[6];
 	int f;
 	const char *turl;
 	char host[256], path[256];
@@ -1910,14 +1911,14 @@
 	}
 
 	g_snprintf(scan_info, sizeof(scan_info),
-			   "%%[%s]:%%[%s]/%%[%s]", addr_ctrl, port_ctrl, page_ctrl);
+			   "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl);
 
 	f = sscanf(url, scan_info, host, port_str, path);
 
 	if (f == 1)
 	{
 		g_snprintf(scan_info, sizeof(scan_info),
-				   "%%[%s]/%%[%s]",
+				   "%%255[%s]/%%255[%s]",
 				   addr_ctrl, page_ctrl);
 		f = sscanf(url, scan_info, host, path);
 		g_snprintf(port_str, sizeof(port_str), "80");