mirror of
https://github.com/transmission/transmission
synced 2024-12-25 01:03:01 +00:00
fix r2306 double-free crash reported by Gimp_, webaake
This commit is contained in:
parent
3a4a0053ca
commit
34b4d0b7f9
4 changed files with 35 additions and 42 deletions
|
@ -12,29 +12,22 @@
|
|||
#include "list.h"
|
||||
#include "utils.h"
|
||||
|
||||
int
|
||||
tr_list_length( const tr_list_t * list )
|
||||
{
|
||||
int i = 0;
|
||||
while( list ) {
|
||||
++i;
|
||||
list = list->next;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
tr_list_t*
|
||||
tr_list_alloc( void )
|
||||
static tr_list_t*
|
||||
node_alloc( void )
|
||||
{
|
||||
return tr_new0( tr_list_t, 1 );
|
||||
}
|
||||
|
||||
void
|
||||
tr_list_free1( tr_list_t* node )
|
||||
static void
|
||||
node_free( tr_list_t* node )
|
||||
{
|
||||
tr_free( node );
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void
|
||||
tr_list_free( tr_list_t* list )
|
||||
{
|
||||
|
@ -42,14 +35,14 @@ tr_list_free( tr_list_t* list )
|
|||
{
|
||||
tr_list_t * node = list;
|
||||
list = list->next;
|
||||
tr_list_free1( node );
|
||||
node_free( node );
|
||||
}
|
||||
}
|
||||
|
||||
tr_list_t*
|
||||
tr_list_prepend( tr_list_t * list, void * data )
|
||||
{
|
||||
tr_list_t * node = tr_list_alloc ();
|
||||
tr_list_t * node = node_alloc ();
|
||||
node->data = data;
|
||||
node->next = list;
|
||||
if( list )
|
||||
|
@ -60,17 +53,19 @@ tr_list_prepend( tr_list_t * list, void * data )
|
|||
tr_list_t*
|
||||
tr_list_append( tr_list_t * list, void * data )
|
||||
{
|
||||
tr_list_t * node = list;
|
||||
tr_list_t * l = tr_list_alloc( );
|
||||
l->data = data;
|
||||
tr_list_t * node = node_alloc( );
|
||||
node->data = data;
|
||||
if( !list )
|
||||
return l;
|
||||
while( node->next )
|
||||
node = node->next;
|
||||
node->next = l;
|
||||
l->prev = node;
|
||||
return node;
|
||||
else {
|
||||
tr_list_t * l = list;
|
||||
while( l->next )
|
||||
l = l->next;
|
||||
l->next = node;
|
||||
node->prev = l;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
tr_list_t*
|
||||
tr_list_find_data ( tr_list_t * list, const void * data )
|
||||
|
@ -83,7 +78,7 @@ tr_list_find_data ( tr_list_t * list, const void * data )
|
|||
}
|
||||
|
||||
tr_list_t*
|
||||
tr_list_remove( tr_list_t * list, const void * data )
|
||||
tr_list_remove_data ( tr_list_t * list, const void * data )
|
||||
{
|
||||
tr_list_t * node = tr_list_find_data( list, data );
|
||||
tr_list_t * prev = node ? node->prev : NULL;
|
||||
|
@ -91,7 +86,7 @@ tr_list_remove( tr_list_t * list, const void * data )
|
|||
if( prev ) prev->next = next;
|
||||
if( next ) next->prev = prev;
|
||||
if( list == node ) list = next;
|
||||
tr_list_free1( node );
|
||||
node_free( node );
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -114,4 +109,3 @@ tr_list_foreach( tr_list_t * list, TrListForeachFunc func )
|
|||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,10 @@ typedef struct tr_list_s
|
|||
}
|
||||
tr_list_t;
|
||||
|
||||
void tr_list_free_1 ( void );
|
||||
void tr_list_free ( tr_list_t* );
|
||||
int tr_list_length ( const tr_list_t* );
|
||||
tr_list_t* tr_list_append ( tr_list_t*, void * data );
|
||||
tr_list_t* tr_list_prepend ( tr_list_t*, void * data );
|
||||
tr_list_t* tr_list_remove ( tr_list_t*, const void * data );
|
||||
tr_list_t* tr_list_remove_data ( tr_list_t*, const void * data );
|
||||
tr_list_t* tr_list_pop ( tr_list_t*, void ** setme );
|
||||
|
||||
typedef int (*TrListCompareFunc)(const void * a, const void * b);
|
||||
|
|
|
@ -123,7 +123,7 @@ blockPending( tr_torrent_t * tor,
|
|||
|
||||
r = (tr_request_t*) peer->outRequests->data;
|
||||
assert( r != NULL );
|
||||
peer->outRequests = tr_list_remove( peer->outRequests, r );
|
||||
peer->outRequests = tr_list_remove_data( peer->outRequests, r );
|
||||
|
||||
if( !tr_cpPieceIsComplete( tor->completion, r->index ) ) /* sanity clause */
|
||||
{
|
||||
|
|
|
@ -417,8 +417,9 @@ static inline int parseCancel( tr_torrent_t * tor, tr_peer_t * peer,
|
|||
req.begin = begin;
|
||||
req.length = length;
|
||||
while(( l = tr_list_find( peer->outRequests, reqCompare, &req ) )) {
|
||||
tr_free( l->data );
|
||||
peer->outRequests = tr_list_remove( peer->outRequests, l );
|
||||
tr_request_t * r = (tr_request_t *) l->data;
|
||||
peer->outRequests = tr_list_remove_data( peer->outRequests, r );
|
||||
tr_free( r );
|
||||
}
|
||||
|
||||
return TR_OK;
|
||||
|
|
Loading…
Reference in a new issue