diff libpurple/protocols/jabber/si.c @ 25756:151b4054ce40

Trigger error callbacks when receiving a malformed-ish packet. Clean up a few pieces of code. Use G_GSIZE_FORMAT like KingAnt showed me. Don't crash if an iq packet doesn't contain the seq attribute. Error check g_fopen() Don't unref the PurpleXfer until after we've called some functions with it. Not sure that could ever actually crash it (I didn't bother to run through the ref-counts in my head to see if it would fail). committer: Marcus Lundblad <ml@update.uu.se>
author Paul Aurich <paul@darkrain42.org>
date Tue, 16 Dec 2008 19:16:10 +0000
parents 2faa374df334
children 4b51394fd834
line wrap: on
line diff
--- a/libpurple/protocols/jabber/si.c	Mon Dec 15 23:13:49 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Tue Dec 16 19:16:10 2008 +0000
@@ -32,9 +32,9 @@
 #include "buddy.h"
 #include "disco.h"
 #include "jabber.h"
+#include "ibb.h"
 #include "iq.h"
 #include "si.h"
-#include "ibb.h"
 
 #define STREAMHOST_CONNECT_TIMEOUT 15
 
@@ -999,7 +999,7 @@
 	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 	
 	if (size <= purple_xfer_get_bytes_remaining(xfer)) {
-		purple_debug_info("jabber", "about to write %lu bytes from IBB stream\n",
+		purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
 			size);
 		if(!fwrite(data, size, 1, jsx->fp)) {
 			purple_debug_error("jabber", "error writing to file\n");
@@ -1018,7 +1018,7 @@
 		/* trying to write past size of file transfers negotiated size,
 		  reject transfer to protect against malicious behaviour */
 		purple_debug_error("jabber", 
-			"IBB file transfer, trying to write past end of file\n");
+			"IBB file transfer send more data than expected\n");
 		jabber_si_xfer_cancel_recv(xfer);
 		purple_xfer_end(xfer);
 	}
@@ -1036,8 +1036,19 @@
 		JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 		JabberIBBSession *sess = 
 			jabber_ibb_session_create_from_xmlnode(js, packet, xfer);
-		
+		const char *filename;
+
 		if (sess) {
+			/* open the file to write to */
+			filename = purple_xfer_get_local_filename(xfer);
+			jsx->fp = g_fopen(filename, "wb");
+			if (jsx->fp == NULL) {
+				purple_debug_error("jabber", "failed to open file %s for writing: %s\n",
+					filename, g_strerror(errno));
+				purple_xfer_cancel_remote(xfer);
+				return FALSE;
+			}
+
 			/* setup callbacks here...*/
 			jabber_ibb_session_set_data_received_callback(sess,
 				jabber_si_xfer_ibb_recv_data_cb);
@@ -1046,9 +1057,6 @@
 			jabber_ibb_session_set_error_callback(sess,
 				jabber_si_xfer_ibb_error_cb);
 			
-			/* open the file to write to */
-			jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
-			
 			jsx->ibb_session = sess;
 			
 			/* start the transfer */
@@ -1082,7 +1090,7 @@
 	gpointer data = g_malloc(packet_size);
 	int res;
 	
-	purple_debug_info("jabber", "IBB: about to read %lu bytes from file %p\n",
+	purple_debug_info("jabber", "IBB: about to read %" G_GSIZE_FORMAT " bytes from file %p\n",
 		packet_size, jsx->fp);
 	res = fread(data, packet_size, 1, jsx->fp);
 	
@@ -1121,18 +1129,30 @@
 {
 	PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
 	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
-	
+	JabberStream *js = jabber_ibb_session_get_js(sess);
+	PurpleConnection *gc = js->gc;
+	PurpleAccount *account = purple_connection_get_account(gc);
+
 	if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) {
-		purple_xfer_start(xfer, 0, NULL, 0);
-		purple_xfer_set_bytes_sent(xfer, 0);
-		purple_xfer_update_progress(xfer);
-		jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
-		jabber_si_xfer_ibb_send_data(sess);
+		const char *filename = purple_xfer_get_local_filename(xfer);
+		jsx->fp = g_fopen(filename, "rb");
+		if (jsx->fp == NULL) {
+			purple_debug_error("jabber", "Failed to open file %s for reading: %s\n",
+				filename, g_strerror(errno));
+			jabber_si_xfer_free(xfer);
+			purple_xfer_error(purple_xfer_get_type(xfer), account,
+				jabber_ibb_session_get_who(sess),
+				_("Failed to open the file"));
+			purple_xfer_end(xfer);
+		} else {
+			/* XXX: Shouldn't this specify a valid file descriptor? */
+			purple_xfer_start(xfer, 0, NULL, 0);
+			purple_xfer_set_bytes_sent(xfer, 0);
+			purple_xfer_update_progress(xfer);
+			jabber_si_xfer_ibb_send_data(sess);
+		}
 	} else {
 		/* error */
-		JabberStream *js = jabber_ibb_session_get_js(sess);
-		PurpleConnection *gc = js->gc;
-		PurpleAccount *account = purple_connection_get_account(gc);
 		jabber_si_xfer_free(xfer);
 		purple_xfer_error(purple_xfer_get_type(xfer), account,
 			jabber_ibb_session_get_who(sess), 
@@ -1167,10 +1187,10 @@
 		
 	} else {
 		/* failed to create IBB session */
-		purple_xfer_unref(xfer);
 		purple_debug_error("jabber", 
 			"failed to initiate IBB session for file transfer\n");
 		jabber_si_xfer_cancel_send(xfer);
+		purple_xfer_unref(xfer);
 	}
 }