1/* 2 * This file Copyright (C) Mnemosyne LLC 3 * 4 * This file is licensed by the GPL version 2. Works owned by the 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 7 * This exemption does not extend to derived works not owned by 8 * the Transmission project. 9 * 10 * $Id: bencode.c 13198 2012-02-04 00:34:39Z jordan $ 11 */ 12 13#include <assert.h> 14#include <ctype.h> /* isdigit() */ 15#include <errno.h> 16#include <math.h> /* fabs() */ 17#include <stdio.h> /* rename() */ 18#include <stdlib.h> /* strtoul(), strtod(), realloc(), qsort(), mkstemp() */ 19#include <string.h> 20 21#ifdef WIN32 /* tr_mkstemp() */ 22 #include <fcntl.h> 23 #define _S_IREAD 256 24 #define _S_IWRITE 128 25#endif 26 27#include <locale.h> /* setlocale() */ 28#include <unistd.h> /* write(), unlink() */ 29 30#include <event2/buffer.h> 31 32#include "ConvertUTF.h" 33 34#include "transmission.h" 35#include "bencode.h" 36#include "fdlimit.h" /* tr_close_file() */ 37#include "json.h" 38#include "list.h" 39#include "platform.h" /* TR_PATH_MAX */ 40#include "ptrarray.h" 41#include "utils.h" /* tr_new(), tr_free() */ 42 43#ifndef ENODATA 44 #define ENODATA EIO 45#endif 46 47/** 48*** 49**/ 50 51static bool 52isContainer( const tr_benc * val ) 53{ 54 return tr_bencIsList( val ) || tr_bencIsDict( val ); 55} 56 57static bool 58isSomething( const tr_benc * val ) 59{ 60 return isContainer( val ) || tr_bencIsInt( val ) 61 || tr_bencIsString( val ) 62 || tr_bencIsReal( val ) 63 || tr_bencIsBool( val ); 64} 65 66static void 67tr_bencInit( tr_benc * val, char type ) 68{ 69 memset( val, 0, sizeof( *val ) ); 70 val->type = type; 71} 72 73/*** 74**** tr_bencParse() 75**** tr_bencLoad() 76***/ 77 78/** 79 * The initial i and trailing e are beginning and ending delimiters. 80 * You can have negative numbers such as i-3e. You cannot prefix the 81 * number with a zero such as i04e. However, i0e is valid. 82 * Example: i3e represents the integer "3" 83 * NOTE: The maximum number of bit of this integer is unspecified, 84 * but to handle it as a signed 64bit integer is mandatory to handle 85 * "large files" aka .torrent for more that 4Gbyte 86 */ 87int 88tr_bencParseInt( const uint8_t * buf, 89 const uint8_t * bufend, 90 const uint8_t ** setme_end, 91 int64_t * setme_val ) 92{ 93 char * endptr; 94 const void * begin; 95 const void * end; 96 int64_t val; 97 98 if( buf >= bufend ) 99 return EILSEQ; 100 if( *buf != 'i' ) 101 return EILSEQ; 102 103 begin = buf + 1; 104 end = memchr( begin, 'e', ( bufend - buf ) - 1 ); 105 if( end == NULL ) 106 return EILSEQ; 107 108 errno = 0; 109 val = evutil_strtoll( begin, &endptr, 10 ); 110 if( errno || ( endptr != end ) ) /* incomplete parse */ 111 return EILSEQ; 112 if( val && *(const char*)begin == '0' ) /* no leading zeroes! */ 113 return EILSEQ; 114 115 *setme_end = (const uint8_t*)end + 1; 116 *setme_val = val; 117 return 0; 118} 119 120/** 121 * Byte strings are encoded as follows: 122 * <string length encoded in base ten ASCII>:<string data> 123 * Note that there is no constant beginning delimiter, and no ending delimiter. 124 * Example: 4:spam represents the string "spam" 125 */ 126int 127tr_bencParseStr( const uint8_t * buf, 128 const uint8_t * bufend, 129 const uint8_t ** setme_end, 130 const uint8_t ** setme_str, 131 size_t * setme_strlen ) 132{ 133 size_t len; 134 const void * end; 135 char * endptr; 136 137 if( buf >= bufend ) 138 return EILSEQ; 139 140 if( !isdigit( *buf ) ) 141 return EILSEQ; 142 143 end = memchr( buf, ':', bufend - buf ); 144 if( end == NULL ) 145 return EILSEQ; 146 147 errno = 0; 148 len = strtoul( (const char*)buf, &endptr, 10 ); 149 if( errno || endptr != end ) 150 return EILSEQ; 151 152 if( (const uint8_t*)end + 1 + len > bufend ) 153 return EILSEQ; 154 155 *setme_end = (const uint8_t*)end + 1 + len; 156 *setme_str = (const uint8_t*)end + 1; 157 *setme_strlen = len; 158 return 0; 159} 160 161/* set to 1 to help expose bugs with tr_bencListAdd and tr_bencDictAdd */ 162#define LIST_SIZE 4 /* number of items to increment list/dict buffer by */ 163 164static int 165makeroom( tr_benc * val, 166 size_t count ) 167{ 168 assert( TR_TYPE_LIST == val->type || TR_TYPE_DICT == val->type ); 169 170 if( val->val.l.count + count > val->val.l.alloc ) 171 { 172 /* We need a bigger boat */ 173 const int len = val->val.l.alloc + count + 174 ( count % LIST_SIZE ? LIST_SIZE - 175 ( count % LIST_SIZE ) : 0 ); 176 void * tmp = realloc( val->val.l.vals, len * sizeof( tr_benc ) ); 177 if( !tmp ) 178 return 1; 179 180 val->val.l.alloc = len; 181 val->val.l.vals = tmp; 182 } 183 184 return 0; 185} 186 187static tr_benc* 188getNode( tr_benc * top, 189 tr_ptrArray * parentStack, 190 int type ) 191{ 192 tr_benc * parent; 193 194 assert( top ); 195 assert( parentStack ); 196 197 if( tr_ptrArrayEmpty( parentStack ) ) 198 return top; 199 200 parent = tr_ptrArrayBack( parentStack ); 201 assert( parent ); 202 203 /* dictionary keys must be strings */ 204 if( ( parent->type == TR_TYPE_DICT ) 205 && ( type != TR_TYPE_STR ) 206 && ( !( parent->val.l.count % 2 ) ) ) 207 return NULL; 208 209 makeroom( parent, 1 ); 210 return parent->val.l.vals + parent->val.l.count++; 211} 212 213/** 214 * This function's previous recursive implementation was 215 * easier to read, but was vulnerable to a smash-stacking 216 * attack via maliciously-crafted bencoded data. (#667) 217 */ 218static int 219tr_bencParseImpl( const void * buf_in, 220 const void * bufend_in, 221 tr_benc * top, 222 tr_ptrArray * parentStack, 223 const uint8_t ** setme_end ) 224{ 225 int err; 226 const uint8_t * buf = buf_in; 227 const uint8_t * bufend = bufend_in; 228 229 tr_bencInit( top, 0 ); 230 231 while( buf != bufend ) 232 { 233 if( buf > bufend ) /* no more text to parse... */ 234 return 1; 235 236 if( *buf == 'i' ) /* int */ 237 { 238 int64_t val; 239 const uint8_t * end; 240 tr_benc * node; 241 242 if( ( err = tr_bencParseInt( buf, bufend, &end, &val ) ) ) 243 return err; 244 245 node = getNode( top, parentStack, TR_TYPE_INT ); 246 if( !node ) 247 return EILSEQ; 248 249 tr_bencInitInt( node, val ); 250 buf = end; 251 252 if( tr_ptrArrayEmpty( parentStack ) ) 253 break; 254 } 255 else if( *buf == 'l' ) /* list */ 256 { 257 tr_benc * node = getNode( top, parentStack, TR_TYPE_LIST ); 258 if( !node ) 259 return EILSEQ; 260 tr_bencInit( node, TR_TYPE_LIST ); 261 tr_ptrArrayAppend( parentStack, node ); 262 ++buf; 263 } 264 else if( *buf == 'd' ) /* dict */ 265 { 266 tr_benc * node = getNode( top, parentStack, TR_TYPE_DICT ); 267 if( !node ) 268 return EILSEQ; 269 tr_bencInit( node, TR_TYPE_DICT ); 270 tr_ptrArrayAppend( parentStack, node ); 271 ++buf; 272 } 273 else if( *buf == 'e' ) /* end of list or dict */ 274 { 275 tr_benc * node; 276 ++buf; 277 if( tr_ptrArrayEmpty( parentStack ) ) 278 return EILSEQ; 279 280 node = tr_ptrArrayBack( parentStack ); 281 if( tr_bencIsDict( node ) && ( node->val.l.count % 2 ) ) 282 { 283 /* odd # of children in dict */ 284 tr_bencFree( &node->val.l.vals[--node->val.l.count] ); 285 return EILSEQ; 286 } 287 288 tr_ptrArrayPop( parentStack ); 289 if( tr_ptrArrayEmpty( parentStack ) ) 290 break; 291 } 292 else if( isdigit( *buf ) ) /* string? */ 293 { 294 const uint8_t * end; 295 const uint8_t * str; 296 size_t str_len; 297 tr_benc * node; 298 299 if( ( err = tr_bencParseStr( buf, bufend, &end, &str, &str_len ) ) ) 300 return err; 301 302 node = getNode( top, parentStack, TR_TYPE_STR ); 303 if( !node ) 304 return EILSEQ; 305 306 tr_bencInitStr( node, str, str_len ); 307 buf = end; 308 309 if( tr_ptrArrayEmpty( parentStack ) ) 310 break; 311 } 312 else /* invalid bencoded text... march past it */ 313 { 314 ++buf; 315 } 316 } 317 318 err = !isSomething( top ) || !tr_ptrArrayEmpty( parentStack ); 319 320 if( !err && setme_end ) 321 *setme_end = buf; 322 323 return err; 324} 325 326int 327tr_bencParse( const void * buf, 328 const void * end, 329 tr_benc * top, 330 const uint8_t ** setme_end ) 331{ 332 int err; 333 tr_ptrArray parentStack = TR_PTR_ARRAY_INIT; 334 335 top->type = 0; /* set to `uninitialized' */ 336 err = tr_bencParseImpl( buf, end, top, &parentStack, setme_end ); 337 if( err ) 338 tr_bencFree( top ); 339 340 tr_ptrArrayDestruct( &parentStack, NULL ); 341 return err; 342} 343 344int 345tr_bencLoad( const void * buf_in, 346 size_t buflen, 347 tr_benc * setme_benc, 348 char ** setme_end ) 349{ 350 const uint8_t * buf = buf_in; 351 const uint8_t * end; 352 const int ret = tr_bencParse( buf, buf + buflen, setme_benc, &end ); 353 354 if( !ret && setme_end ) 355 *setme_end = (char*) end; 356 return ret; 357} 358 359/*** 360**** 361***/ 362 363/* returns true if the benc's string was malloced. 364 * this occurs when the string is too long for our string buffer */ 365static inline int 366stringIsAlloced( const tr_benc * val ) 367{ 368 return val->val.s.len >= sizeof( val->val.s.str.buf ); 369} 370 371/* returns a const pointer to the benc's string */ 372static inline const char* 373getStr( const tr_benc* val ) 374{ 375 return stringIsAlloced(val) ? val->val.s.str.ptr : val->val.s.str.buf; 376} 377 378static int 379dictIndexOf( const tr_benc * val, const char * key ) 380{ 381 if( tr_bencIsDict( val ) ) 382 { 383 size_t i; 384 const size_t len = strlen( key ); 385 386 for( i = 0; ( i + 1 ) < val->val.l.count; i += 2 ) 387 { 388 const tr_benc * child = val->val.l.vals + i; 389 if( ( child->type == TR_TYPE_STR ) 390 && ( child->val.s.len == len ) 391 && !memcmp( getStr(child), key, len ) ) 392 return i; 393 } 394 } 395 396 return -1; 397} 398 399tr_benc * 400tr_bencDictFind( tr_benc * val, const char * key ) 401{ 402 const int i = dictIndexOf( val, key ); 403 404 return i < 0 ? NULL : &val->val.l.vals[i + 1]; 405} 406 407static bool 408tr_bencDictFindType( tr_benc * dict, const char * key, int type, tr_benc ** setme ) 409{ 410 return tr_bencIsType( *setme = tr_bencDictFind( dict, key ), type ); 411} 412 413size_t 414tr_bencListSize( const tr_benc * list ) 415{ 416 return tr_bencIsList( list ) ? list->val.l.count : 0; 417} 418 419tr_benc* 420tr_bencListChild( tr_benc * val, 421 size_t i ) 422{ 423 tr_benc * ret = NULL; 424 425 if( tr_bencIsList( val ) && ( i < val->val.l.count ) ) 426 ret = val->val.l.vals + i; 427 return ret; 428} 429 430int 431tr_bencListRemove( tr_benc * list, size_t i ) 432{ 433 if( tr_bencIsList( list ) && ( i < list->val.l.count ) ) 434 { 435 tr_bencFree( &list->val.l.vals[i] ); 436 tr_removeElementFromArray( list->val.l.vals, i, sizeof( tr_benc ), list->val.l.count-- ); 437 return 1; 438 } 439 440 return 0; 441} 442 443static void 444tr_benc_warning( const char * err ) 445{ 446 fprintf( stderr, "warning: %s\n", err ); 447} 448 449bool 450tr_bencGetInt( const tr_benc * val, 451 int64_t * setme ) 452{ 453 bool success = false; 454 455 if( !success && (( success = tr_bencIsInt( val )))) 456 if( setme ) 457 *setme = val->val.i; 458 459 if( !success && (( success = tr_bencIsBool( val )))) { 460 tr_benc_warning( "reading bool as an int" ); 461 if( setme ) 462 *setme = val->val.b ? 1 : 0; 463 } 464 465 return success; 466} 467 468bool 469tr_bencGetStr( const tr_benc * val, const char ** setme ) 470{ 471 const bool success = tr_bencIsString( val ); 472 473 if( success ) 474 *setme = getStr( val ); 475 476 return success; 477} 478 479bool 480tr_bencGetRaw( const tr_benc * val, const uint8_t ** setme_raw, size_t * setme_len ) 481{ 482 const bool success = tr_bencIsString( val ); 483 484 if( success ) { 485 *setme_raw = (uint8_t*) getStr(val); 486 *setme_len = val->val.s.len; 487 } 488 489 return success; 490} 491 492bool 493tr_bencGetBool( const tr_benc * val, bool * setme ) 494{ 495 const char * str; 496 bool success = false; 497 498 if(( success = tr_bencIsBool( val ))) 499 *setme = val->val.b; 500 501 if( !success && tr_bencIsInt( val ) ) 502 if(( success = ( val->val.i==0 || val->val.i==1 ) )) 503 *setme = val->val.i!=0; 504 505 if( !success && tr_bencGetStr( val, &str ) ) 506 if(( success = ( !strcmp(str,"true") || !strcmp(str,"false")))) 507 *setme = !strcmp(str,"true"); 508 509 return success; 510} 511 512bool 513tr_bencGetReal( const tr_benc * val, double * setme ) 514{ 515 bool success = false; 516 517 if( !success && (( success = tr_bencIsReal( val )))) 518 *setme = val->val.d; 519 520 if( !success && (( success = tr_bencIsInt( val )))) 521 *setme = val->val.i; 522 523 if( !success && tr_bencIsString(val) ) 524 { 525 char * endptr; 526 char locale[128]; 527 double d; 528 529 /* the json spec requires a '.' decimal point regardless of locale */ 530 tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) ); 531 setlocale( LC_NUMERIC, "POSIX" ); 532 d = strtod( getStr(val), &endptr ); 533 setlocale( LC_NUMERIC, locale ); 534 535 if(( success = ( getStr(val) != endptr ) && !*endptr )) 536 *setme = d; 537 } 538 539 540 return success; 541} 542 543bool 544tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme ) 545{ 546 return tr_bencGetInt( tr_bencDictFind( dict, key ), setme ); 547} 548 549bool 550tr_bencDictFindBool( tr_benc * dict, const char * key, bool * setme ) 551{ 552 return tr_bencGetBool( tr_bencDictFind( dict, key ), setme ); 553} 554 555bool 556tr_bencDictFindReal( tr_benc * dict, const char * key, double * setme ) 557{ 558 return tr_bencGetReal( tr_bencDictFind( dict, key ), setme ); 559} 560 561bool 562tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme ) 563{ 564 return tr_bencGetStr( tr_bencDictFind( dict, key ), setme ); 565} 566 567bool 568tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme ) 569{ 570 return tr_bencDictFindType( dict, key, TR_TYPE_LIST, setme ); 571} 572 573bool 574tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme ) 575{ 576 return tr_bencDictFindType( dict, key, TR_TYPE_DICT, setme ); 577} 578 579bool 580tr_bencDictFindRaw( tr_benc * dict, const char * key, const uint8_t ** setme_raw, size_t * setme_len ) 581{ 582 return tr_bencGetRaw( tr_bencDictFind( dict, key ), setme_raw, setme_len ); 583} 584 585/*** 586**** 587***/ 588 589void 590tr_bencInitRaw( tr_benc * val, const void * src, size_t byteCount ) 591{ 592 char * setme; 593 tr_bencInit( val, TR_TYPE_STR ); 594 595 /* There's no way in benc notation to distinguish between 596 * zero-terminated strings and raw byte arrays. 597 * Because of this, tr_bencMergeDicts() and tr_bencListCopy() 598 * don't know whether or not a TR_TYPE_STR node needs a '\0'. 599 * Append one, een to the raw arrays, just to be safe. */ 600 601 if( byteCount < sizeof( val->val.s.str.buf ) ) 602 setme = val->val.s.str.buf; 603 else 604 setme = val->val.s.str.ptr = tr_new( char, byteCount + 1 ); 605 606 memcpy( setme, src, byteCount ); 607 setme[byteCount] = '\0'; 608 val->val.s.len = byteCount; 609} 610 611void 612tr_bencInitStr( tr_benc * val, const void * str, int len ) 613{ 614 if( str == NULL ) 615 len = 0; 616 else if( len < 0 ) 617 len = strlen( str ); 618 619 tr_bencInitRaw( val, str, len ); 620} 621 622void 623tr_bencInitBool( tr_benc * b, int value ) 624{ 625 tr_bencInit( b, TR_TYPE_BOOL ); 626 b->val.b = value != 0; 627} 628 629void 630tr_bencInitReal( tr_benc * b, double value ) 631{ 632 tr_bencInit( b, TR_TYPE_REAL ); 633 b->val.d = value; 634} 635 636void 637tr_bencInitInt( tr_benc * b, int64_t value ) 638{ 639 tr_bencInit( b, TR_TYPE_INT ); 640 b->val.i = value; 641} 642 643int 644tr_bencInitList( tr_benc * b, size_t reserveCount ) 645{ 646 tr_bencInit( b, TR_TYPE_LIST ); 647 return tr_bencListReserve( b, reserveCount ); 648} 649 650int 651tr_bencListReserve( tr_benc * b, size_t count ) 652{ 653 assert( tr_bencIsList( b ) ); 654 return makeroom( b, count ); 655} 656 657int 658tr_bencInitDict( tr_benc * b, size_t reserveCount ) 659{ 660 tr_bencInit( b, TR_TYPE_DICT ); 661 return tr_bencDictReserve( b, reserveCount ); 662} 663 664int 665tr_bencDictReserve( tr_benc * b, size_t reserveCount ) 666{ 667 assert( tr_bencIsDict( b ) ); 668 return makeroom( b, reserveCount * 2 ); 669} 670 671tr_benc * 672tr_bencListAdd( tr_benc * list ) 673{ 674 tr_benc * item; 675 676 assert( tr_bencIsList( list ) ); 677 678 if( list->val.l.count == list->val.l.alloc ) 679 tr_bencListReserve( list, LIST_SIZE ); 680 681 assert( list->val.l.count < list->val.l.alloc ); 682 683 item = &list->val.l.vals[list->val.l.count]; 684 list->val.l.count++; 685 tr_bencInit( item, TR_TYPE_INT ); 686 687 return item; 688} 689 690tr_benc * 691tr_bencListAddInt( tr_benc * list, int64_t val ) 692{ 693 tr_benc * node = tr_bencListAdd( list ); 694 695 tr_bencInitInt( node, val ); 696 return node; 697} 698 699tr_benc * 700tr_bencListAddReal( tr_benc * list, double val ) 701{ 702 tr_benc * node = tr_bencListAdd( list ); 703 tr_bencInitReal( node, val ); 704 return node; 705} 706 707tr_benc * 708tr_bencListAddBool( tr_benc * list, bool val ) 709{ 710 tr_benc * node = tr_bencListAdd( list ); 711 tr_bencInitBool( node, val ); 712 return node; 713} 714 715tr_benc * 716tr_bencListAddStr( tr_benc * list, const char * val ) 717{ 718 tr_benc * node = tr_bencListAdd( list ); 719 tr_bencInitStr( node, val, -1 ); 720 return node; 721} 722 723tr_benc * 724tr_bencListAddRaw( tr_benc * list, const uint8_t * val, size_t len ) 725{ 726 tr_benc * node = tr_bencListAdd( list ); 727 tr_bencInitRaw( node, val, len ); 728 return node; 729} 730 731tr_benc* 732tr_bencListAddList( tr_benc * list, 733 size_t reserveCount ) 734{ 735 tr_benc * child = tr_bencListAdd( list ); 736 737 tr_bencInitList( child, reserveCount ); 738 return child; 739} 740 741tr_benc* 742tr_bencListAddDict( tr_benc * list, 743 size_t reserveCount ) 744{ 745 tr_benc * child = tr_bencListAdd( list ); 746 747 tr_bencInitDict( child, reserveCount ); 748 return child; 749} 750 751tr_benc * 752tr_bencDictAdd( tr_benc * dict, 753 const char * key ) 754{ 755 tr_benc * keyval, * itemval; 756 757 assert( tr_bencIsDict( dict ) ); 758 if( dict->val.l.count + 2 > dict->val.l.alloc ) 759 makeroom( dict, 2 ); 760 assert( dict->val.l.count + 2 <= dict->val.l.alloc ); 761 762 keyval = dict->val.l.vals + dict->val.l.count++; 763 tr_bencInitStr( keyval, key, -1 ); 764 765 itemval = dict->val.l.vals + dict->val.l.count++; 766 tr_bencInit( itemval, TR_TYPE_INT ); 767 768 return itemval; 769} 770 771static tr_benc* 772dictFindOrAdd( tr_benc * dict, const char * key, int type ) 773{ 774 tr_benc * child; 775 776 /* see if it already exists, and if so, try to reuse it */ 777 if(( child = tr_bencDictFind( dict, key ))) { 778 if( !tr_bencIsType( child, type ) ) { 779 tr_bencDictRemove( dict, key ); 780 child = NULL; 781 } 782 } 783 784 /* if it doesn't exist, create it */ 785 if( child == NULL ) 786 child = tr_bencDictAdd( dict, key ); 787 788 return child; 789} 790 791tr_benc* 792tr_bencDictAddInt( tr_benc * dict, 793 const char * key, 794 int64_t val ) 795{ 796 tr_benc * child = dictFindOrAdd( dict, key, TR_TYPE_INT ); 797 tr_bencInitInt( child, val ); 798 return child; 799} 800 801tr_benc* 802tr_bencDictAddBool( tr_benc * dict, const char * key, bool val ) 803{ 804 tr_benc * child = dictFindOrAdd( dict, key, TR_TYPE_BOOL ); 805 tr_bencInitBool( child, val ); 806 return child; 807} 808 809tr_benc* 810tr_bencDictAddReal( tr_benc * dict, const char * key, double val ) 811{ 812 tr_benc * child = dictFindOrAdd( dict, key, TR_TYPE_REAL ); 813 tr_bencInitReal( child, val ); 814 return child; 815} 816 817tr_benc* 818tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val ) 819{ 820 tr_benc * child; 821 822 /* see if it already exists, and if so, try to reuse it */ 823 if(( child = tr_bencDictFind( dict, key ))) { 824 if( tr_bencIsString( child ) ) { 825 if( stringIsAlloced( child ) ) 826 tr_free( child->val.s.str.ptr ); 827 } else { 828 tr_bencDictRemove( dict, key ); 829 child = NULL; 830 } 831 } 832 833 /* if it doesn't exist, create it */ 834 if( child == NULL ) 835 child = tr_bencDictAdd( dict, key ); 836 837 /* set it */ 838 tr_bencInitStr( child, val, -1 ); 839 840 return child; 841} 842 843tr_benc* 844tr_bencDictAddRaw( tr_benc * dict, 845 const char * key, 846 const void * src, 847 size_t len ) 848{ 849 tr_benc * child; 850 851 /* see if it already exists, and if so, try to reuse it */ 852 if(( child = tr_bencDictFind( dict, key ))) { 853 if( tr_bencIsString( child ) ) { 854 if( stringIsAlloced( child ) ) 855 tr_free( child->val.s.str.ptr ); 856 } else { 857 tr_bencDictRemove( dict, key ); 858 child = NULL; 859 } 860 } 861 862 /* if it doesn't exist, create it */ 863 if( child == NULL ) 864 child = tr_bencDictAdd( dict, key ); 865 866 /* set it */ 867 tr_bencInitRaw( child, src, len ); 868 869 return child; 870} 871 872tr_benc* 873tr_bencDictAddList( tr_benc * dict, 874 const char * key, 875 size_t reserveCount ) 876{ 877 tr_benc * child = tr_bencDictAdd( dict, key ); 878 879 tr_bencInitList( child, reserveCount ); 880 return child; 881} 882 883tr_benc* 884tr_bencDictAddDict( tr_benc * dict, 885 const char * key, 886 size_t reserveCount ) 887{ 888 tr_benc * child = tr_bencDictAdd( dict, key ); 889 890 tr_bencInitDict( child, reserveCount ); 891 return child; 892} 893 894int 895tr_bencDictRemove( tr_benc * dict, 896 const char * key ) 897{ 898 int i = dictIndexOf( dict, key ); 899 900 if( i >= 0 ) 901 { 902 const int n = dict->val.l.count; 903 tr_bencFree( &dict->val.l.vals[i] ); 904 tr_bencFree( &dict->val.l.vals[i + 1] ); 905 if( i + 2 < n ) 906 { 907 dict->val.l.vals[i] = dict->val.l.vals[n - 2]; 908 dict->val.l.vals[i + 1] = dict->val.l.vals[n - 1]; 909 } 910 dict->val.l.count -= 2; 911 } 912 return i >= 0; /* return true if found */ 913} 914 915/*** 916**** BENC WALKING 917***/ 918 919struct KeyIndex 920{ 921 const char * key; 922 int index; 923}; 924 925static int 926compareKeyIndex( const void * va, 927 const void * vb ) 928{ 929 const struct KeyIndex * a = va; 930 const struct KeyIndex * b = vb; 931 932 return strcmp( a->key, b->key ); 933} 934 935struct SaveNode 936{ 937 const tr_benc * val; 938 int valIsVisited; 939 int childCount; 940 int childIndex; 941 int * children; 942}; 943 944static void 945nodeInitDict( struct SaveNode * node, const tr_benc * val, bool sort_dicts ) 946{ 947 const int n = val->val.l.count; 948 const int nKeys = n / 2; 949 950 assert( tr_bencIsDict( val ) ); 951 952 node->val = val; 953 node->children = tr_new0( int, n ); 954 955 if( sort_dicts ) 956 { 957 int i, j; 958 struct KeyIndex * indices = tr_new( struct KeyIndex, nKeys ); 959 for( i=j=0; i<n; i+=2, ++j ) 960 { 961 indices[j].key = getStr(&val->val.l.vals[i]); 962 indices[j].index = i; 963 } 964 qsort( indices, j, sizeof( struct KeyIndex ), compareKeyIndex ); 965 for( i = 0; i < j; ++i ) 966 { 967 const int index = indices[i].index; 968 node->children[node->childCount++] = index; 969 node->children[node->childCount++] = index + 1; 970 } 971 972 tr_free( indices ); 973 } 974 else 975 { 976 int i; 977 978 for( i=0; i<n; ++i ) 979 node->children[node->childCount++] = i; 980 } 981 982 assert( node->childCount == n ); 983} 984 985static void 986nodeInitList( struct SaveNode * node, const tr_benc * val ) 987{ 988 int i, n; 989 990 assert( tr_bencIsList( val ) ); 991 992 n = val->val.l.count; 993 node->val = val; 994 node->childCount = n; 995 node->children = tr_new0( int, n ); 996 for( i = 0; i < n; ++i ) /* a list's children don't need to be reordered */ 997 node->children[i] = i; 998} 999 1000static void 1001nodeInitLeaf( struct SaveNode * node, const tr_benc * val ) 1002{ 1003 assert( !isContainer( val ) ); 1004 1005 node->val = val; 1006} 1007 1008static void 1009nodeInit( struct SaveNode * node, const tr_benc * val, bool sort_dicts ) 1010{ 1011 static const struct SaveNode INIT_NODE = { NULL, 0, 0, 0, NULL }; 1012 *node = INIT_NODE; 1013 1014 if( tr_bencIsList( val ) ) nodeInitList( node, val ); 1015 else if( tr_bencIsDict( val ) ) nodeInitDict( node, val, sort_dicts ); 1016 else nodeInitLeaf( node, val ); 1017} 1018 1019typedef void ( *BencWalkFunc )( const tr_benc * val, void * user_data ); 1020 1021struct WalkFuncs 1022{ 1023 BencWalkFunc intFunc; 1024 BencWalkFunc boolFunc; 1025 BencWalkFunc realFunc; 1026 BencWalkFunc stringFunc; 1027 BencWalkFunc dictBeginFunc; 1028 BencWalkFunc listBeginFunc; 1029 BencWalkFunc containerEndFunc; 1030}; 1031 1032/** 1033 * This function's previous recursive implementation was 1034 * easier to read, but was vulnerable to a smash-stacking 1035 * attack via maliciously-crafted bencoded data. (#667) 1036 */ 1037static void 1038bencWalk( const tr_benc * top, 1039 const struct WalkFuncs * walkFuncs, 1040 void * user_data, 1041 bool sort_dicts ) 1042{ 1043 int stackSize = 0; 1044 int stackAlloc = 64; 1045 struct SaveNode * stack = tr_new( struct SaveNode, stackAlloc ); 1046 1047 nodeInit( &stack[stackSize++], top, sort_dicts ); 1048 1049 while( stackSize > 0 ) 1050 { 1051 struct SaveNode * node = &stack[stackSize-1]; 1052 const tr_benc * val; 1053 1054 if( !node->valIsVisited ) 1055 { 1056 val = node->val; 1057 node->valIsVisited = true; 1058 } 1059 else if( node->childIndex < node->childCount ) 1060 { 1061 const int index = node->children[node->childIndex++]; 1062 val = node->val->val.l.vals + index; 1063 } 1064 else /* done with this node */ 1065 { 1066 if( isContainer( node->val ) ) 1067 walkFuncs->containerEndFunc( node->val, user_data ); 1068 --stackSize; 1069 tr_free( node->children ); 1070 continue; 1071 } 1072 1073 if( val ) switch( val->type ) 1074 { 1075 case TR_TYPE_INT: 1076 walkFuncs->intFunc( val, user_data ); 1077 break; 1078 1079 case TR_TYPE_BOOL: 1080 walkFuncs->boolFunc( val, user_data ); 1081 break; 1082 1083 case TR_TYPE_REAL: 1084 walkFuncs->realFunc( val, user_data ); 1085 break; 1086 1087 case TR_TYPE_STR: 1088 walkFuncs->stringFunc( val, user_data ); 1089 break; 1090 1091 case TR_TYPE_LIST: 1092 if( val == node->val ) 1093 walkFuncs->listBeginFunc( val, user_data ); 1094 else { 1095 if( stackAlloc == stackSize ) { 1096 stackAlloc *= 2; 1097 stack = tr_renew( struct SaveNode, stack, stackAlloc ); 1098 } 1099 nodeInit( &stack[stackSize++], val, sort_dicts ); 1100 } 1101 break; 1102 1103 case TR_TYPE_DICT: 1104 if( val == node->val ) 1105 walkFuncs->dictBeginFunc( val, user_data ); 1106 else { 1107 if( stackAlloc == stackSize ) { 1108 stackAlloc *= 2; 1109 stack = tr_renew( struct SaveNode, stack, stackAlloc ); 1110 } 1111 nodeInit( &stack[stackSize++], val, sort_dicts ); 1112 } 1113 break; 1114 1115 default: 1116 /* did caller give us an uninitialized val? */ 1117 tr_err( "%s", _( "Invalid metadata" ) ); 1118 break; 1119 } 1120 } 1121 1122 tr_free( stack ); 1123} 1124 1125/**** 1126***** 1127****/ 1128 1129static void 1130saveIntFunc( const tr_benc * val, void * evbuf ) 1131{ 1132 evbuffer_add_printf( evbuf, "i%" PRId64 "e", val->val.i ); 1133} 1134 1135static void 1136saveBoolFunc( const tr_benc * val, void * evbuf ) 1137{ 1138 if( val->val.b ) 1139 evbuffer_add( evbuf, "i1e", 3 ); 1140 else 1141 evbuffer_add( evbuf, "i0e", 3 ); 1142} 1143 1144static void 1145saveRealFunc( const tr_benc * val, void * evbuf ) 1146{ 1147 char buf[128]; 1148 char locale[128]; 1149 size_t len; 1150 1151 /* always use a '.' decimal point s.t. locale-hopping doesn't bite us */ 1152 tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) ); 1153 setlocale( LC_NUMERIC, "POSIX" ); 1154 tr_snprintf( buf, sizeof( buf ), "%f", val->val.d ); 1155 setlocale( LC_NUMERIC, locale ); 1156 1157 len = strlen( buf ); 1158 evbuffer_add_printf( evbuf, "%lu:", (unsigned long)len ); 1159 evbuffer_add( evbuf, buf, len ); 1160} 1161 1162static void 1163saveStringFunc( const tr_benc * val, void * evbuf ) 1164{ 1165 evbuffer_add_printf( evbuf, "%lu:", (unsigned long)val->val.s.len ); 1166 evbuffer_add( evbuf, getStr(val), val->val.s.len ); 1167} 1168 1169static void 1170saveDictBeginFunc( const tr_benc * val UNUSED, void * evbuf ) 1171{ 1172 evbuffer_add( evbuf, "d", 1 ); 1173} 1174 1175static void 1176saveListBeginFunc( const tr_benc * val UNUSED, void * evbuf ) 1177{ 1178 evbuffer_add( evbuf, "l", 1 ); 1179} 1180 1181static void 1182saveContainerEndFunc( const tr_benc * val UNUSED, void * evbuf ) 1183{ 1184 evbuffer_add( evbuf, "e", 1 ); 1185} 1186 1187static const struct WalkFuncs saveFuncs = { saveIntFunc, 1188 saveBoolFunc, 1189 saveRealFunc, 1190 saveStringFunc, 1191 saveDictBeginFunc, 1192 saveListBeginFunc, 1193 saveContainerEndFunc }; 1194 1195/*** 1196**** 1197***/ 1198 1199static void 1200freeDummyFunc( const tr_benc * val UNUSED, void * buf UNUSED ) 1201{} 1202 1203static void 1204freeStringFunc( const tr_benc * val, void * unused UNUSED ) 1205{ 1206 if( stringIsAlloced( val ) ) 1207 tr_free( val->val.s.str.ptr ); 1208} 1209 1210static void 1211freeContainerEndFunc( const tr_benc * val, void * unused UNUSED ) 1212{ 1213 tr_free( val->val.l.vals ); 1214} 1215 1216static const struct WalkFuncs freeWalkFuncs = { freeDummyFunc, 1217 freeDummyFunc, 1218 freeDummyFunc, 1219 freeStringFunc, 1220 freeDummyFunc, 1221 freeDummyFunc, 1222 freeContainerEndFunc }; 1223 1224void 1225tr_bencFree( tr_benc * val ) 1226{ 1227 if( isSomething( val ) ) 1228 bencWalk( val, &freeWalkFuncs, NULL, false ); 1229} 1230 1231/*** 1232**** 1233***/ 1234 1235/** @brief Implementation helper class for tr_bencToBuffer(TR_FMT_JSON) */ 1236struct ParentState 1237{ 1238 int bencType; 1239 int childIndex; 1240 int childCount; 1241}; 1242 1243/** @brief Implementation helper class for tr_bencToBuffer(TR_FMT_JSON) */ 1244struct jsonWalk 1245{ 1246 bool doIndent; 1247 tr_list * parents; 1248 struct evbuffer * out; 1249}; 1250 1251static void 1252jsonIndent( struct jsonWalk * data ) 1253{ 1254 if( data->doIndent ) 1255 { 1256 char buf[1024]; 1257 const int width = tr_list_size( data->parents ) * 4; 1258 1259 buf[0] = '\n'; 1260 memset( buf+1, ' ', width ); 1261 evbuffer_add( data->out, buf, 1+width ); 1262 } 1263} 1264 1265static void 1266jsonChildFunc( struct jsonWalk * data ) 1267{ 1268 if( data->parents && data->parents->data ) 1269 { 1270 struct ParentState * parentState = data->parents->data; 1271 1272 switch( parentState->bencType ) 1273 { 1274 case TR_TYPE_DICT: 1275 { 1276 const int i = parentState->childIndex++; 1277 if( !( i % 2 ) ) 1278 evbuffer_add( data->out, ": ", data->doIndent ? 2 : 1 ); 1279 else { 1280 const bool isLast = parentState->childIndex == parentState->childCount; 1281 if( !isLast ) { 1282 evbuffer_add( data->out, ", ", data->doIndent ? 2 : 1 ); 1283 jsonIndent( data ); 1284 } 1285 } 1286 break; 1287 } 1288 1289 case TR_TYPE_LIST: 1290 { 1291 const bool isLast = ++parentState->childIndex == parentState->childCount; 1292 if( !isLast ) { 1293 evbuffer_add( data->out, ", ", data->doIndent ? 2 : 1 ); 1294 jsonIndent( data ); 1295 } 1296 break; 1297 } 1298 1299 default: 1300 break; 1301 } 1302 } 1303} 1304 1305static void 1306jsonPushParent( struct jsonWalk * data, 1307 const tr_benc * benc ) 1308{ 1309 struct ParentState * parentState = tr_new( struct ParentState, 1 ); 1310 1311 parentState->bencType = benc->type; 1312 parentState->childIndex = 0; 1313 parentState->childCount = benc->val.l.count; 1314 tr_list_prepend( &data->parents, parentState ); 1315} 1316 1317static void 1318jsonPopParent( struct jsonWalk * data ) 1319{ 1320 tr_free( tr_list_pop_front( &data->parents ) ); 1321} 1322 1323static void 1324jsonIntFunc( const tr_benc * val, 1325 void * vdata ) 1326{ 1327 struct jsonWalk * data = vdata; 1328 1329 evbuffer_add_printf( data->out, "%" PRId64, val->val.i ); 1330 jsonChildFunc( data ); 1331} 1332 1333static void 1334jsonBoolFunc( const tr_benc * val, void * vdata ) 1335{ 1336 struct jsonWalk * data = vdata; 1337 1338 if( val->val.b ) 1339 evbuffer_add( data->out, "true", 4 ); 1340 else 1341 evbuffer_add( data->out, "false", 5 ); 1342 1343 jsonChildFunc( data ); 1344} 1345 1346static void 1347jsonRealFunc( const tr_benc * val, void * vdata ) 1348{ 1349 struct jsonWalk * data = vdata; 1350 char locale[128]; 1351 1352 if( fabs( val->val.d - (int)val->val.d ) < 0.00001 ) 1353 evbuffer_add_printf( data->out, "%d", (int)val->val.d ); 1354 else { 1355 /* json requires a '.' decimal point regardless of locale */ 1356 tr_strlcpy( locale, setlocale( LC_NUMERIC, NULL ), sizeof( locale ) ); 1357 setlocale( LC_NUMERIC, "POSIX" ); 1358 evbuffer_add_printf( data->out, "%.4f", tr_truncd( val->val.d, 4 ) ); 1359 setlocale( LC_NUMERIC, locale ); 1360 } 1361 1362 jsonChildFunc( data ); 1363} 1364 1365static void 1366jsonStringFunc( const tr_benc * val, void * vdata ) 1367{ 1368 char * out; 1369 char * outwalk; 1370 char * outend; 1371 struct evbuffer_iovec vec[1]; 1372 struct jsonWalk * data = vdata; 1373 const unsigned char * it = (const unsigned char *) getStr(val); 1374 const unsigned char * end = it + val->val.s.len; 1375 1376 evbuffer_reserve_space( data->out, val->val.s.len * 4, vec, 1 ); 1377 out = vec[0].iov_base; 1378 outend = out + vec[0].iov_len; 1379 1380 outwalk = out; 1381 *outwalk++ = '"'; 1382 1383 for( ; it!=end; ++it ) 1384 { 1385 switch( *it ) 1386 { 1387 case '\b': *outwalk++ = '\\'; *outwalk++ = 'b'; break; 1388 case '\f': *outwalk++ = '\\'; *outwalk++ = 'f'; break; 1389 case '\n': *outwalk++ = '\\'; *outwalk++ = 'n'; break; 1390 case '\r': *outwalk++ = '\\'; *outwalk++ = 'r'; break; 1391 case '\t': *outwalk++ = '\\'; *outwalk++ = 't'; break; 1392 case '"' : *outwalk++ = '\\'; *outwalk++ = '"'; break; 1393 case '\\': *outwalk++ = '\\'; *outwalk++ = '\\'; break; 1394 1395 default: 1396 if( isascii( *it ) ) 1397 *outwalk++ = *it; 1398 else { 1399 const UTF8 * tmp = it; 1400 UTF32 buf[1] = { 0 }; 1401 UTF32 * u32 = buf; 1402 ConversionResult result = ConvertUTF8toUTF32( &tmp, end, &u32, buf + 1, 0 ); 1403 if((( result==conversionOK ) || (result==targetExhausted)) && (tmp!=it)) { 1404 outwalk += tr_snprintf( outwalk, outend-outwalk, "\\u%04x", (unsigned int)buf[0] ); 1405 it = tmp - 1; 1406 } 1407 } 1408 } 1409 } 1410 1411 *outwalk++ = '"'; 1412 vec[0].iov_len = outwalk - out; 1413 evbuffer_commit_space( data->out, vec, 1 ); 1414 1415 jsonChildFunc( data ); 1416} 1417 1418static void 1419jsonDictBeginFunc( const tr_benc * val, 1420 void * vdata ) 1421{ 1422 struct jsonWalk * data = vdata; 1423 1424 jsonPushParent( data, val ); 1425 evbuffer_add( data->out, "{", 1 ); 1426 if( val->val.l.count ) 1427 jsonIndent( data ); 1428} 1429 1430static void 1431jsonListBeginFunc( const tr_benc * val, 1432 void * vdata ) 1433{ 1434 const size_t nChildren = tr_bencListSize( val ); 1435 struct jsonWalk * data = vdata; 1436 1437 jsonPushParent( data, val ); 1438 evbuffer_add( data->out, "[", 1 ); 1439 if( nChildren ) 1440 jsonIndent( data ); 1441} 1442 1443static void 1444jsonContainerEndFunc( const tr_benc * val, 1445 void * vdata ) 1446{ 1447 struct jsonWalk * data = vdata; 1448 int emptyContainer = false; 1449 1450 jsonPopParent( data ); 1451 if( !emptyContainer ) 1452 jsonIndent( data ); 1453 if( tr_bencIsDict( val ) ) 1454 evbuffer_add( data->out, "}", 1 ); 1455 else /* list */ 1456 evbuffer_add( data->out, "]", 1 ); 1457 jsonChildFunc( data ); 1458} 1459 1460static const struct WalkFuncs jsonWalkFuncs = { jsonIntFunc, 1461 jsonBoolFunc, 1462 jsonRealFunc, 1463 jsonStringFunc, 1464 jsonDictBeginFunc, 1465 jsonListBeginFunc, 1466 jsonContainerEndFunc }; 1467 1468/*** 1469**** 1470***/ 1471 1472static void 1473tr_bencListCopy( tr_benc * target, const tr_benc * src ) 1474{ 1475 int i = 0; 1476 const tr_benc * val; 1477 1478 while(( val = tr_bencListChild( (tr_benc*)src, i++ ))) 1479 { 1480 if( tr_bencIsBool( val ) ) 1481 { 1482 bool boolVal = 0; 1483 tr_bencGetBool( val, &boolVal ); 1484 tr_bencListAddBool( target, boolVal ); 1485 } 1486 else if( tr_bencIsReal( val ) ) 1487 { 1488 double realVal = 0; 1489 tr_bencGetReal( val, &realVal ); 1490 tr_bencListAddReal( target, realVal ); 1491 } 1492 else if( tr_bencIsInt( val ) ) 1493 { 1494 int64_t intVal = 0; 1495 tr_bencGetInt( val, &intVal ); 1496 tr_bencListAddInt( target, intVal ); 1497 } 1498 else if( tr_bencIsString( val ) ) 1499 { 1500 tr_bencListAddRaw( target, (const uint8_t*)getStr( val ), val->val.s.len ); 1501 } 1502 else if( tr_bencIsDict( val ) ) 1503 { 1504 tr_bencMergeDicts( tr_bencListAddDict( target, 0 ), val ); 1505 } 1506 else if ( tr_bencIsList( val ) ) 1507 { 1508 tr_bencListCopy( tr_bencListAddList( target, 0 ), val ); 1509 } 1510 else 1511 { 1512 tr_err( "tr_bencListCopy skipping item" ); 1513 } 1514 } 1515} 1516 1517static size_t 1518tr_bencDictSize( const tr_benc * dict ) 1519{ 1520 size_t count = 0; 1521 1522 if( tr_bencIsDict( dict ) ) 1523 count = dict->val.l.count / 2; 1524 1525 return count; 1526} 1527 1528bool 1529tr_bencDictChild( tr_benc * dict, size_t n, const char ** key, tr_benc ** val ) 1530{ 1531 bool success = 0; 1532 1533 assert( tr_bencIsDict( dict ) ); 1534 1535 if( tr_bencIsDict( dict ) && (n*2)+1 <= dict->val.l.count ) 1536 { 1537 tr_benc * k = dict->val.l.vals + (n*2); 1538 tr_benc * v = dict->val.l.vals + (n*2) + 1; 1539 if(( success = tr_bencGetStr( k, key ) && isSomething( v ))) 1540 *val = v; 1541 } 1542 1543 return success; 1544} 1545 1546void 1547tr_bencMergeDicts( tr_benc * target, const tr_benc * source ) 1548{ 1549 size_t i; 1550 const size_t sourceCount = tr_bencDictSize( source ); 1551 1552 assert( tr_bencIsDict( target ) ); 1553 assert( tr_bencIsDict( source ) ); 1554 1555 for( i=0; i<sourceCount; ++i ) 1556 { 1557 const char * key; 1558 tr_benc * val; 1559 tr_benc * t; 1560 1561 if( tr_bencDictChild( (tr_benc*)source, i, &key, &val ) ) 1562 { 1563 if( tr_bencIsBool( val ) ) 1564 { 1565 bool boolVal; 1566 tr_bencGetBool( val, &boolVal ); 1567 tr_bencDictAddBool( target, key, boolVal ); 1568 } 1569 else if( tr_bencIsReal( val ) ) 1570 { 1571 double realVal = 0; 1572 tr_bencGetReal( val, &realVal ); 1573 tr_bencDictAddReal( target, key, realVal ); 1574 } 1575 else if( tr_bencIsInt( val ) ) 1576 { 1577 int64_t intVal = 0; 1578 tr_bencGetInt( val, &intVal ); 1579 tr_bencDictAddInt( target, key, intVal ); 1580 } 1581 else if( tr_bencIsString( val ) ) 1582 { 1583 tr_bencDictAddRaw( target, key, getStr( val ), val->val.s.len ); 1584 } 1585 else if( tr_bencIsDict( val ) && tr_bencDictFindDict( target, key, &t ) ) 1586 { 1587 tr_bencMergeDicts( t, val ); 1588 } 1589 else if( tr_bencIsList( val ) ) 1590 { 1591 if( tr_bencDictFind( target, key ) == NULL ) 1592 { 1593 tr_bencListCopy( tr_bencDictAddList( target, key, tr_bencListSize( val ) ), val ); 1594 } 1595 } 1596 else if( tr_bencIsDict( val ) ) 1597 { 1598 tr_benc * target_dict = tr_bencDictFind( target, key ); 1599 1600 if( target_dict == NULL ) 1601 target_dict = tr_bencDictAddDict( target, key, tr_bencDictSize( val ) ); 1602 1603 if( tr_bencIsDict( target_dict ) ) 1604 tr_bencMergeDicts( target_dict, val ); 1605 } 1606 else 1607 { 1608 tr_dbg( "tr_bencMergeDicts skipping \"%s\"", key ); 1609 } 1610 } 1611 } 1612} 1613 1614/*** 1615**** 1616***/ 1617 1618struct evbuffer * 1619tr_bencToBuf( const tr_benc * top, tr_fmt_mode mode ) 1620{ 1621 struct evbuffer * buf = evbuffer_new( ); 1622 1623 evbuffer_expand( buf, 4096 ); /* alloc a little memory to start off with */ 1624 1625 switch( mode ) 1626 { 1627 case TR_FMT_BENC: 1628 bencWalk( top, &saveFuncs, buf, true ); 1629 break; 1630 1631 case TR_FMT_JSON: 1632 case TR_FMT_JSON_LEAN: { 1633 struct jsonWalk data; 1634 data.doIndent = mode==TR_FMT_JSON; 1635 data.out = buf; 1636 data.parents = NULL; 1637 bencWalk( top, &jsonWalkFuncs, &data, true ); 1638 if( evbuffer_get_length( buf ) ) 1639 evbuffer_add_printf( buf, "\n" ); 1640 break; 1641 } 1642 } 1643 1644 return buf; 1645} 1646 1647char* 1648tr_bencToStr( const tr_benc * top, tr_fmt_mode mode, int * len ) 1649{ 1650 struct evbuffer * buf = tr_bencToBuf( top, mode ); 1651 const size_t n = evbuffer_get_length( buf ); 1652 char * ret = evbuffer_free_to_str( buf ); 1653 if( len != NULL ) 1654 *len = (int) n; 1655 return ret; 1656} 1657 1658/* portability wrapper for mkstemp(). */ 1659static int 1660tr_mkstemp( char * template ) 1661{ 1662#ifdef WIN32 1663 const int flags = O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED; 1664 const mode_t mode = _S_IREAD | _S_IWRITE; 1665 mktemp( template ); 1666 return open( template, flags, mode ); 1667#else 1668 return mkstemp( template ); 1669#endif 1670} 1671 1672int 1673tr_bencToFile( const tr_benc * top, tr_fmt_mode mode, const char * filename ) 1674{ 1675 char * tmp; 1676 int fd; 1677 int err = 0; 1678 char buf[TR_PATH_MAX]; 1679 1680 /* follow symlinks to find the "real" file, to make sure the temporary 1681 * we build with tr_mkstemp() is created on the right partition */ 1682 if( tr_realpath( filename, buf ) != NULL ) 1683 filename = buf; 1684 1685 /* if the file already exists, try to move it out of the way & keep it as a backup */ 1686 tmp = tr_strdup_printf( "%s.tmp.XXXXXX", filename ); 1687 fd = tr_mkstemp( tmp ); 1688 tr_set_file_for_single_pass( fd ); 1689 if( fd >= 0 ) 1690 { 1691 int nleft; 1692 1693 /* save the benc to a temporary file */ 1694 { 1695 struct evbuffer * buf = tr_bencToBuf( top, mode ); 1696 const char * walk = (const char *) evbuffer_pullup( buf, -1 ); 1697 nleft = evbuffer_get_length( buf ); 1698 1699 while( nleft > 0 ) { 1700 const int n = write( fd, walk, nleft ); 1701 if( n >= 0 ) { 1702 nleft -= n; 1703 walk += n; 1704 } 1705 else if( errno != EAGAIN ) { 1706 err = errno; 1707 break; 1708 } 1709 } 1710 1711 evbuffer_free( buf ); 1712 } 1713 1714 if( nleft > 0 ) 1715 { 1716 tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp, tr_strerror( err ) ); 1717 tr_close_file( fd ); 1718 unlink( tmp ); 1719 } 1720 else 1721 { 1722 //tr_fsync( fd ); 1723 tr_close_file( fd ); 1724 1725#ifdef WIN32 1726 if( MoveFileEx( tmp, filename, MOVEFILE_REPLACE_EXISTING ) ) 1727#else 1728 if( !rename( tmp, filename ) ) 1729#endif 1730 { 1731 tr_inf( _( "Saved \"%s\"" ), filename ); 1732 } 1733 else 1734 { 1735 err = errno; 1736 tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename, tr_strerror( err ) ); 1737 unlink( tmp ); 1738 } 1739 } 1740 } 1741 else 1742 { 1743 err = errno; 1744 tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp, tr_strerror( err ) ); 1745 } 1746 1747 tr_free( tmp ); 1748 return err; 1749} 1750 1751/*** 1752**** 1753***/ 1754 1755int 1756tr_bencLoadFile( tr_benc * setme, tr_fmt_mode mode, const char * filename ) 1757{ 1758 int err; 1759 size_t contentLen; 1760 uint8_t * content; 1761 1762 content = tr_loadFile( filename, &contentLen ); 1763 if( !content && errno ) 1764 err = errno; 1765 else if( !content ) 1766 err = ENODATA; 1767 else { 1768 if( mode == TR_FMT_BENC ) 1769 err = tr_bencLoad( content, contentLen, setme, NULL ); 1770 else 1771 err = tr_jsonParse( filename, content, contentLen, setme, NULL ); 1772 } 1773 1774 tr_free( content ); 1775 return err; 1776} 1777 1778