changeset 27104:3ada8179ff2a

merge of '6fc007db8432a45dd3273d0abcc8bb9a09b11ecf' and '8806e5fba5cdb38ef9be6799e7e829dc2a762a69'
author Paul Aurich <paul@darkrain42.org>
date Wed, 03 Jun 2009 21:57:19 +0000
parents 2f297ab00e9d (diff) 1d2b813faca7 (current diff)
children 7c864f388c96
files
diffstat 6 files changed, 56 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jun 03 21:46:05 2009 +0000
+++ b/ChangeLog	Wed Jun 03 21:57:19 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
@@ -50,8 +52,6 @@
 	  chat to avoid getting too many fetch requests).
 	* Fix an issue with Jabber (pre-XMPP) servers and the user's preference
 	  to require SSL not being respected.
-	* When using non-Cyrus SASL DIGEST-MD5 authentication, only specify the
-	  charset as UTF-8 if the username/password weren't converted to ISO-8859-1.
 
 	Yahoo:
 	* P2P file transfers.  (Sulabh Mahajan)
--- a/ChangeLog.API	Wed Jun 03 21:46:05 2009 +0000
+++ b/ChangeLog.API	Wed Jun 03 21:57:19 2009 +0000
@@ -49,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/auth.c	Wed Jun 03 21:46:05 2009 +0000
+++ b/libpurple/protocols/jabber/auth.c	Wed Jun 03 21:57:19 2009 +0000
@@ -784,29 +784,22 @@
 
 static char *
 generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
-		const char *cnonce, const char *a2, const char *realm,
-		gboolean *converted)
+		const char *cnonce, const char *a2, const char *realm)
 {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
 	guchar result[16];
 	size_t a1len;
+
 	gchar *a1, *convnode=NULL, *convpasswd = NULL, *ha1, *ha2, *kd, *x, *z;
 
-	if (converted)
-		*converted = TRUE;
-
 	if((convnode = g_convert(jid->node, -1, "iso-8859-1", "utf-8",
 					NULL, NULL, NULL)) == NULL) {
 		convnode = g_strdup(jid->node);
-		if (converted)
-			*converted = FALSE;
 	}
 	if(passwd && ((convpasswd = g_convert(passwd, -1, "iso-8859-1",
 						"utf-8", NULL, NULL, NULL)) == NULL)) {
 		convpasswd = g_strdup(passwd);
-		if (converted)
-			*converted = FALSE;
 	}
 
 	cipher = purple_ciphers_find_cipher("md5");
@@ -921,19 +914,18 @@
 				char *auth_resp;
 				char *buf;
 				char *cnonce;
-				gboolean converted_to_iso8859;
 
 				cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL),
 						g_random_int());
 
 				a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm);
 				auth_resp = generate_response_value(js->user,
-						purple_connection_get_password(js->gc), nonce, cnonce, a2, realm, &converted_to_iso8859);
+						purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
 				g_free(a2);
 
 				a2 = g_strdup_printf(":xmpp/%s", realm);
 				js->expected_rspauth = generate_response_value(js->user,
-						purple_connection_get_password(js->gc), nonce, cnonce, a2, realm, &converted_to_iso8859);
+						purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
 				g_free(a2);
 
 				g_string_append_printf(response, "username=\"%s\"", js->user->node);
@@ -944,8 +936,7 @@
 				g_string_append_printf(response, ",qop=auth");
 				g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm);
 				g_string_append_printf(response, ",response=%s", auth_resp);
-				if (!converted_to_iso8859)
-					g_string_append_printf(response, ",charset=utf-8");
+				g_string_append_printf(response, ",charset=utf-8");
 
 				g_free(auth_resp);
 				g_free(cnonce);
--- a/libpurple/protocols/jabber/message.c	Wed Jun 03 21:46:05 2009 +0000
+++ b/libpurple/protocols/jabber/message.c	Wed Jun 03 21:57:19 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/util.c	Wed Jun 03 21:46:05 2009 +0000
+++ b/libpurple/util.c	Wed Jun 03 21:57:19 2009 +0000
@@ -4424,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 21:46:05 2009 +0000
+++ b/libpurple/util.h	Wed Jun 03 21:57:19 2009 +0000
@@ -1248,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().