changeset 28482:22c65c1090a8

jabber: Use a better method for dealing with terminating slashes in JIDs. This saves an allocation/free in jabber_normalize
author Paul Aurich <paul@darkrain42.org>
date Sat, 29 Aug 2009 02:38:28 +0000
parents d7cfffdd35e6
children 49308951822a
files libpurple/protocols/jabber/jutil.c libpurple/tests/test_jabber_jutil.c
diffstat 2 files changed, 27 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/jutil.c	Sat Aug 29 02:36:57 2009 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Sat Aug 29 02:38:28 2009 +0000
@@ -277,8 +277,8 @@
 #endif /* USE_IDN */
 }
 
-JabberID*
-jabber_id_new(const char *str)
+static JabberID*
+jabber_id_new_internal(const char *str, gboolean allow_terminating_slash)
 {
 	const char *at = NULL;
 	const char *slash = NULL;
@@ -323,7 +323,7 @@
 						/* JIDs cannot start with / */
 						return NULL;
 					}
-					if (c[1] == '\0') {
+					if (c[1] == '\0' && !allow_terminating_slash) {
 						/* JIDs cannot end with / */
 						return NULL;
 					}
@@ -386,14 +386,16 @@
 			jid->node = g_ascii_strdown(str, at - str);
 			if (slash) {
 				jid->domain = g_ascii_strdown(at + 1, slash - (at + 1));
-				jid->resource = g_strdup(slash + 1);
+				if (*(slash + 1))
+					jid->resource = g_strdup(slash + 1);
 			} else {
 				jid->domain = g_ascii_strdown(at + 1, -1);
 			}
 		} else {
 			if (slash) {
 				jid->domain = g_ascii_strdown(str, slash - str);
-				jid->resource = g_strdup(slash + 1);
+				if (*(slash + 1))
+					jid->resource = g_strdup(slash + 1);
 			} else {
 				jid->domain = g_ascii_strdown(str, -1);
 			}
@@ -421,14 +423,16 @@
 		node = g_utf8_casefold(str, at-str);
 		if(slash) {
 			domain = g_utf8_casefold(at+1, slash-(at+1));
-			jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
+			if (*(slash + 1))
+				jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
 		} else {
 			domain = g_utf8_casefold(at+1, -1);
 		}
 	} else {
 		if(slash) {
 			domain = g_utf8_casefold(str, slash-str);
-			jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
+			if (*(slash + 1))
+				jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
 		} else {
 			domain = g_utf8_casefold(str, -1);
 		}
@@ -500,30 +504,20 @@
 	return out;
 }
 
+JabberID *
+jabber_id_new(const char *str)
+{
+	return jabber_id_new_internal(str, FALSE);
+}
+
 const char *jabber_normalize(const PurpleAccount *account, const char *in)
 {
 	PurpleConnection *gc = account ? account->gc : NULL;
 	JabberStream *js = gc ? gc->proto_data : NULL;
 	static char buf[3072]; /* maximum legal length of a jabber jid */
 	JabberID *jid;
-	char *tmp;
-	size_t len = strlen(in);
 
-	/*
-	 * If the JID ends with a '/', jabber_id_new is going to throw it away as
-	 * invalid.  However, this is what the UI generates for a JID with no
-	 * resource. Deal with that by dropping away the '/'...
-	 */
-	if (in[len - 1] == '/')
-		tmp = g_strndup(in, len - 1);
-	else
-		tmp = (gchar *)in;
-
-	jid = jabber_id_new(tmp);
-
-	if (tmp != in)
-		g_free(tmp);
-
+	jid = jabber_id_new_internal(in, TRUE);
 	if(!jid)
 		return NULL;
 
--- a/libpurple/tests/test_jabber_jutil.c	Sat Aug 29 02:36:57 2009 +0000
+++ b/libpurple/tests/test_jabber_jutil.c	Sat Aug 29 02:38:28 2009 +0000
@@ -153,6 +153,14 @@
 }
 END_TEST
 
+START_TEST(test_jabber_normalize)
+{
+	assert_string_equal("paul@darkrain42.org", jabber_normalize(NULL, "PaUL@DaRkRain42.org"));
+	assert_string_equal("paul@darkrain42.org", jabber_normalize(NULL, "PaUL@DaRkRain42.org/"));
+	assert_string_equal("paul@darkrain42.org", jabber_normalize(NULL, "PaUL@DaRkRain42.org/resource"));
+}
+END_TEST
+
 Suite *
 jabber_jutil_suite(void)
 {
@@ -172,6 +180,7 @@
 	tcase_add_test(tc, test_nodeprep_validate_illegal_chars);
 	tcase_add_test(tc, test_nodeprep_validate_too_long);
 	tcase_add_test(tc, test_jabber_id_new);
+	tcase_add_test(tc, test_jabber_normalize);
 	suite_add_tcase(s, tc);
 
 	return s;