changeset 30382:47dfe1d54e9e

Fixed (I hope) #12284. incomingim_ch2_icqserverrelay() was doing something it wasn't supposed to. I suppose the packet format was reverse-engineered wrongly eons ago. The correct packet format can be found at http://iserverd.khstu.ru/oscar/message.html (and also in every open-source OSCAR client I could get my hands on). The funny thing is that before #12284 showed up everything worked right due to another bug. I'm too lazy to type out all the details, so I'll just include a reference to my conversation with Mark Doliner: http://www.pidgin.im/nopaste/102
author ivan.komarov@soc.pidgin.im
date Sat, 24 Jul 2010 18:14:29 +0000
parents a347a4cd1caf
children 502f25fd81b8
files libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 3 files changed, 31 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icbm.c	Sat Jul 24 17:32:00 2010 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Sat Jul 24 18:14:29 2010 +0000
@@ -1966,7 +1966,7 @@
 static void
 incomingim_ch2_icqserverrelay_free(OscarData *od, IcbmArgsCh2 *args)
 {
-	g_free((char *)args->info.rtfmsg.rtfmsg);
+	g_free((char *)args->info.rtfmsg.msg);
 }
 
 /*
@@ -1980,33 +1980,34 @@
 static void
 incomingim_ch2_icqserverrelay(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata)
 {
-	guint16 hdrlen, anslen, msglen;
-
-	if (byte_stream_empty(servdata) < 24)
-		/* Someone sent us a short server relay ICBM.  Weird.  (Maybe?) */
-		return;
-
-	hdrlen = byte_stream_getle16(servdata);
+	guint16 hdrlen, msglen;
+
+	args->destructor = (void *)incomingim_ch2_icqserverrelay_free;
+
+#define SKIP_HEADER(expected_hdrlen) \
+	hdrlen = byte_stream_getle16(servdata); \
+	if (hdrlen != expected_hdrlen) { \
+		purple_debug_warning("oscar", "Expected to find a header with length " #expected_hdrlen "; ignoring message"); \
+		return; \
+	} \
 	byte_stream_advance(servdata, hdrlen);
 
-	hdrlen = byte_stream_getle16(servdata);
-	byte_stream_advance(servdata, hdrlen);
-
-	args->info.rtfmsg.msgtype = byte_stream_getle16(servdata);
-
-	anslen = byte_stream_getle32(servdata);
-	byte_stream_advance(servdata, anslen);
+	SKIP_HEADER(0x001b);
+	SKIP_HEADER(0x000e);
+
+	args->info.rtfmsg.msgtype = byte_stream_get8(servdata);
+	/*
+	 * Copied from http://iserverd.khstu.ru/oscar/message.html:
+	 * xx      byte       message flags
+	 * xx xx   word (LE)  status code
+	 * xx xx   word (LE)  priority code
+	 *
+	 * We don't need any of these, so just skip them.
+	 */
+	byte_stream_advance(servdata, 1 + 2 + 2);
 
 	msglen = byte_stream_getle16(servdata);
-	args->info.rtfmsg.rtfmsg = byte_stream_getstr(servdata, msglen);
-
-	args->info.rtfmsg.fgcolor = byte_stream_getle32(servdata);
-	args->info.rtfmsg.bgcolor = byte_stream_getle32(servdata);
-
-	hdrlen = byte_stream_getle32(servdata);
-	byte_stream_advance(servdata, hdrlen);
-
-	args->destructor = (void *)incomingim_ch2_icqserverrelay_free;
+	args->info.rtfmsg.msg = byte_stream_getstr(servdata, msglen);
 }
 
 static void
--- a/libpurple/protocols/oscar/oscar.c	Sat Jul 24 17:32:00 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sat Jul 24 18:14:29 2010 +0000
@@ -1812,17 +1812,17 @@
 
 		if (args->info.rtfmsg.msgtype == 1)
 		{
-			if (args->info.rtfmsg.rtfmsg != NULL)
+			if (args->info.rtfmsg.msg != NULL)
 			{
 				char *rtfmsg = NULL;
 				if (args->encoding != NULL) {
 					char *encoding = oscar_encoding_extract(args->encoding);
 					rtfmsg = oscar_encoding_to_utf8(account, encoding,
-							args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg));
+							args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg));
 					g_free(encoding);
 				} else {
-					if (g_utf8_validate(args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg), NULL))
-						rtfmsg = g_strdup(args->info.rtfmsg.rtfmsg);
+					if (g_utf8_validate(args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg), NULL))
+						rtfmsg = g_strdup(args->info.rtfmsg.msg);
 				}
 				if (rtfmsg) {
 					serv_got_im(gc, userinfo->bn, rtfmsg, flags, time(NULL));
--- a/libpurple/protocols/oscar/oscar.h	Sat Jul 24 17:32:00 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Sat Jul 24 18:14:29 2010 +0000
@@ -997,10 +997,8 @@
 			struct aim_chat_roominfo roominfo;
 		} chat;
 		struct {
-			guint16 msgtype;
-			guint32 fgcolor;
-			guint32 bgcolor;
-			const char *rtfmsg;
+			guint8 msgtype;
+			const char *msg;
 		} rtfmsg;
 		struct {
 			guint16 subtype;