changeset 29384:cece09dbb119

merge of 'e9d34ab5e47f22b35fd2d69d61a2c943cc0653db' and 'fc3d5c2a3920e0875ac235415cea9fc7f5ed780c'
author Mark Doliner <mark@kingant.net>
date Thu, 18 Feb 2010 08:10:58 +0000
parents 46abe1203e0b (current diff) 4e42f18df200 (diff)
children 4c266d9c17eb
files ChangeLog
diffstat 11 files changed, 74 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Feb 18 06:20:55 2010 +0000
+++ b/ChangeLog	Thu Feb 18 08:10:58 2010 +0000
@@ -1,6 +1,6 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
-version 2.6.6 (??/??/20??):
+version 2.6.6 (02/18/2010):
 	libpurple:
 	* Fix 'make check' on OS X. (David Fang)
 	* Fix a quirk in purple_markup_html_to_xhtml that caused some messages
@@ -26,6 +26,8 @@
 	  Previously only icons between 48x48 and 50x50 were allowed.
 
 	MSN:
+	* Fix CVE-2010-0277, a possible remote crash when parsing an incoming
+	  SLP message.  (Discovered by Fabian Yamaguchi)
 	* File transfer requests will no longer cause a crash if you delete the
 	  file before the other side accepts.
 	* Received files will no longer hold an extra lock after completion,
@@ -73,6 +75,8 @@
 	  Mohta)
 
 	Pidgin:
+	* Fix CVE-2010-0423, a denial of service attack due to the parsing
+	  of large numbers of smileys.  (Discovered by Antti Hayrynen)
 	* Correctly size conversation and status box entries when the
 	  interior-focus style property is diabled. (Gabriel Schulhof)
 	* Correctly handle a multiline text field being required in a
@@ -102,6 +106,8 @@
 	  descriptions not to be displayed in the theme selector.
 
 	Finch:
+	* Fix CVE-2010-0420, a possible remote crash when handling chat room
+	  buddy names.
 	* Rebindable 'move-first' and 'move-last' actions for tree widgets. So
 	  it is possible to jump to the first or last entry in the buddy list
 	  (and other such lists) by pressing home or end key (defaults)
--- a/ChangeLog.API	Thu Feb 18 06:20:55 2010 +0000
+++ b/ChangeLog.API	Thu Feb 18 08:10:58 2010 +0000
@@ -1,6 +1,6 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
-version 2.6.6 (??/??/2010):
+version 2.6.6 (02/18/2010):
 	libpurple:
 		Changed:
 		* purple_xfer_cancel_local is now called instead of
--- a/ChangeLog.win32	Thu Feb 18 06:20:55 2010 +0000
+++ b/ChangeLog.win32	Thu Feb 18 08:10:58 2010 +0000
@@ -1,5 +1,5 @@
 
-version 2.6.6 (??/??/2010):
+version 2.6.6 (02/18/2010):
 	* Installer translations for: Norwegian nynorsk
 
 version 2.6.5 (01/08/2010):
--- a/NEWS	Thu Feb 18 06:20:55 2010 +0000
+++ b/NEWS	Thu Feb 18 08:10:58 2010 +0000
@@ -2,7 +2,9 @@
 
 Our development blog is available at: http://planet.pidgin.im
 
-2.6.6 (??/??/2010):
+2.6.6 (02/18/2010):
+	Mark: This release includes some great little changes and fixes a few
+	security-related bugs.  See the ChangeLog for details.
 
 2.6.5 (01/08/2010):
 	Paul: This release fixes a pretty serious bug in the MSN code, so we're
--- a/configure.ac	Thu Feb 18 06:20:55 2010 +0000
+++ b/configure.ac	Thu Feb 18 08:10:58 2010 +0000
@@ -47,7 +47,7 @@
 m4_define([purple_major_version], [2])
 m4_define([purple_minor_version], [6])
 m4_define([purple_micro_version], [6])
