changeset 27505:5048054d319a

Use the ui_info hash table instead of prefs when passing the clientstring and distid from the UIs to the oscar prpl. I realized that using a pref wasn't great because it's persistent, and if you switch from a UI that sets one of those strings to a UI that doesn't hen we'll keep using the old value.
author Mark Doliner <mark@kingant.net>
date Wed, 08 Jul 2009 20:11:07 +0000
parents 4f24d5da4cb3
children 74e487f82f39
files libpurple/protocols/jabber/jutil.c libpurple/protocols/oscar/family_auth.c libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/oscar/util.c libpurple/server.c
diffstat 7 files changed, 111 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/jutil.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Wed Jul 08 20:11:07 2009 +0000
@@ -103,20 +103,86 @@
 JabberID*
 jabber_id_new(const char *str)
 {
-	char *at;
-	char *slash;
+	const char *at = NULL;
+	const char *slash = NULL;
+	const char *c;
+	gboolean needs_validation = FALSE;
 	char *node = NULL;
 	char *domain;
 	JabberID *jid;
 
-	if(!str || !g_utf8_validate(str, -1, NULL))
+	if (!str)
+		return NULL;
+
+	for (c = str; *c != '\0'; c++) {
+		switch (*c) {
+			case '@':
+				if (!slash) {
+					if (at) {
+						/* Multiple @'s in the node/domain portion, not a valid JID! */
+						return NULL;
+					}
+					at = c;
+				}
+				break;
+
+			case '/':
+				if (!slash)
+					slash = c;
+				break;
+
+			default:
+				/* make sure this character falls within the allowed ascii characters
+				 * specified in the nodeprep RFC.  If it's outside of this range,
+				 * the character is probably unicode and will be validated using the
+				 * more expensive UTF-8 compliant nodeprep functions
+				 */
+				if ( !(	('a' <= *c && *c <= '~') ||  /*a-z{|}~*/
+						('.' <= *c && *c <= '9') ||  /*./0123456789*/
+						('A' <= *c && *c <= '_') ||  /*A-Z[\]^_*/
+						(*c == ';')  ))              /*;*/
+				{
+					needs_validation = TRUE;
+				}
+				break;
+		}
+	}
+
+	if (!needs_validation) {
+		/* JID is made of only ASCII characters--just lowercase and return */
+		jid = g_new0(JabberID, 1);
+
+		if (at) {
+			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);
+			} 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);
+			} else {
+				jid->domain = g_ascii_strdown(str, -1);
+			}
+		}
+		return jid;
+	}
+
+	/*
+	 * If we get here, there are some non-ASCII chars in the string, so
+	 * we'll need to validate it, normalize, and finally do a full jabber
+	 * nodeprep on the jid.
+	 */
+
+	if (!g_utf8_validate(str, -1, NULL))
 		return NULL;
 
 	jid = g_new0(JabberID, 1);
 
-	at = g_utf8_strchr(str, -1, '@');
-	slash = g_utf8_strchr(str, -1, '/');
-
+	/* normalization */
 	if(at) {
 		node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC);
 		if(slash) {
@@ -144,6 +210,7 @@
 		g_free(domain);
 	}
 
