From: Jordan Lee Date: Wed, 28 Sep 2011 16:07:35 +0000 (+0000) Subject: #4506 'crash from memory corruption somewhere called from tr_handshakeDone()' --... X-Git-Tag: 2.40b3~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0337806b039f1e747a41c6167a760540f82cde1b;p=transmission #4506 'crash from memory corruption somewhere called from tr_handshakeDone()' -- possible fix. --- diff --git a/libtransmission/bitfield.c b/libtransmission/bitfield.c index d09257986..db1682b9b 100644 --- a/libtransmission/bitfield.c +++ b/libtransmission/bitfield.c @@ -170,25 +170,27 @@ tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count ) assert( b->bit_count > 0 ); - if( b->alloc_count ) + if( b->alloc_count ) { + assert( b->alloc_count <= n ); memcpy( bits, b->bits, b->alloc_count ); - else if( tr_bitfieldHasAll( b ) ) + } else if( tr_bitfieldHasAll( b ) ) { set_all_true( bits, b->bit_count ); + } *byte_count = n; return bits; } static void -tr_bitfieldEnsureBitsAlloced( tr_bitfield * b, size_t nth ) +tr_bitfieldEnsureBitsAlloced( tr_bitfield * b, size_t n ) { size_t bytes_needed; const bool has_all = tr_bitfieldHasAll( b ); if( has_all ) - bytes_needed = get_bytes_needed( MAX( nth, b->true_count ) + 1 ); + bytes_needed = get_bytes_needed( MAX( n, b->true_count ) ); else - bytes_needed = get_bytes_needed( nth + 1 ); + bytes_needed = get_bytes_needed( n ); if( b->alloc_count < bytes_needed ) { @@ -201,6 +203,13 @@ tr_bitfieldEnsureBitsAlloced( tr_bitfield * b, size_t nth ) } } +static void +tr_bitfieldEnsureNthBitAlloced( tr_bitfield * b, size_t nth ) +{ + /* count is zero-based, so we need to allocate nth+1 bits before setting the nth */ + tr_bitfieldEnsureBitsAlloced( b, nth + 1 ); +} + static void tr_bitfieldFreeArray( tr_bitfield * b ) { @@ -332,7 +341,7 @@ tr_bitfieldAdd( tr_bitfield * b, size_t nth ) { if( !tr_bitfieldHas( b, nth ) ) { - tr_bitfieldEnsureBitsAlloced( b, nth ); + tr_bitfieldEnsureNthBitAlloced( b, nth ); b->bits[nth >> 3u] |= ( 0x80 >> ( nth & 7u ) ); tr_bitfieldIncTrueCount( b, 1 ); } @@ -358,7 +367,7 @@ tr_bitfieldAddRange( tr_bitfield * b, size_t begin, size_t end ) eb = end >> 3; em = 0xff << ( 7 - ( end & 7 ) ); - tr_bitfieldEnsureBitsAlloced( b, end ); + tr_bitfieldEnsureNthBitAlloced( b, end ); if( sb == eb ) { b->bits[sb] |= ( sm & em ); @@ -381,7 +390,7 @@ tr_bitfieldRem( tr_bitfield * b, size_t nth ) if( !tr_bitfieldHas( b, nth ) ) { - tr_bitfieldEnsureBitsAlloced( b, nth ); + tr_bitfieldEnsureNthBitAlloced( b, nth ); b->bits[nth >> 3u] &= ( 0xff7f >> ( nth & 7u ) ); tr_bitfieldIncTrueCount( b, -1 ); } @@ -408,7 +417,7 @@ tr_bitfieldRemRange( tr_bitfield * b, size_t begin, size_t end ) eb = end >> 3; em = ~( 0xff << ( 7 - ( end & 7 ) ) ); - tr_bitfieldEnsureBitsAlloced( b, end ); + tr_bitfieldEnsureNthBitAlloced( b, end ); if( sb == eb ) { b->bits[sb] &= ( sm | em );