qulogic/pidgin

Fix chunk decoding errors
release-2.x.y
2016-06-03, Andrew Victor
5e3601f8bde4
Parents ae243a809727
Children 1c5197a66760
Fix chunk decoding errors
--- a/libpurple/protocols/mxit/chunk.c Fri Jun 03 12:15:05 2016 -0500
+++ b/libpurple/protocols/mxit/chunk.c Fri Jun 03 12:33:50 2016 -0500
@@ -449,13 +449,16 @@
* @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 @@
/* flags [4 bytes] */
/* not used by libPurple */
+
+ return TRUE;
}
@@ -492,13 +497,16 @@
* @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 @@
/* file data */
getfile->data = &chunkdata[pos];
+
+ return TRUE;
}
@@ -522,13 +532,16 @@
* @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 @@
/* data length */
splash->datalen = datalen - pos;
+
+ return TRUE;
}
@@ -552,14 +567,17 @@
* @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 @@
{
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 @@
pos += chunk_length( chunk );
chunklen -= ( MXIT_CHUNK_HEADER_SIZE + chunk_length( chunk ) );
}
+
+ return TRUE;
}
@@ -613,19 +634,22 @@
* @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 @@
/* status message [UTF-8 string] */
pos += get_utf8_string( &chunkdata[pos], sendfile->statusmsg, sizeof( sendfile->statusmsg ) );
+
+ return TRUE;
}
@@ -644,19 +670,22 @@
* @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 @@
/* file data */
avatar->data = &chunkdata[pos];
+
+ return TRUE;
}
--- a/libpurple/protocols/mxit/chunk.h Fri Jun 03 12:15:05 2016 -0500
+++ b/libpurple/protocols/mxit/chunk.h Fri Jun 03 12:33:50 2016 -0500
@@ -182,11 +182,12 @@
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_ */
--- a/libpurple/protocols/mxit/protocol.c Fri Jun 03 12:15:05 2016 -0500
+++ b/libpurple/protocols/mxit/protocol.c Fri Jun 03 12:33:50 2016 -0500
@@ -2114,27 +2114,26 @@
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 @@
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 @@
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 @@
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 );
-
- /* update avatar image */
- if ( chunk.data ) {
+ if ( mxit_chunk_parse_get_avatar( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk ) ) {
+ /* update avatar image */
purple_debug_info( MXIT_PLUGIN_ID, "updating avatar for contact '%s'\n", chunk.mxitid );
contact = get_mxit_invite_contact( session, chunk.mxitid );
@@ -2201,13 +2195,12 @@
{
struct sendfile_chunk chunk;
- memset( &chunk, 0, sizeof( struct sendfile_chunk ) );
- mxit_chunk_parse_sendfile( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &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 */
- mxit_popup( PURPLE_NOTIFY_MSG_ERROR, _( "File Send Failed" ), chunk.statusmsg );
+ if ( mxit_chunk_parse_sendfile( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &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 */
+ mxit_popup( PURPLE_NOTIFY_MSG_ERROR, _( "File Send Failed" ), chunk.statusmsg );
+ }
}
break;