/pidgin/main: 5e3601f8bde4: Fix chunk decoding errors

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


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

Description:

Fix chunk decoding errors

diffstat:

 libpurple/protocols/mxit/chunk.c    |  53 ++++++++++++++++++++-----
 libpurple/protocols/mxit/chunk.h    |  11 ++--
 libpurple/protocols/mxit/protocol.c |  75 ++++++++++++++++--------------------
 3 files changed, 82 insertions(+), 57 deletions(-)

diffs (truncated from 328 to 300 lines):

diff --git a/libpurple/protocols/mxit/chunk.c b/libpurple/protocols/mxit/chunk.c
--- a/libpurple/protocols/mxit/chunk.c
+++ b/libpurple/protocols/mxit/chunk.c
@@ -449,13 +449,16 @@ size_t mxit_chunk_create_get_avatar( cha
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param offer			Decoded offerfile information
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-void mxit_chunk_parse_offer( char* chunkdata, size_t datalen, struct offerfile_chunk* offer )
+gboolean mxit_chunk_parse_offer( char* chunkdata, size_t datalen, struct offerfile_chunk* offer )
 {
 	int		pos			= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_offer (%zu bytes)\n", datalen );
 
+	memset( offer, 0, sizeof( struct offerfile_chunk ) );
+
 	/* id [8 bytes] */
 	pos += get_data( &chunkdata[pos], offer->fileid, 8);
 
@@ -483,6 +486,8 @@ void mxit_chunk_parse_offer( char* chunk
 
 	/* flags [4 bytes] */
 	/* not used by libPurple */
+
+	return TRUE;
 }
 
 
@@ -492,13 +497,16 @@ void mxit_chunk_parse_offer( char* chunk
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param offer			Decoded getfile information
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-void mxit_chunk_parse_get( char* chunkdata, size_t datalen, struct getfile_chunk* getfile )
+gboolean mxit_chunk_parse_get( char* chunkdata, size_t datalen, struct getfile_chunk* getfile )
 {
 	int			pos			= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_file (%zu bytes)\n", datalen );
 
+	memset( getfile, 0, sizeof( struct getfile_chunk ) );
+
 	/* id [8 bytes] */
 	pos += get_data( &chunkdata[pos], getfile->fileid, 8 );
 
@@ -513,6 +521,8 @@ void mxit_chunk_parse_get( char* chunkda
 
 	/* file data */
 	getfile->data = &chunkdata[pos];
+
+	return TRUE;
 }
 
 
@@ -522,13 +532,16 @@ void mxit_chunk_parse_get( char* chunkda
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param splash			Decoded splash image information
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-static void mxit_chunk_parse_splash( char* chunkdata, size_t datalen, struct splash_chunk* splash )
+gboolean mxit_chunk_parse_splash( char* chunkdata, size_t datalen, struct splash_chunk* splash )
 {
 	int			pos			= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_splash (%zu bytes)\n", datalen );
 
+	memset( splash, 0, sizeof( struct splash_chunk ) );
+
 	/* anchor [1 byte] */
 	pos += get_int8( &chunkdata[pos], &(splash->anchor) );
 
@@ -543,6 +556,8 @@ static void mxit_chunk_parse_splash( cha
 
 	/* data length */
 	splash->datalen = datalen - pos;
+
+	return TRUE;
 }
 
 
@@ -552,14 +567,17 @@ static void mxit_chunk_parse_splash( cha
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param offer			Decoded custom resource
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-void mxit_chunk_parse_cr( char* chunkdata, size_t datalen, struct cr_chunk* cr )
+gboolean mxit_chunk_parse_cr( char* chunkdata, size_t datalen, struct cr_chunk* cr )
 {
 	int				pos			= 0;
 	unsigned int	chunklen	= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_cr (%zu bytes)\n", datalen );
 
+	memset( cr, 0, sizeof( struct cr_chunk ) );
+
 	/* id [UTF-8] */
 	pos += get_utf8_string( &chunkdata[pos], cr->id, sizeof( cr->id ) );
 
@@ -584,9 +602,10 @@ void mxit_chunk_parse_cr( char* chunkdat
 				{
 					struct splash_chunk* splash = g_new0( struct splash_chunk, 1 );
 
-					mxit_chunk_parse_splash( &chunkdata[pos], chunk_length( chunk ), splash );
-
-					cr->resources = g_list_append( cr->resources, splash );
+					if ( mxit_chunk_parse_splash( &chunkdata[pos], chunk_length( chunk ), splash ) )
+						cr->resources = g_list_append( cr->resources, splash );
+					else
+						g_free( splash );
 					break;
 				}
 			case CP_CHUNK_CLICK :			/* splash click */
@@ -604,6 +623,8 @@ void mxit_chunk_parse_cr( char* chunkdat
 		pos += chunk_length( chunk );
 		chunklen -= ( MXIT_CHUNK_HEADER_SIZE + chunk_length( chunk ) );
 	}
+
+	return TRUE;
 }
 
 
@@ -613,19 +634,22 @@ void mxit_chunk_parse_cr( char* chunkdat
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param sendfile			Decoded sendfile information
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-void mxit_chunk_parse_sendfile( char* chunkdata, size_t datalen, struct sendfile_chunk* sendfile )
+gboolean mxit_chunk_parse_sendfile( char* chunkdata, size_t datalen, struct sendfile_chunk* sendfile )
 {
 	int				pos		= 0;
 	unsigned short	entries	= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_sendfile (%zu bytes)\n", datalen );
 
+	memset( sendfile, 0, sizeof( struct sendfile_chunk ) );
+
 	/* number of entries [2 bytes] */
 	pos += get_int16( &chunkdata[pos], &entries );
 
 	if ( entries < 1 )		/* no data */
-		return;
+		return FALSE;
 
 	/* contactAddress [UTF-8 string] */
 	pos += get_utf8_string( &chunkdata[pos], sendfile->username, sizeof( sendfile->username ) );
@@ -635,6 +659,8 @@ void mxit_chunk_parse_sendfile( char* ch
 
 	/* status message [UTF-8 string] */
 	pos += get_utf8_string( &chunkdata[pos], sendfile->statusmsg, sizeof( sendfile->statusmsg ) );
+
+	return TRUE;
 }
 
 
@@ -644,19 +670,22 @@ void mxit_chunk_parse_sendfile( char* ch
  *  @param chunkdata		Chunked data buffer
  *  @param datalen			The length of the chunked data
  *  @param avatar			Decoded avatar information
+ *  @return					TRUE if successfully parsed, otherwise FALSE
  */
-void mxit_chunk_parse_get_avatar( char* chunkdata, size_t datalen, struct getavatar_chunk* avatar )
+gboolean mxit_chunk_parse_get_avatar( char* chunkdata, size_t datalen, struct getavatar_chunk* avatar )
 {
 	int				pos			= 0;
 	unsigned int	numfiles	= 0;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_chunk_parse_get_avatar (%zu bytes)\n", datalen );
 
+	memset( avatar, 0, sizeof( struct getavatar_chunk ) );
+
 	/* number of files [4 bytes] */
 	pos += get_int32( &chunkdata[pos], &numfiles );
 
 	if ( numfiles < 1 )		/* no data */
-		return;
+		return FALSE;
 
 	/* mxitId [UTF-8 string] */
 	pos += get_utf8_string( &chunkdata[pos], avatar->mxitid, sizeof( avatar->mxitid ) );
@@ -684,4 +713,6 @@ void mxit_chunk_parse_get_avatar( char* 
 
 	/* file data */
 	avatar->data = &chunkdata[pos];
+
+	return TRUE;
 }
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
@@ -182,11 +182,12 @@ size_t mxit_chunk_create_set_avatar( cha
 size_t mxit_chunk_create_get_avatar( char* chunkdata, const char* mxitId, const char* avatarId );
 
 /* Decode chunk */
-void mxit_chunk_parse_offer( char* chunkdata, size_t datalen, struct offerfile_chunk* offer );
-void mxit_chunk_parse_get( char* chunkdata, size_t datalen, struct getfile_chunk* getfile );
-void mxit_chunk_parse_cr( char* chunkdata, size_t datalen, struct cr_chunk* cr );
-void mxit_chunk_parse_sendfile( char* chunkdata, size_t datalen, struct sendfile_chunk* sendfile );
-void mxit_chunk_parse_get_avatar( char* chunkdata, size_t datalen, struct getavatar_chunk* avatar );
+gboolean mxit_chunk_parse_offer( char* chunkdata, size_t datalen, struct offerfile_chunk* offer );
+gboolean mxit_chunk_parse_get( char* chunkdata, size_t datalen, struct getfile_chunk* getfile );
+gboolean mxit_chunk_parse_cr( char* chunkdata, size_t datalen, struct cr_chunk* cr );
+gboolean mxit_chunk_parse_sendfile( char* chunkdata, size_t datalen, struct sendfile_chunk* sendfile );
+gboolean mxit_chunk_parse_get_avatar( char* chunkdata, size_t datalen, struct getavatar_chunk* avatar );
+gboolean mxit_chunk_parse_splash( char* chunkdata, size_t datalen, struct splash_chunk* splash );
 
 #endif		/* _MXIT_CHUNK_H_ */
 
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
@@ -2114,27 +2114,26 @@ static void mxit_parse_cmd_media( struct
 				struct cr_chunk chunk;
 
 				/* decode the chunked data */
-				memset( &chunk, 0, sizeof( struct cr_chunk ) );
-				mxit_chunk_parse_cr( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );
-
-				purple_debug_info( MXIT_PLUGIN_ID, "chunk info id=%s handle=%s op=%i\n", chunk.id, chunk.handle, chunk.operation );
-
-				/* this is a splash-screen operation */
-				if ( strcmp( chunk.handle, HANDLE_SPLASH2 ) == 0 ) {
-					if ( chunk.operation == CR_OP_UPDATE ) {		/* update the splash-screen */
-						struct splash_chunk *splash = chunk.resources->data;			// TODO: Fix - assuming 1st resource is splash
-						gboolean clickable = ( g_list_length( chunk.resources ) > 1 );	// TODO: Fix - if 2 resources, then is clickable
-
-						if ( splash != NULL )
-							splash_update( session, chunk.id, splash->data, splash->datalen, clickable );
+				if ( mxit_chunk_parse_cr( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+
+					purple_debug_info( MXIT_PLUGIN_ID, "chunk info id=%s handle=%s op=%i\n", chunk.id, chunk.handle, chunk.operation );
+
+					/* this is a splash-screen operation */
+					if ( strcmp( chunk.handle, HANDLE_SPLASH2 ) == 0 ) {
+						if ( chunk.operation == CR_OP_UPDATE ) {		/* update the splash-screen */
+							struct splash_chunk *splash = chunk.resources->data;			// TODO: Fix - assuming 1st resource is splash
+							gboolean clickable = ( g_list_length( chunk.resources ) > 1 );	// TODO: Fix - if 2 resources, then is clickable
+
+							if ( splash != NULL )
+								splash_update( session, chunk.id, splash->data, splash->datalen, clickable );
+						}
+						else if ( chunk.operation == CR_OP_REMOVE )		/* remove the splash-screen */
+							splash_remove( session );
 					}
-					else if ( chunk.operation == CR_OP_REMOVE )		/* remove the splash-screen */
-						splash_remove( session );
+
+					/* cleanup custom resources */
+					g_list_foreach( chunk.resources, (GFunc)g_free, NULL );
 				}
-
-				/* cleanup custom resources */
-				g_list_foreach( chunk.resources, (GFunc)g_free, NULL );
-
 			}
 			break;
 
@@ -2143,11 +2142,10 @@ static void mxit_parse_cmd_media( struct
 				struct offerfile_chunk chunk;
 
 				/* decode the chunked data */
-				memset( &chunk, 0, sizeof( struct offerfile_chunk ) );
-				mxit_chunk_parse_offer( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );
-
-				/* process the offer */
-				mxit_xfer_rx_offer( session, chunk.username, chunk.filename, chunk.filesize, chunk.fileid );
+				if ( mxit_chunk_parse_offer( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+					/* process the offer */
+					mxit_xfer_rx_offer( session, chunk.username, chunk.filename, chunk.filesize, chunk.fileid );
+				}
 			}
 			break;
 
@@ -2156,11 +2154,10 @@ static void mxit_parse_cmd_media( struct
 				struct getfile_chunk chunk;
 
 				/* decode the chunked data */
-				memset( &chunk, 0, sizeof( struct getfile_chunk ) );
-				mxit_chunk_parse_get( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );
-
-				/* process the getfile */
-				mxit_xfer_rx_file( session, chunk.fileid, chunk.data, chunk.length );
+				if ( mxit_chunk_parse_get( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+					/* process the getfile */
+					mxit_xfer_rx_file( session, chunk.fileid, chunk.data, chunk.length );
+				}
 			}
 			break;
 
@@ -2170,11 +2167,8 @@ static void mxit_parse_cmd_media( struct
 				struct contact* contact = NULL;
 
 				/* decode the chunked data */
-				memset( &chunk, 0, sizeof( struct getavatar_chunk ) );
-				mxit_chunk_parse_get_avatar( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );



More information about the Commits mailing list