From 18b90f60bcc50bdeb3e80440990966edeb31136d Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Mon, 26 Sep 2011 22:50:42 +0000 Subject: [PATCH] (trunk libt) in tr_bitfieldSetRaw(), add a `bounded' argument for cases where we know how large the final bitfield will be. This can be used ensure that the excess bits at the end of the array are zeroed out and safe for bitfield.c's countArray() function. --- libtransmission/bitfield.c | 18 ++++++++++++++++-- libtransmission/bitfield.h | 2 +- libtransmission/peer-msgs.c | 2 +- libtransmission/resume.c | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libtransmission/bitfield.c b/libtransmission/bitfield.c index b5a5bca10..8c053350d 100644 --- a/libtransmission/bitfield.c +++ b/libtransmission/bitfield.c @@ -281,16 +281,30 @@ tr_bitfieldSetFromBitfield( tr_bitfield * b, const tr_bitfield * src ) else if( tr_bitfieldHasNone( src ) ) tr_bitfieldSetHasNone( b ); else - tr_bitfieldSetRaw( b, src->bits, src->alloc_count ); + tr_bitfieldSetRaw( b, src->bits, src->alloc_count, true ); } void -tr_bitfieldSetRaw( tr_bitfield * b, const void * bits, size_t byte_count ) +tr_bitfieldSetRaw( tr_bitfield * b, const void * bits, size_t byte_count, bool bounded ) { tr_bitfieldFreeArray( b ); b->true_count = 0; + + if( bounded ) + byte_count = MIN( byte_count, get_bytes_needed( b->bit_count ) ); + b->bits = tr_memdup( bits, byte_count ); b->alloc_count = byte_count; + + if( bounded ) { + /* ensure the excess bits are set to '0' */ + const int excess_bit_count = byte_count*8 - b->bit_count; + assert( excess_bit_count >= 0 ); + assert( excess_bit_count <= 7 ); + if( excess_bit_count ) + b->bits[b->alloc_count-1] &= ((0xff) << excess_bit_count); + } + tr_bitfieldRebuildTrueCount( b ); } diff --git a/libtransmission/bitfield.h b/libtransmission/bitfield.h index a78762a2c..616980537 100644 --- a/libtransmission/bitfield.h +++ b/libtransmission/bitfield.h @@ -74,7 +74,7 @@ void tr_bitfieldSetFromFlags( tr_bitfield*, const bool * bytes, size_t n ); void tr_bitfieldSetFromBitfield( tr_bitfield*, const tr_bitfield* ); -void tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count ); +void tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count, bool bounded ); void* tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count ); diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index a8ec91ec2..eedde2cc4 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -1414,7 +1414,7 @@ readBtMessage( tr_peermsgs * msgs, struct evbuffer * inbuf, size_t inlen ) uint8_t * tmp = tr_new( uint8_t, msglen ); dbgmsg( msgs, "got a bitfield" ); tr_peerIoReadBytes( msgs->peer->io, inbuf, tmp, msglen ); - tr_bitfieldSetRaw( &msgs->peer->have, tmp, msglen ); + tr_bitfieldSetRaw( &msgs->peer->have, tmp, msglen, tr_torrentHasMetadata( msgs->torrent ) ); fireClientGotBitfield( msgs, &msgs->peer->have ); updatePeerProgress( msgs ); tr_free( tmp ); diff --git a/libtransmission/resume.c b/libtransmission/resume.c index 9a80d3542..a87951596 100644 --- a/libtransmission/resume.c +++ b/libtransmission/resume.c @@ -591,7 +591,7 @@ loadProgress( tr_benc * dict, tr_torrent * tor ) else if( ( buflen == 4 ) && !memcmp( buf, "none", 4 ) ) tr_bitfieldSetHasNone( &blocks ); else - tr_bitfieldSetRaw( &blocks, buf, buflen ); + tr_bitfieldSetRaw( &blocks, buf, buflen, true ); } else if( tr_bencDictFindStr( prog, KEY_PROGRESS_HAVE, &str ) ) { @@ -602,7 +602,7 @@ loadProgress( tr_benc * dict, tr_torrent * tor ) } else if( tr_bencDictFindRaw( prog, KEY_PROGRESS_BITFIELD, &raw, &rawlen ) ) { - tr_bitfieldSetRaw( &blocks, raw, rawlen ); + tr_bitfieldSetRaw( &blocks, raw, rawlen, true ); } else err = "Couldn't find 'pieces' or 'have' or 'bitfield'"; -- 2.40.0