/pidgin/main: 1c5197a66760: Check the chunk header

Andrew Victor andrew.victor at mxit.com
Mon Jun 20 20:09:58 EDT 2016


Changeset: 1c5197a66760396a28de87d566e0eb0d986175ea
Author:	 Andrew Victor <andrew.victor at mxit.com>
Date:	 2016-06-03 12:39 -0500
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/1c5197a66760

Description:

Check the chunk header

diffstat:

 libpurple/protocols/mxit/chunk.h    |   2 +-
 libpurple/protocols/mxit/protocol.c |  62 ++++++++++++++++++------------------
 libpurple/protocols/mxit/protocol.h |   2 +-
 3 files changed, 33 insertions(+), 33 deletions(-)

diffs (164 lines):

diff --git a/libpurple/protocols/mxit/chunk.h b/libpurple/protocols/mxit/chunk.h
--- a/libpurple/protocols/mxit/chunk.h
+++ b/libpurple/protocols/mxit/chunk.h
@@ -85,7 +85,7 @@ static inline void set_chunk_type( gchar
 static inline guint32 chunk_length( gchar* chunkheader )
 {
 	guint32 length = *( (const guint32*) &chunkheader[1] );
-	return htonl( length );
+	return ntohl( length );
 }
 
 static inline void set_chunk_length( gchar* chunkheader, guint32 size )
diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c
--- a/libpurple/protocols/mxit/protocol.c
+++ b/libpurple/protocols/mxit/protocol.c
@@ -2076,21 +2076,6 @@ static void mxit_parse_cmd_msgevent( str
 
 
 /*------------------------------------------------------------------------
- * Return the length of a multimedia chunk
- *
- * @return		The actual chunk data length in bytes
- */
-static int get_chunk_len( const char* chunkdata )
-{
-	int*	sizeptr;
-
-	sizeptr = (int*) &chunkdata[1];		/* we skip the first byte (type field) */
-
-	return ntohl( *sizeptr );
-}
-
-
-/*------------------------------------------------------------------------
  * Process a received multimedia packet.
  *
  *  @param session		The MXit session object
@@ -2099,22 +2084,33 @@ static int get_chunk_len( const char* ch
  */
 static void mxit_parse_cmd_media( struct MXitSession* session, struct record** records, int rcount )
 {
-	char	type;
-	int		size;
-
-	type = records[0]->fields[0]->data[0];
-	size = get_chunk_len( records[0]->fields[0]->data );
-
-	purple_debug_info( MXIT_PLUGIN_ID, "mxit_parse_cmd_media (%i records) (%i bytes)\n", rcount, size );
+	guint	chunktype;
+	guint32	chunksize;
+	gchar*	chunkdata;
+
+	/* received packet is too short to even contain a chunk header */
+	if ( records[0]->fields[0]->len < MXIT_CHUNK_HEADER_SIZE )
+		return;
+
+	/* decode the chunk header */
+	chunktype = chunk_type( records[0]->fields[0]->data );
+	chunksize = chunk_length( records[0]->fields[0]->data );
+	chunkdata = chunk_data( records[0]->fields[0]->data );
+
+	/* check chunk size against length of received data */
+	if ( MXIT_CHUNK_HEADER_SIZE + chunksize > records[0]->fields[0]->len )
+		return;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "mxit_parse_cmd_media (%i records) (%i type) (%i bytes)\n", rcount, chunktype, chunksize );
 
 	/* supported chunked data types */
-	switch ( type ) {
+	switch ( chunktype ) {
 		case CP_CHUNK_CUSTOM :				/* custom resource */
 			{
 				struct cr_chunk chunk;
 
 				/* decode the chunked data */
-				if ( mxit_chunk_parse_cr( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+				if ( mxit_chunk_parse_cr( chunkdata, chunksize, &chunk ) ) {
 
 					purple_debug_info( MXIT_PLUGIN_ID, "chunk info id=%s handle=%s op=%i\n", chunk.id, chunk.handle, chunk.operation );
 
@@ -2142,7 +2138,7 @@ static void mxit_parse_cmd_media( struct
 				struct offerfile_chunk chunk;
 
 				/* decode the chunked data */
-				if ( mxit_chunk_parse_offer( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+				if ( mxit_chunk_parse_offer( chunkdata, chunksize, &chunk ) ) {
 					/* process the offer */
 					mxit_xfer_rx_offer( session, chunk.username, chunk.filename, chunk.filesize, chunk.fileid );
 				}
@@ -2154,7 +2150,7 @@ static void mxit_parse_cmd_media( struct
 				struct getfile_chunk chunk;
 
 				/* decode the chunked data */
-				if ( mxit_chunk_parse_get( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+				if ( mxit_chunk_parse_get( chunkdata, chunksize, &chunk ) ) {
 					/* process the getfile */
 					mxit_xfer_rx_file( session, chunk.fileid, chunk.data, chunk.length );
 				}
@@ -2167,7 +2163,7 @@ static void mxit_parse_cmd_media( struct
 				struct contact* contact = NULL;
 
 				/* decode the chunked data */
-				if ( mxit_chunk_parse_get_avatar( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+				if ( mxit_chunk_parse_get_avatar( chunkdata, chunksize, &chunk ) ) {
 					/* update avatar image */
 					purple_debug_info( MXIT_PLUGIN_ID, "updating avatar for contact '%s'\n", chunk.mxitid );
 
@@ -2190,12 +2186,16 @@ static void mxit_parse_cmd_media( struct
 			/* this is a reply packet to a set avatar request. no action is required */
 			break;
 
+		case CP_CHUNK_REJECT :
+			/* this is a reply packet to a reject file request. no action is required */
+			break;
+
 		case CP_CHUNK_DIRECT_SND :
 			/* this is a ack for a file send. */
 			{
 				struct sendfile_chunk chunk;
 
-				if ( mxit_chunk_parse_sendfile( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+				if ( mxit_chunk_parse_sendfile( chunkdata, chunksize, &chunk ) ) {
 					purple_debug_info( MXIT_PLUGIN_ID, "file-send send to '%s' [status=%i message='%s']\n", chunk.username, chunk.status, chunk.statusmsg );
 
 					if ( chunk.status != 0 )	/* not success */
@@ -2209,7 +2209,7 @@ static void mxit_parse_cmd_media( struct
 			break;
 
 		default :
-			purple_debug_error( MXIT_PLUGIN_ID, "Unsupported chunked data packet type received (%i)\n", type );
+			purple_debug_error( MXIT_PLUGIN_ID, "Unsupported chunked data packet type received (%i)\n", chunktype );
 			break;
 	}
 }
@@ -2525,7 +2525,7 @@ static void dump_packet( struct rx_packe
 
 		for ( j = 0; j < r->fcount; j++ ) {
 			f = r->fields[j];
-			purple_debug_info( MXIT_PLUGIN_ID, "\tFIELD: (len=%i) '%s' \n", f->len, f->data );
+			purple_debug_info( MXIT_PLUGIN_ID, "\tFIELD: (len=%zu) '%s' \n", f->len, f->data );
 		}
 	}
 }
@@ -2646,7 +2646,7 @@ int mxit_parse_packet( struct MXitSessio
 								field->data = &session->rx_dbuf[i + 1];
 								field->len = session->rx_i - i;
 								/* now skip the binary data */
-								res = get_chunk_len( field->data );
+								res = chunk_length( field->data );
 								/* determine if we have more packets */
 								if ( res + 6 + i < session->rx_i ) {
 									/* we have more than one packet in this stream */
diff --git a/libpurple/protocols/mxit/protocol.h b/libpurple/protocols/mxit/protocol.h
--- a/libpurple/protocols/mxit/protocol.h
+++ b/libpurple/protocols/mxit/protocol.h
@@ -241,7 +241,7 @@ struct MXitSession;
 
 struct field {
 	char*				data;
-	int					len;
+	size_t				len;
 };
 
 struct record {



More information about the Commits mailing list