2 * This file Copyright (C) 2008-2010 Mnemosyne LLC
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.
10 * $Id: bencode.c 11445 2010-12-01 04:54:18Z charles $
14 #include <ctype.h> /* isdigit() */
16 #include <math.h> /* fabs() */
18 #include <stdlib.h> /* realpath() */
21 #ifdef WIN32 /* tr_mkstemp() */
27 #include <sys/types.h> /* stat() */
28 #include <sys/stat.h> /* stat() */
30 #include <unistd.h> /* stat() */
32 #include <event.h> /* struct evbuffer */
34 #include "ConvertUTF.h"
36 #include "transmission.h"
38 #include "fdlimit.h" /* tr_close_file() */
41 #include "platform.h" /* TR_PATH_MAX */
43 #include "utils.h" /* tr_new(), tr_free() */
54 isContainer( const tr_benc
* val
)
56 return tr_bencIsList( val
) || tr_bencIsDict( val
);
60 isSomething( const tr_benc
* val
)
62 return isContainer( val
) || tr_bencIsInt( val
)
63 || tr_bencIsString( val
)
64 || tr_bencIsReal( val
)
65 || tr_bencIsBool( val
);
69 tr_bencInit( tr_benc
* val
, char type
)
71 memset( val
, 0, sizeof( *val
) );
81 * The initial i and trailing e are beginning and ending delimiters.
82 * You can have negative numbers such as i-3e. You cannot prefix the
83 * number with a zero such as i04e. However, i0e is valid.
84 * Example: i3e represents the integer "3"
85 * NOTE: The maximum number of bit of this integer is unspecified,
86 * but to handle it as a signed 64bit integer is mandatory to handle
87 * "large files" aka .torrent for more that 4Gbyte
90 tr_bencParseInt( const uint8_t * buf
,
91 const uint8_t * bufend
,
92 const uint8_t ** setme_end
,
106 end
= memchr( begin
, 'e', ( bufend
- buf
) - 1 );
111 val
= evutil_strtoll( begin
, &endptr
, 10 );
112 if( errno
|| ( endptr
!= end
) ) /* incomplete parse */
114 if( val
&& *(const char*)begin
== '0' ) /* no leading zeroes! */
117 *setme_end
= (const uint8_t*)end
+ 1;
123 * Byte strings are encoded as follows:
124 * <string length encoded in base ten ASCII>:<string data>
125 * Note that there is no constant beginning delimiter, and no ending delimiter.
126 * Example: 4:spam represents the string "spam"
129 tr_bencParseStr( const uint8_t * buf
,
130 const uint8_t * bufend
,
131 const uint8_t ** setme_end
,
132 const uint8_t ** setme_str
,
133 size_t * setme_strlen
)
142 if( !isdigit( *buf
) )
145 end
= memchr( buf
, ':', bufend
- buf
);
150 len
= strtoul( (const char*)buf
, &endptr
, 10 );
151 if( errno
|| endptr
!= end
)
154 if( (const uint8_t*)end
+ 1 + len
> bufend
)
157 *setme_end
= (const uint8_t*)end
+ 1 + len
;
158 *setme_str
= (const uint8_t*)end
+ 1;
163 /* set to 1 to help expose bugs with tr_bencListAdd and tr_bencDictAdd */
164 #define LIST_SIZE 4 /* number of items to increment list/dict buffer by */
167 makeroom( tr_benc
* val
,
170 assert( TR_TYPE_LIST
== val
->type
|| TR_TYPE_DICT
== val
->type
);
172 if( val
->val
.l
.count
+ count
> val
->val
.l
.alloc
)
174 /* We need a bigger boat */
175 const int len
= val
->val
.l
.alloc
+ count
+
176 ( count
% LIST_SIZE
? LIST_SIZE
-
177 ( count
% LIST_SIZE
) : 0 );
178 void * tmp
= realloc( val
->val
.l
.vals
, len
* sizeof( tr_benc
) );
182 val
->val
.l
.alloc
= len
;
183 val
->val
.l
.vals
= tmp
;
190 getNode( tr_benc
* top
,
191 tr_ptrArray
* parentStack
,
197 assert( parentStack
);
199 if( tr_ptrArrayEmpty( parentStack
) )
202 parent
= tr_ptrArrayBack( parentStack
);
205 /* dictionary keys must be strings */
206 if( ( parent
->type
== TR_TYPE_DICT
)
207 && ( type
!= TR_TYPE_STR
)
208 && ( !( parent
->val
.l
.count
% 2 ) ) )
211 makeroom( parent
, 1 );
212 return parent
->val
.l
.vals
+ parent
->val
.l
.count
++;
216 * This function's previous recursive implementation was
217 * easier to read, but was vulnerable to a smash-stacking
218 * attack via maliciously-crafted bencoded data. (#667)
221 tr_bencParseImpl( const void * buf_in
,
222 const void * bufend_in
,
224 tr_ptrArray
* parentStack
,
225 const uint8_t ** setme_end
)
228 const uint8_t * buf
= buf_in
;
229 const uint8_t * bufend
= bufend_in
;
231 tr_bencInit( top
, 0 );
233 while( buf
!= bufend
)
235 if( buf
> bufend
) /* no more text to parse... */
238 if( *buf
== 'i' ) /* int */
244 if( ( err
= tr_bencParseInt( buf
, bufend
, &end
, &val
) ) )
247 node
= getNode( top
, parentStack
, TR_TYPE_INT
);
251 tr_bencInitInt( node
, val
);
254 if( tr_ptrArrayEmpty( parentStack
) )
257 else if( *buf
== 'l' ) /* list */
259 tr_benc
* node
= getNode( top
, parentStack
, TR_TYPE_LIST
);
262 tr_bencInit( node
, TR_TYPE_LIST
);
263 tr_ptrArrayAppend( parentStack
, node
);
266 else if( *buf
== 'd' ) /* dict */
268 tr_benc
* node
= getNode( top
, parentStack
, TR_TYPE_DICT
);
271 tr_bencInit( node
, TR_TYPE_DICT
);
272 tr_ptrArrayAppend( parentStack
, node
);
275 else if( *buf
== 'e' ) /* end of list or dict */
279 if( tr_ptrArrayEmpty( parentStack
) )
282 node
= tr_ptrArrayBack( parentStack
);
283 if( tr_bencIsDict( node
) && ( node
->val
.l
.count
% 2 ) )
285 /* odd # of children in dict */
286 tr_bencFree( &node
->val
.l
.vals
[--node
->val
.l
.count
] );
290 tr_ptrArrayPop( parentStack
);
291 if( tr_ptrArrayEmpty( parentStack
) )
294 else if( isdigit( *buf
) ) /* string? */
301 if( ( err
= tr_bencParseStr( buf
, bufend
, &end
, &str
, &str_len
) ) )
304 node
= getNode( top
, parentStack
, TR_TYPE_STR
);
308 tr_bencInitStr( node
, str
, str_len
);
311 if( tr_ptrArrayEmpty( parentStack
) )
314 else /* invalid bencoded text... march past it */
320 err
= !isSomething( top
) || !tr_ptrArrayEmpty( parentStack
);
322 if( !err
&& setme_end
)
329 tr_bencParse( const void * buf
,
332 const uint8_t ** setme_end
)
335 tr_ptrArray parentStack
= TR_PTR_ARRAY_INIT
;
337 top
->type
= 0; /* set to `uninitialized' */
338 err
= tr_bencParseImpl( buf
, end
, top
, &parentStack
, setme_end
);
342 tr_ptrArrayDestruct( &parentStack
, NULL
);
347 tr_bencLoad( const void * buf_in
,
349 tr_benc
* setme_benc
,
352 const uint8_t * buf
= buf_in
;
354 const int ret
= tr_bencParse( buf
, buf
+ buflen
, setme_benc
, &end
);
356 if( !ret
&& setme_end
)
357 *setme_end
= (char*) end
;
365 /* returns true if the benc's string was malloced.
366 * this occurs when the string is too long for our string buffer */
368 stringIsAlloced( const tr_benc
* val
)
370 return val
->val
.s
.len
>= sizeof( val
->val
.s
.str
.buf
);
373 /* returns a const pointer to the benc's string */
374 static inline const char*
375 getStr( const tr_benc
* val
)
377 return stringIsAlloced(val
) ? val
->val
.s
.str
.ptr
: val
->val
.s
.str
.buf
;
381 dictIndexOf( const tr_benc
* val
, const char * key
)
383 if( tr_bencIsDict( val
) )
386 const size_t len
= strlen( key
);
388 for( i
= 0; ( i
+ 1 ) < val
->val
.l
.count
; i
+= 2 )
390 const tr_benc
* child
= val
->val
.l
.vals
+ i
;
391 if( ( child
->type
== TR_TYPE_STR
)
392 && ( child
->val
.s
.len
== len
)
393 && !memcmp( getStr(child
), key
, len
) )
402 tr_bencDictFind( tr_benc
* val
, const char * key
)
404 const int i
= dictIndexOf( val
, key
);
406 return i
< 0 ? NULL
: &val
->val
.l
.vals
[i
+ 1];
410 tr_bencDictFindType( tr_benc
* dict
, const char * key
, int type
, tr_benc
** setme
)
412 return tr_bencIsType( *setme
= tr_bencDictFind( dict
, key
), type
);
416 tr_bencListSize( const tr_benc
* list
)
418 return tr_bencIsList( list
) ? list
->val
.l
.count
: 0;
422 tr_bencListChild( tr_benc
* val
,
425 tr_benc
* ret
= NULL
;
427 if( tr_bencIsList( val
) && ( i
< val
->val
.l
.count
) )
428 ret
= val
->val
.l
.vals
+ i
;
433 tr_bencListRemove( tr_benc
* list
, size_t i
)
435 if( tr_bencIsList( list
) && ( i
< list
->val
.l
.count
) )
437 tr_bencFree( &list
->val
.l
.vals
[i
] );
438 tr_removeElementFromArray( list
->val
.l
.vals
, i
, sizeof( tr_benc
), list
->val
.l
.count
-- );
446 tr_benc_warning( const char * err
)
448 fprintf( stderr
, "warning: %s\n", err
);
452 tr_bencGetInt( const tr_benc
* val
,
455 tr_bool success
= FALSE
;
457 if( !success
&& (( success
= tr_bencIsInt( val
))))
461 if( !success
&& (( success
= tr_bencIsBool( val
)))) {
462 tr_benc_warning( "reading bool as an int" );
464 *setme
= val
->val
.b
? 1 : 0;
471 tr_bencGetStr( const tr_benc
* val
, const char ** setme
)
473 const tr_bool success
= tr_bencIsString( val
);
476 *setme
= getStr( val
);
482 tr_bencGetBool( const tr_benc
* val
, tr_bool
* setme
)
485 tr_bool success
= FALSE
;
487 if(( success
= tr_bencIsBool( val
)))
490 if( !success
&& tr_bencIsInt( val
) )
491 if(( success
= ( val
->val
.i
==0 || val
->val
.i
==1 ) ))
492 *setme
= val
->val
.i
!=0;
494 if( !success
&& tr_bencGetStr( val
, &str
) )
495 if(( success
= ( !strcmp(str
,"true") || !strcmp(str
,"false"))))
496 *setme
= !strcmp(str
,"true");
502 tr_bencGetReal( const tr_benc
* val
, double * setme
)
504 tr_bool success
= FALSE
;
506 if( !success
&& (( success
= tr_bencIsReal( val
))))
509 if( !success
&& (( success
= tr_bencIsInt( val
))))
512 if( !success
&& tr_bencIsString(val
) )
518 /* the json spec requires a '.' decimal point regardless of locale */
519 tr_strlcpy( locale
, setlocale( LC_NUMERIC
, NULL
), sizeof( locale
) );
520 setlocale( LC_NUMERIC
, "POSIX" );
521 d
= strtod( getStr(val
), &endptr
);
522 setlocale( LC_NUMERIC
, locale
);
524 if(( success
= ( getStr(val
) != endptr
) && !*endptr
))
533 tr_bencDictFindInt( tr_benc
* dict
, const char * key
, int64_t * setme
)
535 return tr_bencGetInt( tr_bencDictFind( dict
, key
), setme
);
539 tr_bencDictFindBool( tr_benc
* dict
, const char * key
, tr_bool
* setme
)
541 return tr_bencGetBool( tr_bencDictFind( dict
, key
), setme
);
545 tr_bencDictFindReal( tr_benc
* dict
, const char * key
, double * setme
)
547 return tr_bencGetReal( tr_bencDictFind( dict
, key
), setme
);
551 tr_bencDictFindStr( tr_benc
* dict
, const char * key
, const char ** setme
)
553 return tr_bencGetStr( tr_bencDictFind( dict
, key
), setme
);
557 tr_bencDictFindList( tr_benc
* dict
, const char * key
, tr_benc
** setme
)
559 return tr_bencDictFindType( dict
, key
, TR_TYPE_LIST
, setme
);
563 tr_bencDictFindDict( tr_benc
* dict
, const char * key
, tr_benc
** setme
)
565 return tr_bencDictFindType( dict
, key
, TR_TYPE_DICT
, setme
);
569 tr_bencDictFindRaw( tr_benc
* dict
,
571 const uint8_t ** setme_raw
,
575 const tr_bool found
= tr_bencDictFindType( dict
, key
, TR_TYPE_STR
, &child
);
578 *setme_raw
= (uint8_t*) getStr(child
);
579 *setme_len
= child
->val
.s
.len
;
590 tr_bencInitRaw( tr_benc
* val
, const void * src
, size_t byteCount
)
593 tr_bencInit( val
, TR_TYPE_STR
);
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. */
601 if( byteCount
< sizeof( val
->val
.s
.str
.buf
) )
602 setme
= val
->val
.s
.str
.buf
;
604 setme
= val
->val
.s
.str
.ptr
= tr_new( char, byteCount
+ 1 );
606 memcpy( setme
, src
, byteCount
);
607 setme
[byteCount
] = '\0';
608 val
->val
.s
.len
= byteCount
;
612 tr_bencInitStr( tr_benc
* val
, const void * str
, int len
)
619 tr_bencInitRaw( val
, str
, len
);
623 tr_bencInitBool( tr_benc
* b
, int value
)
625 tr_bencInit( b
, TR_TYPE_BOOL
);
626 b
->val
.b
= value
!= 0;
630 tr_bencInitReal( tr_benc
* b
, double value
)
632 tr_bencInit( b
, TR_TYPE_REAL
);
637 tr_bencInitInt( tr_benc
* b
, int64_t value
)
639 tr_bencInit( b
, TR_TYPE_INT
);
644 tr_bencInitList( tr_benc
* b
, size_t reserveCount
)
646 tr_bencInit( b
, TR_TYPE_LIST
);
647 return tr_bencListReserve( b
, reserveCount
);
651 tr_bencListReserve( tr_benc
* b
, size_t count
)
653 assert( tr_bencIsList( b
) );
654 return makeroom( b
, count
);
658 tr_bencInitDict( tr_benc
* b
, size_t reserveCount
)
660 tr_bencInit( b
, TR_TYPE_DICT
);
661 return tr_bencDictReserve( b
, reserveCount
);
665 tr_bencDictReserve( tr_benc
* b
, size_t reserveCount
)
667 assert( tr_bencIsDict( b
) );
668 return makeroom( b
, reserveCount
* 2 );
672 tr_bencListAdd( tr_benc
* list
)
676 assert( tr_bencIsList( list
) );
678 if( list
->val
.l
.count
== list
->val
.l
.alloc
)
679 tr_bencListReserve( list
, LIST_SIZE
);
681 assert( list
->val
.l
.count
< list
->val
.l
.alloc
);
683 item
= &list
->val
.l
.vals
[list
->val
.l
.count
];
685 tr_bencInit( item
, TR_TYPE_INT
);
691 tr_bencListAddInt( tr_benc
* list
, int64_t val
)
693 tr_benc
* node
= tr_bencListAdd( list
);
695 tr_bencInitInt( node
, val
);
700 tr_bencListAddReal( tr_benc
* list
, double val
)
702 tr_benc
* node
= tr_bencListAdd( list
);
703 tr_bencInitReal( node
, val
);
708 tr_bencListAddBool( tr_benc
* list
, tr_bool val
)
710 tr_benc
* node
= tr_bencListAdd( list
);
711 tr_bencInitBool( node
, val
);
716 tr_bencListAddStr( tr_benc
* list
, const char * val
)
718 tr_benc
* node
= tr_bencListAdd( list
);
719 tr_bencInitStr( node
, val
, -1 );
724 tr_bencListAddRaw( tr_benc
* list
, const uint8_t * val
, size_t len
)
726 tr_benc
* node
= tr_bencListAdd( list
);
727 tr_bencInitRaw( node
, val
, len
);
732 tr_bencListAddList( tr_benc
* list
,
733 size_t reserveCount
)
735 tr_benc
* child
= tr_bencListAdd( list
);
737 tr_bencInitList( child
, reserveCount
);
742 tr_bencListAddDict( tr_benc
* list
,
743 size_t reserveCount
)
745 tr_benc
* child
= tr_bencListAdd( list
);
747 tr_bencInitDict( child
, reserveCount
);
752 tr_bencDictAdd( tr_benc
* dict
,
755 tr_benc
* keyval
, * itemval
;
757 assert( tr_bencIsDict( dict
) );
758 if( dict
->val
.l
.count
+ 2 > dict
->val
.l
.alloc
)
760 assert( dict
->val
.l
.count
+ 2 <= dict
->val
.l
.alloc
);
762 keyval
= dict
->val
.l
.vals
+ dict
->val
.l
.count
++;
763 tr_bencInitStr( keyval
, key
, -1 );
765 itemval
= dict
->val
.l
.vals
+ dict
->val
.l
.count
++;
766 tr_bencInit( itemval
, TR_TYPE_INT
);
772 dictFindOrAdd( tr_benc
* dict
, const char * key
, int type
)
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
);
784 /* if it doesn't exist, create it */
786 child
= tr_bencDictAdd( dict
, key
);
792 tr_bencDictAddInt( tr_benc
* dict
,
796 tr_benc
* child
= dictFindOrAdd( dict
, key
, TR_TYPE_INT
);
797 tr_bencInitInt( child
, val
);
802 tr_bencDictAddBool( tr_benc
* dict
, const char * key
, tr_bool val
)
804 tr_benc
* child
= dictFindOrAdd( dict
, key
, TR_TYPE_BOOL
);
805 tr_bencInitBool( child
, val
);
810 tr_bencDictAddReal( tr_benc
* dict
, const char * key
, double val
)
812 tr_benc
* child
= dictFindOrAdd( dict
, key
, TR_TYPE_REAL
);
813 tr_bencInitReal( child
, val
);
818 tr_bencDictAddStr( tr_benc
* dict
, const char * key
, const char * val
)
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
);
828 tr_bencDictRemove( dict
, key
);
833 /* if it doesn't exist, create it */
835 child
= tr_bencDictAdd( dict
, key
);
838 tr_bencInitStr( child
, val
, -1 );
844 tr_bencDictAddRaw( tr_benc
* dict
,
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
);
857 tr_bencDictRemove( dict
, key
);
862 /* if it doesn't exist, create it */
864 child
= tr_bencDictAdd( dict
, key
);
867 tr_bencInitRaw( child
, src
, len
);
873 tr_bencDictAddList( tr_benc
* dict
,
875 size_t reserveCount
)
877 tr_benc
* child
= tr_bencDictAdd( dict
, key
);
879 tr_bencInitList( child
, reserveCount
);
884 tr_bencDictAddDict( tr_benc
* dict
,
886 size_t reserveCount
)
888 tr_benc
* child
= tr_bencDictAdd( dict
, key
);
890 tr_bencInitDict( child
, reserveCount
);
895 tr_bencDictRemove( tr_benc
* dict
,
898 int i
= dictIndexOf( dict
, key
);
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] );
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];
910 dict
->val
.l
.count
-= 2;
912 return i
>= 0; /* return true if found */
926 compareKeyIndex( const void * va
,
929 const struct KeyIndex
* a
= va
;
930 const struct KeyIndex
* b
= vb
;
932 return strcmp( a
->key
, b
->key
);
945 nodeInitDict( struct SaveNode
* node
, const tr_benc
* val
)
949 struct KeyIndex
* indices
;
951 assert( tr_bencIsDict( val
) );
953 nKeys
= val
->val
.l
.count
/ 2;
955 node
->children
= tr_new0( int, nKeys
* 2 );
957 /* ugh, a dictionary's children have to be sorted by key... */
958 indices
= tr_new( struct KeyIndex
, nKeys
);
959 for( i
= j
= 0; i
< ( nKeys
* 2 ); i
+= 2, ++j
)
961 indices
[j
].key
= getStr(&val
->val
.l
.vals
[i
]);
962 indices
[j
].index
= i
;
964 qsort( indices
, j
, sizeof( struct KeyIndex
), compareKeyIndex
);
965 for( i
= 0; i
< j
; ++i
)
967 const int index
= indices
[i
].index
;
968 node
->children
[node
->childCount
++] = index
;
969 node
->children
[node
->childCount
++] = index
+ 1;
972 assert( node
->childCount
== nKeys
* 2 );
977 nodeInitList( struct SaveNode
* node
, const tr_benc
* val
)
981 assert( tr_bencIsList( val
) );
983 n
= val
->val
.l
.count
;
985 node
->childCount
= n
;
986 node
->children
= tr_new0( int, n
);
987 for( i
= 0; i
< n
; ++i
) /* a list's children don't need to be reordered */
988 node
->children
[i
] = i
;
992 nodeInitLeaf( struct SaveNode
* node
, const tr_benc
* val
)
994 assert( !isContainer( val
) );
1000 nodeInit( struct SaveNode
* node
, const tr_benc
* val
)
1002 static const struct SaveNode INIT_NODE
= { NULL
, 0, 0, 0, NULL
};
1005 if( tr_bencIsList( val
) ) nodeInitList( node
, val
);
1006 else if( tr_bencIsDict( val
) ) nodeInitDict( node
, val
);
1007 else nodeInitLeaf( node
, val
);
1010 typedef void ( *BencWalkFunc
)( const tr_benc
* val
, void * user_data
);
1014 BencWalkFunc intFunc
;
1015 BencWalkFunc boolFunc
;
1016 BencWalkFunc realFunc
;
1017 BencWalkFunc stringFunc
;
1018 BencWalkFunc dictBeginFunc
;
1019 BencWalkFunc listBeginFunc
;
1020 BencWalkFunc containerEndFunc
;
1024 * This function's previous recursive implementation was
1025 * easier to read, but was vulnerable to a smash-stacking
1026 * attack via maliciously-crafted bencoded data. (#667)
1029 bencWalk( const tr_benc
* top
,
1030 const struct WalkFuncs
* walkFuncs
,
1034 int stackAlloc
= 64;
1035 struct SaveNode
* stack
= tr_new( struct SaveNode
, stackAlloc
);
1037 nodeInit( &stack
[stackSize
++], top
);
1039 while( stackSize
> 0 )
1041 struct SaveNode
* node
= &stack
[stackSize
-1];
1042 const tr_benc
* val
;
1044 if( !node
->valIsVisited
)
1047 node
->valIsVisited
= TRUE
;
1049 else if( node
->childIndex
< node
->childCount
)
1051 const int index
= node
->children
[node
->childIndex
++];
1052 val
= node
->val
->val
.l
.vals
+ index
;
1054 else /* done with this node */
1056 if( isContainer( node
->val
) )
1057 walkFuncs
->containerEndFunc( node
->val
, user_data
);
1059 tr_free( node
->children
);
1063 if( val
) switch( val
->type
)
1066 walkFuncs
->intFunc( val
, user_data
);
1070 walkFuncs
->boolFunc( val
, user_data
);
1074 walkFuncs
->realFunc( val
, user_data
);
1078 walkFuncs
->stringFunc( val
, user_data
);
1082 if( val
== node
->val
)
1083 walkFuncs
->listBeginFunc( val
, user_data
);
1085 if( stackAlloc
== stackSize
) {
1087 stack
= tr_renew( struct SaveNode
, stack
, stackAlloc
);
1089 nodeInit( &stack
[stackSize
++], val
);
1094 if( val
== node
->val
)
1095 walkFuncs
->dictBeginFunc( val
, user_data
);
1097 if( stackAlloc
== stackSize
) {
1099 stack
= tr_renew( struct SaveNode
, stack
, stackAlloc
);
1101 nodeInit( &stack
[stackSize
++], val
);
1106 /* did caller give us an uninitialized val? */
1107 tr_err( "%s", _( "Invalid metadata" ) );
1120 saveIntFunc( const tr_benc
* val
, void * evbuf
)
1122 evbuffer_add_printf( evbuf
, "i%" PRId64
"e", val
->val
.i
);
1126 saveBoolFunc( const tr_benc
* val
, void * evbuf
)
1129 evbuffer_add( evbuf
, "i1e", 3 );
1131 evbuffer_add( evbuf
, "i0e", 3 );
1135 saveRealFunc( const tr_benc
* val
, void * evbuf
)
1141 /* always use a '.' decimal point s.t. locale-hopping doesn't bite us */
1142 tr_strlcpy( locale
, setlocale( LC_NUMERIC
, NULL
), sizeof( locale
) );
1143 setlocale( LC_NUMERIC
, "POSIX" );
1144 tr_snprintf( buf
, sizeof( buf
), "%f", val
->val
.d
);
1145 setlocale( LC_NUMERIC
, locale
);
1147 len
= strlen( buf
);
1148 evbuffer_add_printf( evbuf
, "%lu:", (unsigned long)len
);
1149 evbuffer_add( evbuf
, buf
, len
);
1153 saveStringFunc( const tr_benc
* val
, void * evbuf
)
1155 evbuffer_add_printf( evbuf
, "%lu:", (unsigned long)val
->val
.s
.len
);
1156 evbuffer_add( evbuf
, getStr(val
), val
->val
.s
.len
);
1160 saveDictBeginFunc( const tr_benc
* val UNUSED
, void * evbuf
)
1162 evbuffer_add( evbuf
, "d", 1 );
1166 saveListBeginFunc( const tr_benc
* val UNUSED
, void * evbuf
)
1168 evbuffer_add( evbuf
, "l", 1 );
1172 saveContainerEndFunc( const tr_benc
* val UNUSED
, void * evbuf
)
1174 evbuffer_add( evbuf
, "e", 1 );
1177 static const struct WalkFuncs saveFuncs
= { saveIntFunc
,
1183 saveContainerEndFunc
};
1190 freeDummyFunc( const tr_benc
* val UNUSED
, void * buf UNUSED
)
1194 freeStringFunc( const tr_benc
* val
, void * unused UNUSED
)
1196 if( stringIsAlloced( val
) )
1197 tr_free( val
->val
.s
.str
.ptr
);
1201 freeContainerEndFunc( const tr_benc
* val
, void * unused UNUSED
)
1203 tr_free( val
->val
.l
.vals
);
1206 static const struct WalkFuncs freeWalkFuncs
= { freeDummyFunc
,
1212 freeContainerEndFunc
};
1215 tr_bencFree( tr_benc
* val
)
1217 if( isSomething( val
) )
1218 bencWalk( val
, &freeWalkFuncs
, NULL
);
1225 /** @brief Implementation helper class for tr_bencToBuffer(TR_FMT_JSON) */
1233 /** @brief Implementation helper class for tr_bencToBuffer(TR_FMT_JSON) */
1238 struct evbuffer
* out
;
1242 jsonIndent( struct jsonWalk
* data
)
1244 if( data
->doIndent
)
1247 const int width
= tr_list_size( data
->parents
) * 4;
1250 memset( buf
+1, ' ', width
);
1251 evbuffer_add( data
->out
, buf
, 1+width
);
1256 jsonChildFunc( struct jsonWalk
* data
)
1260 struct ParentState
* parentState
= data
->parents
->data
;
1262 switch( parentState
->bencType
)
1266 const int i
= parentState
->childIndex
++;
1268 evbuffer_add( data
->out
, ": ", data
->doIndent
? 2 : 1 );
1270 const tr_bool isLast
= parentState
->childIndex
== parentState
->childCount
;
1272 evbuffer_add( data
->out
, ", ", data
->doIndent
? 2 : 1 );
1281 const tr_bool isLast
= ++parentState
->childIndex
== parentState
->childCount
;
1283 evbuffer_add( data
->out
, ", ", data
->doIndent
? 2 : 1 );
1296 jsonPushParent( struct jsonWalk
* data
,
1297 const tr_benc
* benc
)
1299 struct ParentState
* parentState
= tr_new( struct ParentState
, 1 );
1301 parentState
->bencType
= benc
->type
;
1302 parentState
->childIndex
= 0;
1303 parentState
->childCount
= benc
->val
.l
.count
;
1304 tr_list_prepend( &data
->parents
, parentState
);
1308 jsonPopParent( struct jsonWalk
* data
)
1310 tr_free( tr_list_pop_front( &data
->parents
) );
1314 jsonIntFunc( const tr_benc
* val
,
1317 struct jsonWalk
* data
= vdata
;
1319 evbuffer_add_printf( data
->out
, "%" PRId64
, val
->val
.i
);
1320 jsonChildFunc( data
);
1324 jsonBoolFunc( const tr_benc
* val
, void * vdata
)
1326 struct jsonWalk
* data
= vdata
;
1329 evbuffer_add( data
->out
, "true", 4 );
1331 evbuffer_add( data
->out
, "false", 5 );
1333 jsonChildFunc( data
);
1337 jsonRealFunc( const tr_benc
* val
, void * vdata
)
1339 struct jsonWalk
* data
= vdata
;
1342 if( fabs( val
->val
.d
- (int)val
->val
.d
) < 0.00001 )
1343 evbuffer_add_printf( data
->out
, "%d", (int)val
->val
.d
);
1345 /* json requires a '.' decimal point regardless of locale */
1346 tr_strlcpy( locale
, setlocale( LC_NUMERIC
, NULL
), sizeof( locale
) );
1347 setlocale( LC_NUMERIC
, "POSIX" );
1348 evbuffer_add_printf( data
->out
, "%.4f", tr_truncd( val
->val
.d
, 4 ) );
1349 setlocale( LC_NUMERIC
, locale
);
1352 jsonChildFunc( data
);
1356 jsonStringFunc( const tr_benc
* val
, void * vdata
)
1358 struct jsonWalk
* data
= vdata
;
1359 const unsigned char * it
= (const unsigned char *) getStr(val
);
1360 const unsigned char * end
= it
+ val
->val
.s
.len
;
1362 evbuffer_expand( data
->out
, val
->val
.s
.len
+ 2 );
1363 evbuffer_add( data
->out
, "\"", 1 );
1365 for( ; it
!=end
; ++it
)
1369 case '\b': evbuffer_add( data
->out
, "\\b", 2 ); break;
1370 case '\f': evbuffer_add( data
->out
, "\\f", 2 ); break;
1371 case '\n': evbuffer_add( data
->out
, "\\n", 2 ); break;
1372 case '\r': evbuffer_add( data
->out
, "\\r", 2 ); break;
1373 case '\t': evbuffer_add( data
->out
, "\\t", 2 ); break;
1374 case '"': evbuffer_add( data
->out
, "\\\"", 2 ); break;
1375 case '\\': evbuffer_add( data
->out
, "\\\\", 2 ); break;
1378 if( isascii( *it
) )
1379 evbuffer_add( data
->out
, it
, 1 );
1381 const UTF8
* tmp
= it
;
1384 ConversionResult result
= ConvertUTF8toUTF32( &tmp
, end
, &u32
, &buf
+ 1, 0 );
1385 if((( result
==conversionOK
) || (result
==targetExhausted
)) && (tmp
!=it
)) {
1386 evbuffer_add_printf( data
->out
, "\\u%04x", (unsigned int)buf
);
1392 evbuffer_add( data
->out
, "\"", 1 );
1393 jsonChildFunc( data
);
1397 jsonDictBeginFunc( const tr_benc
* val
,
1400 struct jsonWalk
* data
= vdata
;
1402 jsonPushParent( data
, val
);
1403 evbuffer_add( data
->out
, "{", 1 );
1404 if( val
->val
.l
.count
)
1409 jsonListBeginFunc( const tr_benc
* val
,
1412 const size_t nChildren
= tr_bencListSize( val
);
1413 struct jsonWalk
* data
= vdata
;
1415 jsonPushParent( data
, val
);
1416 evbuffer_add( data
->out
, "[", 1 );
1422 jsonContainerEndFunc( const tr_benc
* val
,
1425 struct jsonWalk
* data
= vdata
;
1426 int emptyContainer
= FALSE
;
1428 jsonPopParent( data
);
1429 if( !emptyContainer
)
1431 if( tr_bencIsDict( val
) )
1432 evbuffer_add( data
->out
, "}", 1 );
1434 evbuffer_add( data
->out
, "]", 1 );
1435 jsonChildFunc( data
);
1438 static const struct WalkFuncs jsonWalkFuncs
= { jsonIntFunc
,
1444 jsonContainerEndFunc
};
1451 tr_bencListCopy( tr_benc
* target
, const tr_benc
* src
)
1454 const tr_benc
* val
;
1456 while(( val
= tr_bencListChild( (tr_benc
*)src
, i
++ )))
1458 if( tr_bencIsBool( val
) )
1460 tr_bool boolVal
= 0;
1461 tr_bencGetBool( val
, &boolVal
);
1462 tr_bencListAddBool( target
, boolVal
);
1464 else if( tr_bencIsReal( val
) )
1467 tr_bencGetReal( val
, &realVal
);
1468 tr_bencListAddReal( target
, realVal
);
1470 else if( tr_bencIsInt( val
) )
1473 tr_bencGetInt( val
, &intVal
);
1474 tr_bencListAddInt( target
, intVal
);
1476 else if( tr_bencIsString( val
) )
1478 tr_bencListAddRaw( target
, (const uint8_t*)getStr( val
), val
->val
.s
.len
);
1480 else if( tr_bencIsDict( val
) )
1482 tr_bencMergeDicts( tr_bencListAddDict( target
, 0 ), val
);
1484 else if ( tr_bencIsList( val
) )
1486 tr_bencListCopy( tr_bencListAddList( target
, 0 ), val
);
1490 tr_err( "tr_bencListCopy skipping item" );
1496 tr_bencDictSize( const tr_benc
* dict
)
1500 if( tr_bencIsDict( dict
) )
1501 count
= dict
->val
.l
.count
/ 2;
1507 tr_bencDictChild( tr_benc
* dict
, size_t n
, const char ** key
, tr_benc
** val
)
1509 tr_bool success
= 0;
1511 assert( tr_bencIsDict( dict
) );
1513 if( tr_bencIsDict( dict
) && (n
*2)+1 <= dict
->val
.l
.count
)
1515 tr_benc
* k
= dict
->val
.l
.vals
+ (n
*2);
1516 tr_benc
* v
= dict
->val
.l
.vals
+ (n
*2) + 1;
1517 if(( success
= tr_bencGetStr( k
, key
) && isSomething( v
)))
1525 tr_bencMergeDicts( tr_benc
* target
, const tr_benc
* source
)
1528 const size_t sourceCount
= tr_bencDictSize( source
);
1530 assert( tr_bencIsDict( target
) );
1531 assert( tr_bencIsDict( source
) );
1533 for( i
=0; i
<sourceCount
; ++i
)
1539 if( tr_bencDictChild( (tr_benc
*)source
, i
, &key
, &val
) )
1541 if( tr_bencIsBool( val
) )
1544 tr_bencGetBool( val
, &boolVal
);
1545 tr_bencDictAddBool( target
, key
, boolVal
);
1547 else if( tr_bencIsReal( val
) )
1550 tr_bencGetReal( val
, &realVal
);
1551 tr_bencDictAddReal( target
, key
, realVal
);
1553 else if( tr_bencIsInt( val
) )
1556 tr_bencGetInt( val
, &intVal
);
1557 tr_bencDictAddInt( target
, key
, intVal
);
1559 else if( tr_bencIsString( val
) )
1561 tr_bencDictAddRaw( target
, key
, getStr( val
), val
->val
.s
.len
);
1563 else if( tr_bencIsDict( val
) && tr_bencDictFindDict( target
, key
, &t
) )
1565 tr_bencMergeDicts( t
, val
);
1567 else if( tr_bencIsList( val
) )
1569 if( tr_bencDictFind( target
, key
) == NULL
)
1571 tr_bencListCopy( tr_bencDictAddList( target
, key
, tr_bencListSize( val
) ), val
);
1576 tr_dbg( "tr_bencMergeDicts skipping \"%s\"", key
);
1587 tr_bencToBuf( const tr_benc
* top
, tr_fmt_mode mode
, struct evbuffer
* buf
)
1589 evbuffer_drain( buf
, EVBUFFER_LENGTH( buf
) );
1590 evbuffer_expand( buf
, 4096 ); /* alloc a little memory to start off with */
1595 bencWalk( top
, &saveFuncs
, buf
);
1599 case TR_FMT_JSON_LEAN
: {
1600 struct jsonWalk data
;
1601 data
.doIndent
= mode
==TR_FMT_JSON
;
1603 data
.parents
= NULL
;
1604 bencWalk( top
, &jsonWalkFuncs
, &data
);
1605 if( EVBUFFER_LENGTH( buf
) )
1606 evbuffer_add_printf( buf
, "\n" );
1613 tr_bencToStr( const tr_benc
* top
, tr_fmt_mode mode
, int * len
)
1616 struct evbuffer
* buf
= evbuffer_new( );
1617 tr_bencToBuf( top
, mode
, buf
);
1618 ret
= tr_strndup( EVBUFFER_DATA( buf
), EVBUFFER_LENGTH( buf
) );
1620 *len
= (int) EVBUFFER_LENGTH( buf
);
1621 evbuffer_free( buf
);
1625 /* portability wrapper for mkstemp(). */
1627 tr_mkstemp( char * template )
1630 const int flags
= O_RDWR
| O_BINARY
| O_CREAT
| O_EXCL
| _O_SHORT_LIVED
;
1631 const mode_t mode
= _S_IREAD
| _S_IWRITE
;
1633 return open( template, flags
, mode
);
1635 return mkstemp( template );
1639 /* portability wrapper for fsync(). */
1651 tr_bencToFile( const tr_benc
* top
, tr_fmt_mode mode
, const char * filename
)
1656 char buf
[TR_PATH_MAX
];
1658 /* follow symlinks to find the "real" file, to make sure the temporary
1659 * we build with tr_mkstemp() is created on the right partition */
1660 if( tr_realpath( filename
, buf
) != NULL
)
1663 /* if the file already exists, try to move it out of the way & keep it as a backup */
1664 tmp
= tr_strdup_printf( "%s.tmp.XXXXXX", filename
);
1665 fd
= tr_mkstemp( tmp
);
1669 char * str
= tr_bencToStr( top
, mode
, &len
);
1671 if( write( fd
, str
, len
) == (ssize_t
)len
)
1674 const tr_bool already_exists
= !stat( filename
, &sb
) && S_ISREG( sb
.st_mode
);
1677 tr_close_file( fd
);
1679 if( !already_exists
|| !unlink( filename
) )
1681 if( !rename( tmp
, filename
) )
1683 tr_inf( _( "Saved \"%s\"" ), filename
);
1688 tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename
, tr_strerror( err
) );
1695 tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename
, tr_strerror( err
) );
1702 tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp
, tr_strerror( err
) );
1703 tr_close_file( fd
);
1712 tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp
, tr_strerror( err
) );
1724 tr_bencLoadFile( tr_benc
* setme
, tr_fmt_mode mode
, const char * filename
)
1730 content
= tr_loadFile( filename
, &contentLen
);
1731 if( !content
&& errno
)
1736 if( mode
== TR_FMT_BENC
)
1737 err
= tr_bencLoad( content
, contentLen
, setme
, NULL
);
1739 err
= tr_jsonParse( filename
, content
, contentLen
, setme
, NULL
);