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:
parent
3a4a0053ca
commit
34b4d0b7f9
4 changed files with 35 additions and 42 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue