static const char* parseFiles (tr_info * inf, tr_benc * files, const tr_benc * length) { int64_t len; inf->totalSize = 0; if (tr_bencIsList (files)) /* multi-file mode */ { tr_file_index_t i; struct evbuffer * buf = evbuffer_new (); inf->isMultifile = 1; inf->fileCount = tr_bencListSize (files); inf->files = tr_new0 (tr_file, inf->fileCount); for (i=0; i<inf->fileCount; i++) { tr_benc * file; tr_benc * path; file = tr_bencListChild (files, i); if (!tr_bencIsDict (file)) return "files"; if (!tr_bencDictFindList (file, "path.utf-8", &path)) if (!tr_bencDictFindList (file, "path", &path)) return "path"; if (!getfile (&inf->files[i].name, inf->name, path, buf)) return "path"; if (!tr_bencDictFindInt (file, "length", &len)) return "length"; inf->files[i].length = len; inf->totalSize += len; } evbuffer_free (buf); } else if (tr_bencGetInt (length, &len)) /* single-file mode */ { if (path_is_suspicious (inf->name)) return "path"; inf->isMultifile = 0; inf->fileCount = 1; inf->files = tr_new0 (tr_file, 1); inf->files[0].name = tr_strdup (inf->name); inf->files[0].length = len; inf->totalSize += len; } else { return "length"; } return NULL; }
static tr_bool getfile( char ** setme, const char * root, tr_benc * path ) { tr_bool success = FALSE; if( tr_bencIsList( path ) ) { int i; char * tmp; const int n = tr_bencListSize( path ); struct evbuffer * buf = evbuffer_new( ); evbuffer_add( buf, root, strlen( root ) ); for( i = 0; i < n; ++i ) { const char * str; if( tr_bencGetStr( tr_bencListChild( path, i ), &str ) ) { evbuffer_add( buf, TR_PATH_DELIMITER_STR, 1 ); evbuffer_add( buf, str, strlen( str ) ); } } tmp = evbuffer_free_to_str( buf ); *setme = tr_utf8clean( tmp, -1 ); tr_free( tmp ); /* fprintf( stderr, "[%s]\n", *setme ); */ success = TRUE; } if( ( *setme != NULL ) && path_is_suspicious( *setme ) ) { tr_free( *setme ); *setme = NULL; success = FALSE; } return success; }
static bool getfile (char ** setme, const char * root, tr_variant * path, struct evbuffer * buf) { bool success = false; if (tr_variantIsList (path)) { int i; const int n = tr_variantListSize (path); evbuffer_drain (buf, evbuffer_get_length (buf)); evbuffer_add (buf, root, strlen (root)); for (i=0; i<n; i++) { size_t len; const char * str; if (tr_variantGetStr (tr_variantListChild (path, i), &str, &len)) { evbuffer_add (buf, TR_PATH_DELIMITER_STR, 1); evbuffer_add (buf, str, len); } } *setme = tr_utf8clean ((char*)evbuffer_pullup (buf, -1), evbuffer_get_length (buf)); /* fprintf (stderr, "[%s]\n", *setme); */ success = true; } if ((*setme != NULL) && path_is_suspicious (*setme)) { tr_free (*setme); *setme = NULL; success = false; } return success; }