Changeset 241 for trunk/libtransmission


Ignore:
Timestamp:
Apr 25, 2006, 7:00:18 AM (17 years ago)
Author:
joshe
Message:

Make sure not to go past the end of the buffer when loading bencoded data.
Add code to encode using bencoding.

Location:
trunk/libtransmission
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r1 r241  
    2323#include "transmission.h"
    2424
    25 #define LIST_SIZE 20
    26 
    27 int _tr_bencLoad( char * buf, benc_val_t * val, char ** end )
    28 {
    29     char * p, * foo;
     25#define LIST_SIZE   20
     26#define OUTBUF_SIZE 100
     27
     28static int tr_bencSprintf( char ** buf, size_t * used, size_t * max,
     29                           char * format, ... )
     30#ifdef __GNUC__
     31    __attribute__ ((format (printf, 4, 5)))
     32#endif
     33    ;
     34
     35int _tr_bencLoad( char * buf, size_t len, benc_val_t * val, char ** end )
     36{
     37    char * p, * e, * foo;
     38
     39    if( 1 >= len )
     40    {
     41        return 1;
     42    }
    3043
    3144    if( !end )
     
    3952    if( buf[0] == 'i' )
    4053    {
     54        e = memchr( &buf[1], 'e', len - 1 );
     55        if( NULL == e )
     56        {
     57            return 1;
     58        }
     59
    4160        /* Integer: i1242e */
    4261        val->type  = TYPE_INT;
     62        *e         = '\0';
    4363        val->val.i = strtoll( &buf[1], &p, 10 );
    44 
    45         if( p == &buf[1] || p[0] != 'e' )
     64        *e         = 'e';
     65
     66        if( p != e )
    4667        {
    4768            return 1;
     
    6788        cur              = &buf[1];
    6889        str_expected     = 1;
    69         while( cur[0] != 'e' )
     90        while( (size_t)(cur - buf) < len && cur[0] != 'e' )
    7091        {
    7192            if( val->val.l.count == val->val.l.alloc )
     
    7697                        val->val.l.alloc  * sizeof( benc_val_t ) );
    7798            }
    78             if( tr_bencLoad( cur, &val->val.l.vals[val->val.l.count], &p ) )
     99            if( tr_bencLoad( cur, len - (cur - buf),
     100                             &val->val.l.vals[val->val.l.count], &p ) )
    79101            {
    80102                return 1;
     
    100122    else
    101123    {
     124        e = memchr( buf, ':', len );
     125        if( NULL == e )
     126        {
     127            return 1;
     128        }
     129
    102130        /* String: 12:whateverword */
    103131        val->type    = TYPE_STR;
     132        e[0]         = '\0';
    104133        val->val.s.i = strtol( buf, &p, 10 );
    105 
    106         if( p == buf || p[0] != ':' )
    107         {
    108             return 1;
    109         }
    110        
     134        e[0]         = ':';
     135
     136        if( p != e || 0 > val->val.s.i ||
     137            (size_t)(val->val.s.i) > len - ((p + 1) - buf) )
     138        {
     139            return 1;
     140        }
     141
    111142        val->val.s.s               = malloc( val->val.s.i + 1 );
    112143        val->val.s.s[val->val.s.i] = 0;
     
    204235    return NULL;
    205236}
     237
     238char * tr_bencSaveMalloc( benc_val_t * val, size_t * len )
     239{
     240    char * buf   = NULL;
     241    size_t alloc = 0;
     242
     243    *len = 0;
     244    if( tr_bencSave( val, &buf, len, &alloc ) )
     245    {
     246        if( NULL != buf )
     247        {
     248            free(buf);
     249        }
     250        *len = 0;
     251        return NULL;
     252    }
     253
     254    return buf;
     255}
     256
     257int tr_bencSave( benc_val_t * val, char ** buf, size_t * used, size_t * max )
     258{
     259    int ii;   
     260
     261    switch( val->type )
     262    {
     263        case TYPE_INT:
     264            if( tr_bencSprintf( buf, used, max, "i%llde", val->val.i ) )
     265            {
     266                return 1;
     267            }
     268            break;
     269
     270        case TYPE_STR:
     271            if( (int)strlen(val->val.s.s) != val->val.s.i )
     272            {
     273                return 1;
     274            }
     275            if( tr_bencSprintf( buf, used, max, "%i:%s",
     276                                val->val.s.i, val->val.s.s ) )
     277            {
     278                return 1;
     279            }
     280            break;
     281
     282        case TYPE_LIST:
     283        case TYPE_DICT:
     284            if( tr_bencSprintf( buf, used, max,
     285                                (TYPE_LIST == val->type ? "l" : "d") ) )
     286            {
     287                return 1;
     288            }
     289            for( ii = 0; val->val.l.count > ii; ii++ )
     290            {
     291                if( tr_bencSave( val->val.l.vals + ii, buf, used, max ) )
     292                {
     293                    return 1;
     294                }
     295            }
     296            if( tr_bencSprintf( buf, used, max, "e" ) )
     297            {
     298                return 1;
     299            }
     300            break;
     301    }
     302
     303    return 0;
     304}
     305
     306static int tr_bencSprintf( char ** buf, size_t * used, size_t * max,
     307                           char * format, ... )
     308{
     309    va_list ap;
     310    int     want;
     311    char  * newbuf;
     312
     313    va_start( ap, format );
     314    want = vsnprintf( NULL, 0, format, ap );
     315    va_end(ap);
     316
     317    while( *used + want + 1 > *max )
     318    {
     319        *max += OUTBUF_SIZE;
     320        newbuf = realloc( *buf, *max );
     321        if( NULL == newbuf )
     322        {
     323            return 1;
     324        }
     325        *buf = newbuf;
     326    }
     327
     328    va_start( ap, format );
     329    *used += vsnprintf( *buf + *used, *max - *used, format, ap );
     330    va_end( ap );
     331
     332    return 0;
     333}
  • trunk/libtransmission/bencode.h

    r1 r241  
    5050} benc_val_t;
    5151
    52 #define tr_bencLoad(b,v,e) _tr_bencLoad((char*)(b),v,(char**)e)
    53 int          _tr_bencLoad( char * buf, benc_val_t * val, char ** end );
     52#define tr_bencLoad(b,l,v,e) _tr_bencLoad((char*)(b),(l),(v),(char**)(e))
     53int          _tr_bencLoad( char * buf, size_t len, benc_val_t * val,
     54                           char ** end );
    5455void         tr_bencPrint( benc_val_t * val );
    5556void         tr_bencFree( benc_val_t * val );
    5657benc_val_t * tr_bencDictFind( benc_val_t * val, char * key );
     58char *       tr_bencSaveMalloc( benc_val_t * val, size_t * len );
     59int          tr_bencSave( benc_val_t * val, char ** buf,
     60                          size_t * used, size_t * max );
    5761
    5862#endif
  • trunk/libtransmission/metainfo.c

    r6 r241  
    7979
    8080    /* Parse bencoded infos */
    81     if( tr_bencLoad( buf, &meta, NULL ) )
     81    if( tr_bencLoad( buf, sb.st_size, &meta, NULL ) )
    8282    {
    8383        fprintf( stderr, "Error while parsing bencoded data\n" );
  • trunk/libtransmission/tracker.c

    r230 r241  
    463463    }
    464464
    465     if( tr_bencLoad( &body[i], &beAll, NULL ) )
     465    if( tr_bencLoad( &body[i], bodylen - i, &beAll, NULL ) )
    466466    {
    467467        tr_err( "Tracker: error parsing bencoded data" );
     
    707707        return 1;
    708708    }
    709     if( tr_bencLoad( &buf[i], &scrape, NULL ) )
     709    if( tr_bencLoad( &buf[i], pos - i, &scrape, NULL ) )
    710710    {
    711711        return 1;
Note: See TracChangeset for help on using the changeset viewer.