1.1 --- a/ChangeLog
1.2 +++ b/ChangeLog
1.3 @@ -27,7 +27,7 @@
1.4
1.5 MSN:
1.6 * Fix CVE-2010-0277, a possible remote crash when parsing an incoming
1.7 - SLP message. Discovered by Fabian Yamaguchi.
1.8 + SLP message. (Discovered by Fabian Yamaguchi)
1.9 * File transfer requests will no longer cause a crash if you delete the
1.10 file before the other side accepts.
1.11 * Received files will no longer hold an extra lock after completion,
1.12 @@ -74,6 +74,8 @@
1.13 Mohta)
1.14
1.15 Pidgin:
1.16 + * Fix CVE-2010-0423, a denial of service attack due to the parsing
1.17 + of large numbers of smileys. (Discovered by Antti Hayrynen)
1.18 * Correctly size conversation and status box entries when the
1.19 interior-focus style property is diabled. (Gabriel Schulhof)
1.20 * Correctly handle a multiline text field being required in a
2.1 --- a/pidgin/gtkimhtml.c
2.2 +++ b/pidgin/gtkimhtml.c
2.3 @@ -2222,21 +2222,6 @@
2.4 return smiley->icon;
2.5 }
2.6
2.7 -static GdkPixbufAnimation *
2.8 -gtk_smiley_tree_image (GtkIMHtml *imhtml,
2.9 - const gchar *sml,
2.10 - const gchar *text)
2.11 -{
2.12 - GtkIMHtmlSmiley *smiley;
2.13 -
2.14 - smiley = gtk_imhtml_smiley_get(imhtml,sml,text);
2.15 -
2.16 - if (!smiley)
2.17 - return NULL;
2.18 -
2.19 - return gtk_smiley_get_image(smiley);
2.20 -}
2.21 -
2.22 #define VALID_TAG(x) do { \
2.23 if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \
2.24 if (tag) *tag = g_strndup (string, strlen (x)); \
2.25 @@ -2695,6 +2680,8 @@
2.26 ws = g_malloc(len + 1);
2.27 ws[0] = '\0';
2.28
2.29 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(0));
2.30 +
2.31 gtk_text_buffer_begin_user_action(imhtml->text_buffer);
2.32 while (pos < len) {
2.33 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) {
2.34 @@ -3547,6 +3534,8 @@
2.35 }
2.36 gtk_text_buffer_delete(imhtml->text_buffer, start, end);
2.37
2.38 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(0));
2.39 +
2.40 g_object_unref(object);
2.41 }
2.42
2.43 @@ -4983,12 +4972,33 @@
2.44 GdkPixbufAnimation *annipixbuf = NULL;
2.45 GtkWidget *icon = NULL;
2.46 GtkTextChildAnchor *anchor = NULL;
2.47 - char *unescaped = purple_unescape_html(smiley);
2.48 - GtkIMHtmlSmiley *imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
2.49 + char *unescaped;
2.50 + GtkIMHtmlSmiley *imhtml_smiley;
2.51 GtkWidget *ebox = NULL;
2.52 + int numsmileys_thismsg, numsmileys_total;
2.53 +
2.54 + /*
2.55 + * This GtkIMHtml has the maximum number of smileys allowed, so don't
2.56 + * add any more. We do this for performance reasons, because smileys
2.57 + * are apparently pretty inefficient. Hopefully we can remove this
2.58 + * restriction when we're using a better HTML widget.
2.59 + */
2.60 + numsmileys_thismsg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg"));
2.61 + if (numsmileys_thismsg >= 30) {
2.62 + gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
2.63 + return;
2.64 + }
2.65 + numsmileys_total = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total"));
2.66 + if (numsmileys_total >= 300) {
2.67 + gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
2.68 + return;
2.69 + }
2.70 +
2.71 + unescaped = purple_unescape_html(smiley);
2.72 + imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
2.73
2.74 if (imhtml->format_functions & GTK_IMHTML_SMILEY) {
2.75 - annipixbuf = gtk_smiley_tree_image(imhtml, sml, unescaped);
2.76 + annipixbuf = imhtml_smiley ? gtk_smiley_get_image(imhtml_smiley) : NULL;
2.77 if (annipixbuf) {
2.78 if (gdk_pixbuf_animation_is_static_image(annipixbuf)) {
2.79 pixbuf = gdk_pixbuf_animation_get_static_image(annipixbuf);
2.80 @@ -5042,6 +5052,9 @@
2.81 if (ebox)
2.82 gtk_container_add(GTK_CONTAINER(ebox), icon);
2.83 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor);
2.84 +
2.85 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1));
2.86 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1));
2.87 } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) {
2.88 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
2.89 imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, g_object_ref(anchor));
2.90 @@ -5054,6 +5067,9 @@
2.91 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
2.92 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor);
2.93 }
2.94 +
2.95 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1));
2.96 + g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1));
2.97 } else {
2.98 gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
2.99 }