/pidgin/main: 5e3601f8bde4: Fix chunk decoding errors
Andrew Victor <[email protected]> Mon, 20 Jun 2016 20:09:58 -0400
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 5e3601f8bde493d648916b611c2f81d507fcc9da Author: Andrew Victor <[email protected]> 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 ); _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits