changeset 27805:80d3f4ff1cae

- fixed the offset of encoding field in ODC frame to be sent to peer. - added sanitize_utf8() to purple_plugin_oscar_convert_to_utf8() as nosuke pointed it out. - altered encoding candidates in purple_plugin_oscar_decode_im_part() to handle UTF-8 properly. - now direct IM with multi-byte characters works correctly.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 20 Mar 2008 11:48:40 +0000
parents d44a96d49ee5
children 07915e7a4c08
files libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/odc.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 4 files changed, 24 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icbm.c	Wed Mar 19 19:23:41 2008 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Mar 20 11:48:40 2008 +0000
@@ -512,7 +512,7 @@
 #endif
 	//yaz
 	// convert msg to ascii first. if it succeed, send as plain ascii.
-	// if it fails, convert msg into ucs-2be, and send it. 
+	// if it fails, convert msg into UTF-16BE, and send it. 
 	ucs = g_convert(msg, strlen(msg), "ASCII", "UTF-8", NULL, &bytes, NULL);
 	if(ucs){
 		byte_stream_new(&hdrbs, 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2);
--- a/libpurple/protocols/oscar/odc.c	Wed Mar 19 19:23:41 2008 +0000
+++ b/libpurple/protocols/oscar/odc.c	Thu Mar 20 11:48:40 2008 +0000
@@ -101,22 +101,28 @@
 	byte_stream_new(&bs, length + frame->payload.len);
 	byte_stream_putraw(&bs, conn->magic, 4);
 	byte_stream_put16(&bs, length);
+
 	byte_stream_put16(&bs, frame->type);
 	byte_stream_put16(&bs, frame->subtype);
 	byte_stream_put16(&bs, 0x0000);
+
 	byte_stream_putraw(&bs, frame->cookie, 8);
 	byte_stream_put16(&bs, 0x0000);
 	byte_stream_put16(&bs, 0x0000);
 	byte_stream_put16(&bs, 0x0000);
 	byte_stream_put16(&bs, 0x0000);
+
 	byte_stream_put32(&bs, frame->payload.len);
-	byte_stream_put16(&bs, 0x0000);
 	byte_stream_put16(&bs, frame->encoding);
 	byte_stream_put16(&bs, 0x0000);
+	byte_stream_put16(&bs, 0x0000);
+
 	byte_stream_put16(&bs, frame->flags);
 	byte_stream_put16(&bs, 0x0000);
 	byte_stream_put16(&bs, 0x0000);
+
 	byte_stream_putraw(&bs, frame->sn, 32);
+
 	byte_stream_putraw(&bs, frame->payload.data, frame->payload.len);
 
 	peer_connection_send(conn, &bs);
@@ -496,13 +502,17 @@
 	frame->type = byte_stream_get16(bs);
 	frame->subtype = byte_stream_get16(bs);
 	byte_stream_advance(bs, 2);
+
 	byte_stream_getrawbuf(bs, frame->cookie, 8);
 	byte_stream_advance(bs, 8);
+
 	frame->payload.len = byte_stream_get32(bs);
 	frame->encoding = byte_stream_get16(bs);
 	byte_stream_advance(bs, 4);
+
 	frame->flags = byte_stream_get16(bs);
 	byte_stream_advance(bs, 4);
+
 	byte_stream_getrawbuf(bs, frame->sn, 32);
 
 	purple_debug_info("oscar", "Incoming ODC frame from %s with "
--- a/libpurple/protocols/oscar/oscar.c	Wed Mar 19 19:23:41 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Mar 20 11:48:40 2008 +0000
@@ -394,7 +394,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'))
@@ -417,7 +417,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;
 }
 
 /**
@@ -453,11 +455,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";
@@ -4153,9 +4155,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;
@@ -4215,12 +4215,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) {
--- a/libpurple/protocols/oscar/oscar.h	Wed Mar 19 19:23:41 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Mar 20 11:48:40 2008 +0000
@@ -756,6 +756,7 @@
 #define AIM_CHARSET_ASCII		0x0000
 #define AIM_CHARSET_UNICODE	0x0002 /* UTF-16BE */
 #define AIM_CHARSET_CUSTOM	0x0003
+#define AIM_CHARSET_QUIRKUTF8	0x000d /* iChat and AIM6 use this in the meaning of UTF-8 in ODC. --yaz */
 
 /*
  * Multipart message structures.