diff libpurple/protocols/oscar/oscar.c @ 27897:7cda79469830

propagate from branch 'im.pidgin.pidgin' (head 05c26e9f58c2ab03f9f6d60143405f368789957d) to branch 'im.pidgin.pidgin.yaz' (head a7be4ac869031429b110ed879d253a9daa1e8717)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 09 Oct 2008 09:27:47 +0000
parents 9396a2124893 5c76f76ee9db
children 6ed03eec37d9
line wrap: on
line diff
--- a/libpurple/protocols/oscar/oscar.c	Thu Oct 02 21:11:08 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Oct 09 09:27:47 2008 +0000
@@ -306,7 +306,25 @@
 	gchar *utf8 = NULL;
 
 	if ((encoding == NULL) || encoding[0] == '\0') {
-		purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");
+		purple_debug_info("yaz oscar", "Empty encoding, validate as UTF-8\n");
+		if(g_utf8_validate(text, textlen, NULL)){
+			gsize newlen;
+			utf8 = sanitize_utf(text, textlen, &newlen);
+			goto done;
+		}
+		// not UTF-8
+		purple_debug_info("yaz oscar", "Empty encoding, assuming UTF-16BE\n");
+		sanitize_ucs((gchar *)text, textlen);
+		utf8 = g_convert(text, textlen, "UTF-8", "UTF-16BE", NULL, NULL, NULL);
+		if(utf8){
+			if(!g_utf8_validate(utf8, strlen(utf8), NULL)){
+				purple_debug_info("yaz oscar", "Invalid conversion\n");
+				g_free(utf8);
+				utf8 = NULL;
+			}
+		} else {
+			purple_debug_info("yaz oscar", "Conversion failed\n");
+		}
 	} else if (!g_ascii_strcasecmp(encoding, "iso-8859-1")) {
 		utf8 = g_convert(text, textlen, "UTF-8", "iso-8859-1", NULL, NULL, NULL);
 	} else if (!g_ascii_strcasecmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1") ||
@@ -321,6 +339,7 @@
 		 * and do something (un)reasonable with that, and not
 		 * mess up too much else. */
 		const gchar *charset = purple_account_get_string(account, "encoding", NULL);
+		sanitize_ucs((gchar *)text, textlen);
 		if (charset) {
 			gsize len;
 			utf8 = g_convert(text, textlen, charset, "UTF-16BE", &len, NULL, NULL);
@@ -352,7 +371,7 @@
 		else
 			utf8 = g_strndup(text, textlen);
 	}
-
+done:
 	return utf8;
 }
 
@@ -377,7 +396,7 @@
 static gchar *
 purple_plugin_oscar_convert_to_utf8(const gchar *data, gsize datalen, const char *charsetstr, gboolean fallback)
 {
-	gchar *ret = NULL;
+	gchar *ret = NULL, *ret2 = NULL;
 	GError *err = NULL;
 
 	if ((charsetstr == NULL) || (*charsetstr == '\0'))
@@ -400,7 +419,9 @@
 			purple_debug_warning("oscar", "String is not valid UTF-8.\n");
 	}
 
-	return ret;
+	ret2 = sanitize_utf(ret, -1, NULL);
+	g_free(ret);
+	return ret2;
 }
 
 /**
@@ -436,11 +457,11 @@
 	} else if (charset == AIM_CHARSET_ASCII) {
 		/* Should just be "ASCII" */
 		charsetstr1 = "ASCII";
