# HG changeset patch # User Paul Aurich # Date 1244057682 0 # Node ID 2f297ab00e9d31044c5d169d2a3036ae2e33bba2 # Parent a0e3e4f3770285b3ccc6664f075c4f417576917c# Parent bf9db4c67679b866ff34e59a22617f46ead02aa2 merge of '054ca20dffd917fc57972d8756d9c15ead22fd85' and 'e1bd4479e6211023f43781c3f4864d56fc9bb1b3' diff -r a0e3e4f37702 -r 2f297ab00e9d ChangeLog --- a/ChangeLog Wed Jun 03 19:34:26 2009 +0000 +++ b/ChangeLog Wed Jun 03 19:34:42 2009 +0000 @@ -41,6 +41,8 @@ * /affiliate and /role will now list the room members with the specified affiliation/role if possible. (Andrei Mozzhuhin) * Put section breaks between resources in "Get Info" to improve readability. + * Silently remove invalid XML 1.0 entities (e.g. ASCII control characters) + from sent messages. * XHTML markup is only included in outgoing messages when the message contains formatting. * Show when the user was last logged in when doing "Get Info" on an offline @@ -82,6 +84,7 @@ rejoin. * Always set unseen-count and unseen-state on conversations. (Joshua Stein) + * Fix a bug in 'Conversation Colors' plugin for RTL messages. Finch: * The hardware cursor is updated correctly. This will be useful diff -r a0e3e4f37702 -r 2f297ab00e9d ChangeLog.API --- a/ChangeLog.API Wed Jun 03 19:34:26 2009 +0000 +++ b/ChangeLog.API Wed Jun 03 19:34:42 2009 +0000 @@ -36,6 +36,7 @@ * purple_global_proxy_set_info * purple_group_destroy * purple_log_get_activity_score + * purple_markup_is_rtl * purple_network_force_online * purple_network_set_stun_server * purple_network_set_turn_server @@ -48,6 +49,7 @@ * purple_request_field_get_ui_data * purple_request_field_set_ui_data * purple_strequal + * purple_utf8_strip_unprintables * xmlnode_from_file * xmlnode_get_parent * xmlnode_set_attrib_full diff -r a0e3e4f37702 -r 2f297ab00e9d libpurple/protocols/jabber/message.c --- a/libpurple/protocols/jabber/message.c Wed Jun 03 19:34:26 2009 +0000 +++ b/libpurple/protocols/jabber/message.c Wed Jun 03 19:34:42 2009 +0000 @@ -1190,7 +1190,9 @@ jm->typing_style |= JM_TS_JEP_0022; } - purple_markup_html_to_xhtml(msg, &xhtml, &jm->body); + tmp = purple_utf8_strip_unprintables(msg); + purple_markup_html_to_xhtml(tmp, &xhtml, &jm->body); + g_free(tmp); tmp = jabber_message_smileyfy_xhtml(jm, xhtml); if (tmp) { g_free(xhtml); @@ -1231,7 +1233,9 @@ jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); jm->id = jabber_get_next_id(jm->js); + tmp = purple_utf8_strip_unprintables(msg); purple_markup_html_to_xhtml(msg, &xhtml, &jm->body); + g_free(tmp); tmp = jabber_message_smileyfy_xhtml(jm, xhtml); if (tmp) { g_free(xhtml); diff -r a0e3e4f37702 -r 2f297ab00e9d libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Wed Jun 03 19:34:26 2009 +0000 +++ b/libpurple/protocols/msn/msn.c Wed Jun 03 19:34:42 2009 +0000 @@ -1281,7 +1281,7 @@ imdata->gc = gc; imdata->who = who; imdata->msg = body_str; - imdata->flags = flags; + imdata->flags = flags & ~PURPLE_MESSAGE_SEND; imdata->when = time(NULL); purple_timeout_add(0, msn_send_me_im, imdata); } diff -r a0e3e4f37702 -r 2f297ab00e9d libpurple/util.c --- a/libpurple/util.c Wed Jun 03 19:34:26 2009 +0000 +++ b/libpurple/util.c Wed Jun 03 19:34:42 2009 +0000 @@ -1041,6 +1041,35 @@ return ret; } +gboolean purple_markup_is_rtl(const char *html) +{ + GData *attributes; + const gchar *start, *end; + gboolean res = FALSE; + + if (purple_markup_find_tag("span", html, &start, &end, &attributes)) + { + /* tmp is a member of attributes and is free with g_datalist_clear call */ + const char *tmp = g_datalist_get_data(&attributes, "dir"); + if (tmp && !g_ascii_strcasecmp(tmp, "RTL")) + res = TRUE; + if (!res) + { + tmp = g_datalist_get_data(&attributes, "style"); + if (tmp) + { + char *tmp2 = purple_markup_get_css_property(tmp, "direction"); + if (tmp2 && !g_ascii_strcasecmp(tmp2, "RTL")) + res = TRUE; + g_free(tmp2); + } + + } + g_datalist_clear(&attributes); + } + return res; +} + gboolean purple_markup_find_tag(const char *needle, const char *haystack, const char **start, const char **end, GData **attributes) @@ -4395,6 +4424,34 @@ return g_string_free(workstr, FALSE); } +gchar * +purple_utf8_strip_unprintables(const gchar *str) +{ + gchar *workstr, *iter; + + g_return_val_if_fail(str != NULL, NULL); + g_return_val_if_fail(g_utf8_validate(str, -1, NULL), NULL); + + workstr = iter = g_new(gchar, strlen(str) + 1); + while (*str) { + gunichar c = g_utf8_get_char(str); + const gchar *next = g_utf8_next_char(str); + size_t len = next - str; + + if (g_unichar_isprint(c)) { + memcpy(iter, str, len); + iter += len; + } + + str = next; + } + + /* nul-terminate the new string */ + *iter = '\0'; + + return workstr; +} + /* * This function is copied from g_strerror() but changed to use * gai_strerror(). diff -r a0e3e4f37702 -r 2f297ab00e9d libpurple/util.h --- a/libpurple/util.h Wed Jun 03 19:34:26 2009 +0000 +++ b/libpurple/util.h Wed Jun 03 19:34:42 2009 +0000 @@ -579,6 +579,16 @@ */ char * purple_markup_get_css_property(const gchar *style, const gchar *opt); +/** + * Check if the given HTML contains RTL text. + * + * @param html The HTML text. + * + * @return TRUE if the text contains RTL text, FALSE otherwise. + * + * @since 2.6.0 + */ +gboolean purple_markup_is_rtl(const char *html); /*@}*/ @@ -1238,6 +1248,21 @@ gchar *purple_utf8_salvage(const char *str); /** + * Removes unprintable characters from a UTF-8 string. These characters + * (in particular low-ASCII characters) are invalid in XML 1.0 and thus + * are not allowed in XMPP and are rejected by libxml2 by default. This + * function uses g_unichar_isprint to determine what characters should + * be stripped. The returned string must be freed by the caller. + * + * @param str A valid UTF-8 string. + * + * @return A newly allocated UTF-8 string without the unprintable characters. + * + * @see g_unichar_isprint + */ +gchar *purple_utf8_strip_unprintables(const gchar *str); + +/** * Return the UTF-8 version of gai_strerror(). It calls gai_strerror() * then converts the result to UTF-8. This function is analogous to * g_strerror(). diff -r a0e3e4f37702 -r 2f297ab00e9d pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed Jun 03 19:34:26 2009 +0000 +++ b/pidgin/gtkconv.c Wed Jun 03 19:34:42 2009 +0000 @@ -5629,38 +5629,6 @@ #endif } -/* Returns true if the given HTML contains RTL text */ -static gboolean -html_is_rtl(const char *html) -{ - GData *attributes; - const gchar *start, *end; - gboolean res = FALSE; - - if (purple_markup_find_tag("span", html, &start, &end, &attributes)) - { - /* tmp is a member of attributes and is free with g_datalist_clear call */ - const char *tmp = g_datalist_get_data(&attributes, "dir"); - if (tmp && !g_ascii_strcasecmp(tmp, "RTL")) - res = TRUE; - if (!res) - { - tmp = g_datalist_get_data(&attributes, "style"); - if (tmp) - { - char *tmp2 = purple_markup_get_css_property(tmp, "direction"); - if (tmp2 && !g_ascii_strcasecmp(tmp2, "RTL")) - res = TRUE; - g_free(tmp2); - } - - } - g_datalist_clear(&attributes); - } - return res; -} - - static void pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, const char *message, PurpleMessageFlags flags, @@ -5822,7 +5790,7 @@ } /* Bi-Directional support - set timestamp direction using unicode characters */ - is_rtl_message = html_is_rtl(message); + is_rtl_message = purple_markup_is_rtl(message); /* Enforce direction only if message is RTL - doesn't effect LTR users */ if (is_rtl_message) str_embed_direction_chars(&mdate); diff -r a0e3e4f37702 -r 2f297ab00e9d pidgin/plugins/convcolors.c --- a/pidgin/plugins/convcolors.c Wed Jun 03 19:34:26 2009 +0000 +++ b/pidgin/plugins/convcolors.c Wed Jun 03 19:34:42 2009 +0000 @@ -101,6 +101,7 @@ gboolean bold, italic, underline; int f; const char *color; + gboolean rtl = FALSE; for (i = 0; formats[i].prefix; i++) if (flags & formats[i].flag) @@ -126,6 +127,7 @@ bold = (f & FONT_BOLD); italic = (f & FONT_ITALIC); underline = (f & FONT_UNDERLINE); + rtl = purple_markup_is_rtl(*displaying); if (purple_prefs_get_bool(PREF_IGNORE)) { @@ -156,11 +158,13 @@ } t = *displaying; - *displaying = g_strdup_printf("%s%s%s%s%s%s%s", + *displaying = g_strdup_printf("%s%s%s%s%s%s%s%s%s", bold ? "" : "", italic ? "" : "", underline ? "" : "", - t, + rtl ? "" : "", + t, + rtl ? "" : "", bold ? "" : "", italic ? "" : "", underline ? "" : ""