From f32d3b24fecaa1040069670bb983aa6966446bca Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 27 Jan 2008 16:08:20 +0000 Subject: [PATCH] #653 "overflow issue in Transmission/1.01" (1) safeguard bitfield functions against overflow. (2) add regression tests to see if this data is corrupted again in the future. --- libtransmission/completion.c | 20 +++++++++++++++++--- libtransmission/utils.c | 6 +++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libtransmission/completion.c b/libtransmission/completion.c index 6059b56ca..5efb76161 100644 --- a/libtransmission/completion.c +++ b/libtransmission/completion.c @@ -151,7 +151,8 @@ const tr_bitfield * tr_cpPieceBitfield( const tr_completion * cp ) return cp->pieceBitfield; } -void tr_cpPieceAdd( tr_completion * cp, int piece ) +void +tr_cpPieceAdd( tr_completion * cp, int piece ) { const tr_torrent * tor = cp->tor; const int start = tr_torPieceFirstBlock(tor,piece); @@ -162,7 +163,8 @@ void tr_cpPieceAdd( tr_completion * cp, int piece ) tr_cpBlockAdd( cp, i ); } -void tr_cpPieceRem( tr_completion * cp, int piece ) +void +tr_cpPieceRem( tr_completion * cp, int piece ) { const tr_torrent * tor = cp->tor; const int start = tr_torPieceFirstBlock(tor,piece); @@ -189,6 +191,10 @@ void tr_cpPieceRem( tr_completion * cp, int piece ) cp->completeBlocks[piece] = 0; tr_bitfieldRemRange ( cp->blockBitfield, start, end ); tr_bitfieldRem( cp->pieceBitfield, piece ); + + assert( cp->completeHave <= tor->info.totalSize ); + assert( cp->doneHave <= tor->info.totalSize ); + assert( cp->doneHave <= cp->completeHave ); } int tr_cpBlockIsComplete( const tr_completion * cp, int block ) @@ -218,6 +224,10 @@ tr_cpBlockAdd( tr_completion * cp, int block ) if( !tor->info.pieces[piece].dnd ) cp->doneHave += blockSize; } + + assert( cp->completeHave <= tor->info.totalSize ); + assert( cp->doneHave <= tor->info.totalSize ); + assert( cp->doneHave <= cp->completeHave ); } const tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp ) @@ -262,6 +272,8 @@ tr_cpPercentComplete ( const tr_completion * cp ) uint64_t tr_cpLeftUntilComplete ( const tr_completion * cp ) { + assert( cp->tor->info.totalSize >= cp->completeHave ); + return cp->tor->info.totalSize - cp->completeHave; } @@ -284,7 +296,9 @@ tr_cpLeftUntilDone ( const tr_completion * cp ) cp_status_t tr_cpGetStatus ( const tr_completion * cp ) { - if( cp->completeHave >= cp->tor->info.totalSize ) + assert( cp->tor->info.totalSize >= cp->completeHave ); + + if( cp->completeHave == cp->tor->info.totalSize ) return TR_CP_COMPLETE; tr_cpEnsureDoneValid( cp ); diff --git a/libtransmission/utils.c b/libtransmission/utils.c index efca57e28..984a75798 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -647,7 +647,7 @@ tr_bitfieldClear( tr_bitfield * bitfield ) int tr_bitfieldIsEmpty( const tr_bitfield * bitfield ) { - unsigned int i; + size_t i; for( i=0; ilen; ++i ) if( bitfield->bits[i] ) @@ -677,7 +677,7 @@ tr_bitfieldAddRange( tr_bitfield * bitfield, size_t end ) { /* TODO: there are faster ways to do this */ - unsigned int i; + size_t i; for( i=begin; i