-		charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
-	} else if (charset == 0x000d) {
+		charsetstr2 = "UTF-8";
+	} else if (charset == AIM_CHARSET_QUIRKUTF8) {
 		/* Mobile AIM client on a Nokia 3100 and an LG VX6000 */
-		charsetstr1 = "ISO-8859-1";
-		charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+		charsetstr1 = "UTF-8";  //iChat use 0x000d when it sends UTF-8. --yaz
+		charsetstr2 = "ISO-8859-1";
 	} else {
 		/* Unknown, hope for valid UTF-8... */
 		charsetstr1 = "UTF-8";
@@ -509,6 +530,7 @@
 		if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b)))
 		{
 			*msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
+			botch_ucs(*msg, msglen);
 			if (*msg != NULL)
 			{
 				*charset = AIM_CHARSET_UNICODE;
@@ -536,13 +558,18 @@
 	 * XXX - We need a way to only attempt to convert if we KNOW "from"
 	 * can be converted to "charsetstr"
 	 */
-	*msg = g_convert(from, -1, charsetstr, "UTF-8", NULL, &msglen, &err);
+#ifndef _WIN32
+	/* nosuke reported that this portion caused unexpected
+	 * conversion from utf-8 fullwidth tilde/numbers/alphabets to
+	 * halfwidth ones on windows environment. --yaz */
+	*msg = g_convert(from, -1, charsetstr, "UTF-8", NULL, &msglen, &errL);
 	if (*msg != NULL) {
 		*charset = AIM_CHARSET_CUSTOM;
 		*charsubset = 0x0000;
 		*msglen_int = msglen;
 		return;
 	}
+#endif
 
 	purple_debug_info("oscar", "Conversion from UTF-8 to %s failed (%s), falling back to unicode.\n",
 					  charsetstr, err->message);
@@ -552,7 +579,8 @@
 	/*
 	 * Nothing else worked, so send as UTF-16BE.
 	 */
-	*msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
+	*msg = g_convert(from, strlen(from), "UTF-16BE", "UTF-8", NULL, &msglen, &err);
+	botch_ucs(*msg, msglen);
 	if (*msg != NULL) {
 		*charset = AIM_CHARSET_UNICODE;
 		*charsubset = 0x0000;
@@ -2241,6 +2269,8 @@
 		tmp = purple_plugin_oscar_decode_im_part(account, userinfo->sn, curpart->charset,
 				curpart->charsubset, curpart->data, curpart->datalen);
 		if (tmp != NULL) {
+			purple_str_strip_char(tmp, 0x0d); // yaz: strip CR
+//			purple_debug_info("yaz oscar", "tmp=%s",tmp);
 			g_string_append(message, tmp);
 			g_free(tmp);
 		}
@@ -2343,6 +2373,7 @@
 		char *encoding, *utf8name, *tmp;
 		GHashTable *components;
 
+//		purple_debug_info("yaz oscar", "chat request %s\n", args->msg);
 		if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange) {
 			g_free(message);
 			return 1;
@@ -2365,6 +2396,8 @@
 		g_hash_table_replace(components, g_strdup("room"), utf8name);
 		g_hash_table_replace(components, g_strdup("exchange"),
 				g_strdup_printf("%d", args->info.chat.roominfo.exchange));
+		purple_debug_info("yaz oscar", "about to call serv_got_chat_invite\n");
+//		purple_debug_info("yaz oscar", "name=%s message=%s\n", name ? name : args->info.chat.roominfo.name, message);
 		serv_got_chat_invite(gc,
 				     utf8name,
 				     userinfo->sn,
@@ -2586,7 +2619,7 @@
 	 * for this suck-ass part of the protocol by splitting the string into at
 	 * most 1 baby string.
 	 */
-	msg1 = g_strsplit(args->msg, "\376", (args->type == 0x01 ? 1 : 0));
+	msg1 = g_strsplit(args->msg, "\376", (args->type == 0x01 ? 1 : 0)); // \376 is 0xfe
 	for (numtoks=0; msg1[numtoks]; numtoks++);
 	msg2 = (gchar **)g_malloc((numtoks+1)*sizeof(gchar *));
 	for (i=0; msg1[i]; i++) {
@@ -4263,9 +4296,7 @@
 {
 	GString *msg;
 	GString *data;
-	gchar *tmp;
-	int tmplen;
-	guint16 charset, charsubset;
+	guint16 charset;
 	GData *attribs;
 	const char *start, *end, *last;
 	int oscar_id = 0;
@@ -4325,12 +4356,8 @@
 
 	g_string_append(msg, "</BODY></HTML>");
 
-	/* Convert the message to a good encoding */
-	purple_plugin_oscar_convert_to_best_encoding(conn->od->gc,
-			conn->sn, msg->str, &tmp, &tmplen, &charset, &charsubset);
-	g_string_free(msg, TRUE);
-	msg = g_string_new_len(tmp, tmplen);
-	g_free(tmp);
+	/* iChat and AIM6 use 0x000d to send UTF8. moreover, AIM6 persists only to UTF8! --yaz */
+	charset = AIM_CHARSET_QUIRKUTF8;
 
 	/* Append any binary data that we may have */
 	if (oscar_id) {
@@ -4572,7 +4599,8 @@
 
 	charset = oscar_charset_check(str);
 	if (charset == AIM_CHARSET_UNICODE) {
-		encoded = g_convert(str, -1, "UTF-16BE", "UTF-8", NULL, ret_len, NULL);
+		encoded = g_convert(str, strlen(str), "UTF-16BE", "UTF-8", NULL, ret_len, NULL);
+		botch_ucs(encoded, *ret_len);
 		*encoding = "unicode-2-0";
 	} else if (charset == AIM_CHARSET_CUSTOM) {
 		encoded = g_convert(str, -1, "ISO-8859-1", "UTF-8", NULL, ret_len, NULL);
@@ -5698,7 +5726,7 @@
 		charsetstr = "unicode-2-0";
 	else if (charset == AIM_CHARSET_CUSTOM)
 		charsetstr = "iso-8859-1";
-	aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "en");
+	aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "JA");
 	g_free(buf2);
 	g_free(buf);