-m4_define([purple_version_suffix], [devel])
+m4_define([purple_version_suffix], [])
 m4_define([purple_version],
           [purple_major_version.purple_minor_version.purple_micro_version])
 m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suffix],[purple_version_suffix]))
@@ -56,7 +56,7 @@
 m4_define([gnt_major_version], [2])
 m4_define([gnt_minor_version], [6])
 m4_define([gnt_micro_version], [6])
-m4_define([gnt_version_suffix], [devel])
+m4_define([gnt_version_suffix], [])
 m4_define([gnt_version],
           [gnt_major_version.gnt_minor_version.gnt_micro_version])
 m4_define([gnt_display_version], gnt_version[]m4_ifdef([gnt_version_suffix],[gnt_version_suffix]))
--- a/finch/libgnt/gnttree.c	Thu Feb 18 06:20:55 2010 +0000
+++ b/finch/libgnt/gnttree.c	Thu Feb 18 08:10:58 2010 +0000
@@ -1346,6 +1346,10 @@
 {
 	GntTreeRow *pr = NULL;
 
+	if (g_hash_table_lookup(tree->hash, key)) {
+		gnt_tree_remove(tree, key);
+	}
+
 	row->tree = tree;
 	row->key = key;
 	row->data = NULL;
--- a/libpurple/protocols/msn/slp.c	Thu Feb 18 06:20:55 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Thu Feb 18 08:10:58 2010 +0000
@@ -741,11 +741,10 @@
 	if (!strncmp(body, "INVITE", strlen("INVITE")))
 	{
 		char *branch;
+		char *call_id;
 		char *content;
 		char *content_type;
 
-		slpcall = msn_slpcall_new(slplink);
-
 		/* From: <msnmsgr:buddy@hotmail.com> */
 #if 0
 		slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
@@ -753,7 +752,7 @@
 
 		branch = get_token(body, ";branch={", "}");
 
-		slpcall->id = get_token(body, "Call-ID: {", "}");
+		call_id = get_token(body, "Call-ID: {", "}");
 
 #if 0
 		long content_len = -1;
@@ -767,13 +766,15 @@
 
 		content = get_token(body, "\r\n\r\n", NULL);
 
-		if (branch && content_type && content)
+		if (branch && call_id && content_type && content)
 		{
+			slpcall = msn_slpcall_new(slplink);
+			slpcall->id = call_id;
 			got_invite(slpcall, branch, content_type, content);
 		}
 		else
 		{
-			msn_slpcall_destroy(slpcall);
+			g_free(call_id);
 			slpcall = NULL;
 		}
 
--- a/libpurple/protocols/msn/slpcall.c	Thu Feb 18 06:20:55 2010 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Thu Feb 18 08:10:58 2010 +0000
@@ -199,7 +199,7 @@
 
 	slpcall = NULL;
 	body = slpmsg->buffer;
-	body_len = slpmsg->size;
+	body_len = slpmsg->offset;
 
 	if (slpmsg->flags == 0x0 || slpmsg->flags == 0x1000000)
 	{
--- a/libpurple/protocols/msn/slplink.c	Thu Feb 18 06:20:55 2010 +0000
+++ b/libpurple/protocols/msn/slplink.c	Thu Feb 18 08:10:58 2010 +0000
@@ -585,15 +585,16 @@
 	}
 	else if (slpmsg->size && slpmsg->buffer)
 	{
-		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
+		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size || slpmsg->offset != offset)
 		{
 			purple_debug_error("msn",
 				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
 				slpmsg->size, offset, len);
 			g_return_if_reached();
+		} else {
+			memcpy(slpmsg->buffer + offset, data, len);
+			slpmsg->offset += len;
 		}
-		else
-			memcpy(slpmsg->buffer + offset, data, len);
 	}
 
 	if ((slpmsg->flags == 0x20 ||
--- a/libpurple/protocols/msn/slpmsg.h	Thu Feb 18 06:20:55 2010 +0000
+++ b/libpurple/protocols/msn/slpmsg.h	Thu Feb 18 08:10:58 2010 +0000
@@ -57,7 +57,18 @@
 	gboolean ft;
 	PurpleStoredImage *img;
 	guchar *buffer;
+
+	/**
+	 * For outgoing messages this is the number of bytes from buffer that
+	 * have already been sent out.  For incoming messages this is the
+	 * number of bytes that have been written to buffer.
+	 */
 	long long offset;
+
+	/**
+	 * This is the size of buffer, unless this is an outgoing file transfer,
+	 * in which case this is the size of the file.
+	 */
 	long long size;
 
 	GList *msgs; /**< The real messages. */
--- a/pidgin/gtkimhtml.c	Thu Feb 18 06:20:55 2010 +0000
+++ b/pidgin/gtkimhtml.c	Thu Feb 18 08:10:58 2010 +0000
@@ -2222,21 +2222,6 @@
 	return smiley->icon;
 }
 
-static GdkPixbufAnimation *
-gtk_smiley_tree_image (GtkIMHtml     *imhtml,
-		       const gchar   *sml,
-		       const gchar   *text)
-{
-	GtkIMHtmlSmiley *smiley;
-
-	smiley = gtk_imhtml_smiley_get(imhtml,sml,text);
-
-	if (!smiley)
-		return NULL;
-
-	return gtk_smiley_get_image(smiley);
-}
-
 #define VALID_TAG(x)	do { \
 			if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) {	\
 				if (tag) *tag = g_strndup (string, strlen (x));		\
@@ -2695,6 +2680,8 @@
 	ws = g_malloc(len + 1);
 	ws[0] = '\0';
 
+	g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(0));
+
 	gtk_text_buffer_begin_user_action(imhtml->text_buffer);
 	while (pos < len) {
 		if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) {
@@ -3547,6 +3534,8 @@
 	}
 	gtk_text_buffer_delete(imhtml->text_buffer, start, end);
 
+	g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(0));
+
 	g_object_unref(object);
 }
 