+	/* and finally the jabber nodeprep */
 	if(!jabber_nodeprep_validate(jid->node) ||
 			!jabber_nameprep_validate(jid->domain) ||
 			!jabber_resourceprep_validate(jid->resource)) {
--- a/libpurple/protocols/oscar/family_auth.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Wed Jul 08 20:11:07 2009 +0000
@@ -141,12 +141,12 @@
 
 	aim_encode_password(password, password_encoded);
 
-	clientstring = purple_prefs_get_string("/plugins/prpl/oscar/clientstring");
-	if (clientstring == NULL)
-		clientstring = ci->clientstring;
-	distrib = purple_prefs_get_int("/plugins/prpl/oscar/distid");
-	if ((gint32)distrib == -1)
-		distrib = ci->distrib;
+	clientstring = oscar_get_ui_info_string(
+			od->icq ? "prpl-icq-clientstring" : "prpl-aim-clientstring",
+			ci->clientstring);
+	distrib = oscar_get_ui_info_int(
+			od->icq ? "prpl-icq-distid" : "prpl-aim-distid",
+			ci->distrib);
 
 	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
 	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
@@ -247,12 +247,12 @@
 
 	aim_encode_password_md5(password, password_len, key, digest);
 
-	clientstring = purple_prefs_get_string("/plugins/prpl/oscar/clientstring");
-	if (clientstring == NULL)
-		clientstring = ci->clientstring;
-	distrib = purple_prefs_get_int("/plugins/prpl/oscar/distid");
-	if ((gint32)distrib == -1)
-		distrib = ci->distrib;
+	clientstring = oscar_get_ui_info_string(
+			od->icq ? "prpl-icq-clientstring" : "prpl-aim-clientstring",
+			ci->clientstring);
+	distrib = oscar_get_ui_info_int(
+			od->icq ? "prpl-icq-distid" : "prpl-aim-distid",
+			ci->distrib);
 
 	aim_tlvlist_add_raw(&tlvlist, 0x0025, 16, digest);
 
--- a/libpurple/protocols/oscar/flap_connection.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Wed Jul 08 20:11:07 2009 +0000
@@ -77,14 +77,19 @@
 {
 	FlapFrame *frame;
 	GSList *tlvlist = NULL;
+	const char *clientstring;
 
 	frame = flap_frame_new(od, 0x01, 1152 + length);
 
 	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
 	aim_tlvlist_add_raw(&tlvlist, 0x0006, length, chipsahoy);
 
-	if (ci->clientstring)
-		aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring);
+	clientstring = oscar_get_ui_info_string(
+			od->icq ? "prpl-icq-clientstring" : "prpl-aim-clientstring",
+			ci->clientstring);
+
+	if (clientstring != NULL)
+		aim_tlvlist_add_str(&tlvlist, 0x0003, clientstring);
 	aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major);
 	aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor);
 	aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point);
--- a/libpurple/protocols/oscar/oscar.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Jul 08 20:11:07 2009 +0000
@@ -7102,18 +7102,6 @@
 	purple_prefs_add_none("/plugins/prpl/oscar");
 	purple_prefs_add_bool("/plugins/prpl/oscar/recent_buddies", FALSE);
 
-	/*
-	 * These two preferences will normally not be changed.  UIs can optionally
-	 * use them to override these two version fields which are sent to the
-	 * server when logging in.  AOL requested this change to allow clients to
-	 * use custom values.
-	 *
-	 * TODO: It would be more appropriate for UIs to put these in the hash
-	 * table returned by purple_core_get_ui_info().
-	 */
-	purple_prefs_add_string("/plugins/prpl/oscar/clientstring", NULL);
-	purple_prefs_add_int("/plugins/prpl/oscar/distid", -1);
-
 	purple_prefs_remove("/plugins/prpl/oscar/show_idle");
 	purple_prefs_remove("/plugins/prpl/oscar/always_use_rv_proxy");
 
--- a/libpurple/protocols/oscar/oscar.h	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Wed Jul 08 20:11:07 2009 +0000
@@ -1527,6 +1527,7 @@
 		(((*((buf)+2)) << 16) & 0x00ff0000) + \
 		(((*((buf)+3)) << 24) & 0xff000000))
 
+int oscar_get_ui_info_int(const char *str, int default_value);
 const char *oscar_get_ui_info_string(const char *str, const char *default_value);
 
 guint16 aimutil_iconsum(const guint8 *buf, int buflen);
--- a/libpurple/protocols/oscar/util.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/protocols/oscar/util.c	Wed Jul 08 20:11:07 2009 +0000
@@ -35,6 +35,20 @@
 #include "win32dep.h"
 #endif
 
+int oscar_get_ui_info_int(const char *str, int default_value)
+{
+	GHashTable *ui_info;
+
+	ui_info = purple_core_get_ui_info();
+	if (ui_info != NULL) {
+		gpointer value;
+		if (g_hash_table_lookup_extended(ui_info, str, NULL, value))
+			return GPOINTER_TO_INT(value);
+	}
+
+	return default_value;
+}
+
 const char *oscar_get_ui_info_string(const char *str, const char *default_value)
 {
 	GHashTable *ui_info;
--- a/libpurple/server.c	Wed Jul 08 19:46:50 2009 +0000
+++ b/libpurple/server.c	Wed Jul 08 20:11:07 2009 +0000
@@ -592,13 +592,10 @@
 	 */
 	flags |= PURPLE_MESSAGE_RECV;
 
-	if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->set_permit_deny == NULL) {
-		/* protocol does not support privacy, handle it ourselves */
-		if (!purple_privacy_check(account, who)) {
-			purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
-					account, who, msg, flags, (unsigned int)mtime);
-			return;
-		}
+	if (!purple_privacy_check(account, who)) {
+		purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
+				account, who, msg, flags, (unsigned int)mtime);
+		return;
 	}
 
 	/*