(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.

This commit is contained in:
Jordan Lee 2011-09-26 22:50:42 +00:00
parent bf6c2a0df7
commit 18b90f60bc
4 changed files with 20 additions and 6 deletions

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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'";