fix r2306 double-free crash reported by Gimp_, webaake

This commit is contained in:
Charles Kerr 2007-07-09 16:30:20 +00:00
parent 3a4a0053ca
commit 34b4d0b7f9
4 changed files with 35 additions and 42 deletions

View File

@ -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,16 +53,18 @@ 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 list;
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*
@ -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;
}
}

View File

@ -19,20 +19,18 @@ 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_pop ( tr_list_t*, void ** setme );
void tr_list_free ( 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_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);
tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void * b );
tr_list_t* tr_list_find_data ( tr_list_t*, const void * data );
tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void * b );
tr_list_t* tr_list_find_data ( tr_list_t*, const void * data );
typedef void (*TrListForeachFunc)(void *);
void tr_list_foreach( tr_list_t*, TrListForeachFunc func );
void tr_list_foreach ( tr_list_t*, TrListForeachFunc func );
#endif /* TR_LIST_H */

View File

@ -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 */
{

View File

@ -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;