diff libpurple/protocols/msn/slp.c @ 29892:1a9977557dc9

I never liked randomly poking at offsets. Fortunately, I was able to find an old document by Siebe on the Internet Archive that explained (as best possible) the FT request Context field. Also, make the incoming request handling a bit stricter.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 28 Feb 2010 02:11:57 +0000
parents 69077f3993f6
children f8a95fdab3bd
line wrap: on
line diff
--- a/libpurple/protocols/msn/slp.c	Sun Feb 28 01:11:19 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Sun Feb 28 02:11:57 2010 +0000
@@ -308,8 +308,6 @@
 	return NULL;
 }
 
-#define MAX_FILE_NAME_LEN 0x226
-
 static void
 got_sessionreq(MsnSlpCall *slpcall, const char *branch,
 			   const char *euf_guid, const char *context)
@@ -382,7 +380,7 @@
 		/* File Transfer */
 		PurpleAccount *account;
 		PurpleXfer *xfer;
-		char *bin;
+		MsnFileContext *header;
 		gsize bin_len;
 		guint32 file_size;
 		char *file_name;
@@ -396,16 +394,18 @@
 
 		xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
 							 slpcall->slplink->remote_user);
-		if (xfer)
-		{
-			bin = (char *)purple_base64_decode(context, &bin_len);
-			file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8));
 
-			file_name = g_convert(bin + 20, MAX_FILE_NAME_LEN, "UTF-8", "UTF-16LE",
+		header = (MsnFileContext *)purple_base64_decode(context, &bin_len);
+		if (bin_len >= sizeof(MsnFileContext) - 1 &&
+		    header->length == sizeof(MsnFileContext) - 1 &&
+		    header->version == 2) {
+			file_size = GUINT64_FROM_LE(header->file_size);
+
+			file_name = g_convert((const gchar *)&header->file_name,
+			                      MAX_FILE_NAME_LEN * 2,
+			                      "UTF-8", "UTF-16LE",
 			                      NULL, NULL, NULL);
 
-			g_free(bin);
-
 			purple_xfer_set_filename(xfer, file_name ? file_name : "");
 			g_free(file_name);
 			purple_xfer_set_size(xfer, file_size);
@@ -424,6 +424,7 @@
 
 			purple_xfer_request(xfer);
 		}
+		g_free(header);
 
 		accepted = TRUE;