changeset 27103:2f297ab00e9d

merge of '054ca20dffd917fc57972d8756d9c15ead22fd85' and 'e1bd4479e6211023f43781c3f4864d56fc9bb1b3'
author Paul Aurich <paul@darkrain42.org>
date Wed, 03 Jun 2009 19:34:42 +0000
parents a0e3e4f37702 (current diff) bf9db4c67679 (diff)
children 3ada8179ff2a
files ChangeLog
diffstat 8 files changed, 100 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
--- 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);
--- 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);
 		}
--- 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().
--- 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().
--- 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);
--- 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 ? "<B>" : "</B>",
 						italic ? "<I>" : "</I>",
 						underline ? "<U>" : "</U>",
-						t, 
+						rtl ? "<SPAN style=\"direction:rtl;text-align:right;\">" : "",
+						t,
+						rtl ? "</SPAN>" : "",
 						bold ? "</B>" : "<B>",
 						italic ? "</I>" : "<I>",
 						underline ? "</U>" : "<U>"