@@ -4983,12 +4972,33 @@
 	GdkPixbufAnimation *annipixbuf = NULL;
 	GtkWidget *icon = NULL;
 	GtkTextChildAnchor *anchor = NULL;
-	char *unescaped = purple_unescape_html(smiley);
-	GtkIMHtmlSmiley *imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
+	char *unescaped;
+	GtkIMHtmlSmiley *imhtml_smiley;
 	GtkWidget *ebox = NULL;
+	int numsmileys_thismsg, numsmileys_total;
+
+	/*
+	 * This GtkIMHtml has the maximum number of smileys allowed, so don't
+	 * add any more.  We do this for performance reasons, because smileys
+	 * are apparently pretty inefficient.  Hopefully we can remove this
+	 * restriction when we're using a better HTML widget.
+	 */
+	numsmileys_thismsg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg"));
+	if (numsmileys_thismsg >= 30) {
+		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
+		return;
+	}
+	numsmileys_total = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total"));
+	if (numsmileys_total >= 300) {
+		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
+		return;
+	}
+
+	unescaped = purple_unescape_html(smiley);
+	imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
 
 	if (imhtml->format_functions & GTK_IMHTML_SMILEY) {
-		annipixbuf = gtk_smiley_tree_image(imhtml, sml, unescaped);
+		annipixbuf = imhtml_smiley ? gtk_smiley_get_image(imhtml_smiley) : NULL;
 		if (annipixbuf) {
 			if (gdk_pixbuf_animation_is_static_image(annipixbuf)) {
 				pixbuf = gdk_pixbuf_animation_get_static_image(annipixbuf);
@@ -5042,6 +5052,9 @@
 		if (ebox)
 			gtk_container_add(GTK_CONTAINER(ebox), icon);
 		gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor);
+
+		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1));
+		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1));
 	} else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) {
 		anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
 		imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, g_object_ref(anchor));
@@ -5054,6 +5067,9 @@
 			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
 			gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor);
 		}
+
+		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1));
+		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1));
 	} else {
 		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
 	}