Changeset 4892
- Timestamp:
- Feb 1, 2008, 3:50:12 PM (14 years ago)
- Location:
- branches/1.0x/libtransmission
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/1.0x/libtransmission/bencode-test.c
r4883 r4892 25 25 uint8_t buf[128]; 26 26 int64_t val; 27 unsignedint err;27 int err; 28 28 const uint8_t * end; 29 29 … … 39 39 val = 888; 40 40 err = tr_bencParseInt( buf, buf+3, &end, &val ); 41 check( err == TR_ERROR );41 check( err == (int)TR_ERROR ); 42 42 check( val == 888 ); 43 43 check( end == NULL ); … … 45 45 /* empty buffer */ 46 46 err = tr_bencParseInt( buf, buf+0, &end, &val ); 47 check( err == TR_ERROR );47 check( err == (int)TR_ERROR ); 48 48 check( val == 888 ); 49 49 check( end == NULL ); … … 52 52 snprintf( (char*)buf, sizeof( buf ), "i6z4e" ); 53 53 err = tr_bencParseInt( buf, buf+5, &end, &val ); 54 check( err == TR_ERROR );54 check( err == (int)TR_ERROR ); 55 55 check( val == 888 ); 56 56 check( end == NULL ); … … 75 75 snprintf( (char*)buf, sizeof( buf ), "i04e" ); 76 76 err = tr_bencParseInt( buf, buf+4, &end, &val ); 77 check( err == TR_ERROR );77 check( err == (int)TR_ERROR ); 78 78 check( val == 0 ); 79 79 check( end == NULL ); … … 86 86 { 87 87 uint8_t buf[128]; 88 unsignedint err;88 int err; 89 89 const uint8_t * end; 90 90 uint8_t * str; … … 105 105 /* string goes past end of buffer */ 106 106 err = tr_bencParseStr( buf, buf+5, &end, &str, &len ); 107 check( err == TR_ERROR );107 check( err == (int)TR_ERROR ); 108 108 check( str == NULL ); 109 109 check( end == NULL ); … … 138 138 139 139 static int 140 testString( const char * str, int isGood ) 141 { 142 benc_val_t val; 143 const uint8_t * end = NULL; 144 char * saved; 145 const size_t len = strlen( str ); 146 int savedLen; 147 int err = tr_bencParse( str, str+len, &val , &end ); 148 if( !isGood ) { 149 check( err ); 150 } else { 151 check( !err ); 152 check( end == (const uint8_t*)str + len ); 153 saved = tr_bencSave( &val, &savedLen ); 154 check( !strcmp( saved, str ) ); 155 check( len == (size_t)savedLen ); 156 tr_free( saved ); 157 tr_bencFree( &val ); 158 } 159 return 0; 160 } 161 162 static int 140 163 testParse( void ) 141 164 { … … 185 208 tr_bencFree( &val ); 186 209 187 end = NULL; 188 snprintf( (char*)buf, sizeof( buf ), "llleee" ); 189 err = tr_bencParse( buf, buf + sizeof( buf ), &val , &end ); 190 check( !err ); 191 check( end == buf + 6 ); 192 saved = tr_bencSave( &val, &len ); 193 check( !strcmp( saved, "llleee" ) ); 194 tr_free( saved ); 195 tr_bencFree( &val ); 210 if(( err = testString( "llleee", TRUE ))) 211 return err; 212 if(( err = testString( "d3:cow3:moo4:spam4:eggse", TRUE ))) 213 return err; 214 if(( err = testString( "d4:spaml1:a1:bee", TRUE ))) 215 return err; 216 #if 0 217 if(( err = testString( "d9:publisher3:bob18:publisher.location4:home17:publisher-webpage15:www.example.come", TRUE ))) 218 return err; 219 #endif 220 if(( err = testString( "d8:completei1e8:intervali1800e12:min intervali1800e5:peers0:e", TRUE ))) 221 return err; 222 if(( err = testString( "d1:ai0e1:be", FALSE ))) /* odd number of children */ 223 return err; 224 if(( err = testString( "", FALSE ))) 225 return err; 196 226 197 227 /* nested containers … … 208 238 check( !strcmp( saved, "lld1:ai64e1:bi32eeee" ) ); 209 239 tr_free( saved ); 210 tr_bencFree( &val );211 212 end = NULL;213 snprintf( (char*)buf, sizeof( buf ), "d8:completei1e8:intervali1800e12:min intervali1800e5:peers0:e" );214 err = tr_bencParse( buf, buf+sizeof( buf ), &val, &end );215 check( !err );216 check( end == buf + strlen( (const char*)buf ) );217 240 tr_bencFree( &val ); 218 241 -
branches/1.0x/libtransmission/bencode.c
r4883 r4892 30 30 #include <stdlib.h> 31 31 32 #include <event.h> 32 #include <event.h> /* evbuffer */ 33 33 34 34 #include "transmission.h" 35 35 #include "bencode.h" 36 36 #include "ptrarray.h" 37 #include "utils.h" 37 #include "utils.h" /* tr_new(), tr_free() */ 38 38 39 39 /** … … 42 42 43 43 static int 44 tr_bencIsInt( const benc_val_t * val ) 45 { 46 return val!=NULL && val->type==TYPE_INT; 47 } 48 49 static int 50 tr_bencIsList( const benc_val_t * val ) 51 { 52 return val!=NULL && val->type==TYPE_LIST; 53 } 54 55 static int 56 tr_bencIsDict( const benc_val_t * val ) 57 { 58 return val!=NULL && val->type==TYPE_DICT; 59 } 44 isType( const benc_val_t * val, int type ) 45 { 46 return ( ( val != NULL ) && ( val->type == type ) ); 47 } 48 49 #define isInt(v) ( isType( ( v ), TYPE_INT ) ) 50 #define isString(v) ( isType( ( v ), TYPE_STR ) ) 51 #define isList(v) ( isType( ( v ), TYPE_LIST ) ) 52 #define isDict(v) ( isType( ( v ), TYPE_DICT ) ) 60 53 61 54 static int 62 55 isContainer( const benc_val_t * val ) 63 56 { 64 return val!=NULL && ( val->type & ( TYPE_DICT | TYPE_LIST ) ); 57 return isList(val) || isDict(val); 58 } 59 static int 60 isSomething( const benc_val_t * val ) 61 { 62 return isContainer(val) || isInt(val) || isString(val); 65 63 } 66 64 … … 69 67 { 70 68 benc_val_t * ret = NULL; 71 if( tr_bencIsList( val ) && ( i >= 0 ) && ( i < val->val.l.count ) )69 if( isList( val ) && ( i >= 0 ) && ( i < val->val.l.count ) ) 72 70 ret = val->val.l.vals + i; 73 71 return ret; … … 215 213 216 214 /** 217 * this function's awkward stack-based implementation218 * is to prevent maliciously-crafed bencode data from219 * smashing our stack through deep recursion. (#667)215 * This function's previous recursive implementation was 216 * easier to read, but was vulnerable to a smash-stacking 217 * attack via maliciously-crafted bencoded data. (#667) 220 218 */ 221 219 int … … 230 228 tr_ptrArray * parentStack = tr_ptrArrayNew( ); 231 229 230 tr_bencInit( top, 0 ); 231 232 232 while( buf != bufend ) 233 233 { … … 275 275 else if( *buf=='e' ) /* end of list or dict */ 276 276 { 277 benc_val_t * node; 277 278 ++buf; 278 279 if( tr_ptrArrayEmpty( parentStack ) ) 279 280 return TR_ERROR; 281 282 node = tr_ptrArrayBack( parentStack ); 283 if( isDict( node ) && ( node->val.l.count % 2 ) ) 284 return TR_ERROR; /* odd # of children in dict */ 285 280 286 tr_ptrArrayPop( parentStack ); 281 287 if( tr_ptrArrayEmpty( parentStack ) ) … … 309 315 } 310 316 311 err = tr_ptrArrayEmpty( parentStack ) ? 0 : 1;317 err = !isSomething( top ) || !tr_ptrArrayEmpty( parentStack ); 312 318 313 319 if( !err && ( setme_end != NULL ) ) … … 368 374 tr_bencGetInt ( const benc_val_t * val ) 369 375 { 370 assert( tr_bencIsInt( val ) );376 assert( isInt( val ) ); 371 377 return val->val.i; 372 378 } … … 454 460 benc_val_t * item; 455 461 456 assert( tr_bencIsList( list ) );462 assert( isList( list ) ); 457 463 assert( list->val.l.count < list->val.l.alloc ); 458 464 … … 469 475 benc_val_t * keyval, * itemval; 470 476 471 assert( tr_bencIsDict( dict ) );477 assert( isDict( dict ) ); 472 478 assert( dict->val.l.count + 2 <= dict->val.l.alloc ); 473 479 … … 503 509 { 504 510 const benc_val_t * val; 505 int valIs Saved;511 int valIsVisited; 506 512 int childCount; 507 513 int childIndex; … … 512 518 nodeNewDict( const benc_val_t * val ) 513 519 { 514 int i, j, n; 520 int i, j; 521 int nKeys; 515 522 struct SaveNode * node; 516 523 struct KeyIndex * indices; 517 524 518 assert( tr_bencIsDict( val ) );519 520 n = val->val.l.count;525 assert( isDict( val ) ); 526 527 nKeys = val->val.l.count / 2; 521 528 node = tr_new0( struct SaveNode, 1 ); 522 529 node->val = val; 523 node->children = tr_new0( int, n );530 node->children = tr_new0( int, nKeys * 2 ); 524 531 525 532 /* ugh, a dictionary's children have to be sorted by key... */ 526 indices = tr_new( struct KeyIndex, n );527 for( i=j=0; i< n; i+=2, ++j ) {533 indices = tr_new( struct KeyIndex, nKeys ); 534 for( i=j=0; i<(nKeys*2); i+=2, ++j ) { 528 535 indices[j].key = val->val.l.vals[i].val.s.s; 529 536 indices[j].index = i; … … 536 543 } 537 544 538 assert( node->childCount == n );545 assert( node->childCount == nKeys * 2 ); 539 546 tr_free( indices ); 540 547 return node; … … 547 554 struct SaveNode * node; 548 555 549 assert( tr_bencIsList( val ) );556 assert( isList( val ) ); 550 557 551 558 n = val->val.l.count; … … 599 606 600 607 /** 601 * this function's awkward stack-based implementation602 * is to prevent maliciously-crafed bencode data from603 * smashing our stack through deep recursion. (#667)608 * This function's previous recursive implementation was 609 * easier to read, but was vulnerable to a smash-stacking 610 * attack via maliciously-crafted bencoded data. (#667) 604 611 */ 605 612 static void … … 616 623 const benc_val_t * val; 617 624 618 if( !node->valIs Saved )625 if( !node->valIsVisited ) 619 626 { 620 627 val = node->val; 621 node->valIs Saved = TRUE;628 node->valIsVisited = TRUE; 622 629 } 623 630 else if( node->childIndex < node->childCount )
Note: See TracChangeset
for help on using the changeset viewer.