***/
static tr_bool
-getfile( char ** setme,
- const char * root,
- tr_benc * path )
+path_is_suspicious( const char * path )
+{
+ return ( path == NULL )
+ || ( strstr( path, "../" ) != NULL );
+}
+
+static tr_bool
+getfile( char ** setme, const char * root, tr_benc * path )
{
tr_bool success = FALSE;
if( tr_bencIsList( path ) )
{
+ int i;
+ const int n = tr_bencListSize( path );
struct evbuffer * buf = evbuffer_new( );
- int n = tr_bencListSize( path );
- int i;
evbuffer_add( buf, root, strlen( root ) );
for( i = 0; i < n; ++i )
{
const char * str;
- if( tr_bencGetStr( tr_bencListChild( path, i ), &str )
- && strcmp( str, ".." ) )
+ if( tr_bencGetStr( tr_bencListChild( path, i ), &str ) )
{
evbuffer_add( buf, TR_PATH_DELIMITER_STR, 1 );
evbuffer_add( buf, str, strlen( str ) );
success = TRUE;
}
+ if( ( *setme != NULL ) && path_is_suspicious( *setme ) )
+ {
+ tr_free( *setme );
+ *setme = NULL;
+ success = FALSE;
+ }
+
return success;
}
static const char*
-parseFiles( tr_info * inf,
- tr_benc * files,
- const tr_benc * length )
+parseFiles( tr_info * inf, tr_benc * files, const tr_benc * length )
{
int64_t len;
}
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 );