/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