1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-25 09:13:06 +00:00

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 "list.h"
#include "utils.h" #include "utils.h"
int static tr_list_t*
tr_list_length( const tr_list_t * list ) node_alloc( void )
{
int i = 0;
while( list ) {
++i;
list = list->next;
}
return i;
}
tr_list_t*
tr_list_alloc( void )
{ {
return tr_new0( tr_list_t, 1 ); return tr_new0( tr_list_t, 1 );
} }
void static void
tr_list_free1( tr_list_t* node ) node_free( tr_list_t* node )
{ {
tr_free( node ); tr_free( node );
} }
/***
****
***/
void void
tr_list_free( tr_list_t* list ) tr_list_free( tr_list_t* list )
{ {
@ -42,14 +35,14 @@ tr_list_free( tr_list_t* list )
{ {
tr_list_t * node = list; tr_list_t * node = list;
list = list->next; list = list->next;
tr_list_free1( node ); node_free( node );
} }
} }
tr_list_t* tr_list_t*
tr_list_prepend( tr_list_t * list, void * data ) 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->data = data;
node->next = list; node->next = list;
if( list ) if( list )
@ -60,16 +53,18 @@ tr_list_prepend( tr_list_t * list, void * data )
tr_list_t* tr_list_t*
tr_list_append( tr_list_t * list, void * data ) tr_list_append( tr_list_t * list, void * data )
{ {
tr_list_t * node = list; tr_list_t * node = node_alloc( );
tr_list_t * l = tr_list_alloc( ); node->data = data;
l->data = data;
if( !list ) if( !list )
return l; return node;
while( node->next ) else {
node = node->next; tr_list_t * l = list;
node->next = l; while( l->next )
l->prev = node; l = l->next;
l->next = node;
node->prev = l;
return list; return list;
}
} }
tr_list_t* tr_list_t*
@ -83,7 +78,7 @@ tr_list_find_data ( tr_list_t * list, const void * data )
} }
tr_list_t* 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 * node = tr_list_find_data( list, data );
tr_list_t * prev = node ? node->prev : NULL; 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( prev ) prev->next = next;
if( next ) next->prev = prev; if( next ) next->prev = prev;
if( list == node ) list = next; if( list == node ) list = next;
tr_list_free1( node ); node_free( node );
return list; return list;
} }
@ -114,4 +109,3 @@ tr_list_foreach( tr_list_t * list, TrListForeachFunc func )
list = list->next; list = list->next;
} }
} }

View file

@ -19,12 +19,10 @@ typedef struct tr_list_s
} }
tr_list_t; tr_list_t;
void tr_list_free_1 ( void );
void tr_list_free ( tr_list_t* ); 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_append ( tr_list_t*, void * data );
tr_list_t* tr_list_prepend ( 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 ); tr_list_t* tr_list_pop ( tr_list_t*, void ** setme );
typedef int (*TrListCompareFunc)(const void * a, const void * b); typedef int (*TrListCompareFunc)(const void * a, const void * b);
@ -32,7 +30,7 @@ tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void *
tr_list_t* tr_list_find_data ( tr_list_t*, const void * data ); tr_list_t* tr_list_find_data ( tr_list_t*, const void * data );
typedef void (*TrListForeachFunc)(void *); 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 */ #endif /* TR_LIST_H */

View file

@ -123,7 +123,7 @@ blockPending( tr_torrent_t * tor,
r = (tr_request_t*) peer->outRequests->data; r = (tr_request_t*) peer->outRequests->data;
assert( r != NULL ); 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 */ 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.begin = begin;
req.length = length; req.length = length;
while(( l = tr_list_find( peer->outRequests, reqCompare, &req ) )) { while(( l = tr_list_find( peer->outRequests, reqCompare, &req ) )) {
tr_free( l->data ); tr_request_t * r = (tr_request_t *) l->data;
peer->outRequests = tr_list_remove( peer->outRequests, l ); peer->outRequests = tr_list_remove_data( peer->outRequests, r );
tr_free( r );
} }
return TR_OK; return TR_OK;