fix bitfield m_buf null pointer (#1526)

fix operations on empty bitfield
This commit is contained in:
Falcosc 2017-01-13 23:08:54 +01:00 committed by Arvid Norberg
parent a31ba7972d
commit 9199756a27
4 changed files with 56 additions and 3 deletions

View File

@ -1,3 +1,4 @@
* fix crash caused by empty bitfield
* removed disk-access-log build configuration
* removed mmap_cache feature
* strengthened type safety in handling of piece and file indices

View File

@ -105,6 +105,8 @@ namespace libtorrent
bool none_set() const
{
if(size() == 0) return true;
const int words = num_words();
std::uint32_t const* b = buf();
for (int i = 0; i < words; ++i)
@ -126,7 +128,7 @@ namespace libtorrent
}
// returns true if the bitfield has zero size.
bool empty() const { return m_buf == nullptr ? true : m_buf[0] == 0; }
bool empty() const { return size() == 0; }
// returns a pointer to the internal buffer of the bitfield.
char const* data() const { return m_buf ? reinterpret_cast<char const*>(&m_buf[1]) : nullptr; }
@ -226,13 +228,13 @@ namespace libtorrent
// set all bits in the bitfield to 1 (set_all) or 0 (clear_all).
void set_all()
{
if (m_buf == nullptr) return;
if (size() == 0) return;
std::memset(buf(), 0xff, size_t(num_words() * 4));
clear_trailing_bits();
}
void clear_all()
{
if (m_buf == nullptr) return;
if (size() == 0) return;
std::memset(buf(), 0x00, size_t(num_words() * 4));
}

View File

@ -41,6 +41,8 @@ namespace libtorrent
{
bool bitfield::all_set() const
{
if(size() == 0) return false;
int const words = size() / 32;
for (int i = 1; i < words + 1; ++i)
{

View File

@ -355,3 +355,51 @@ TORRENT_TEST(find_last_clear_misc)
test4.clear_bit(89);
TEST_EQUAL(test4.find_last_clear(), 91);
}
TORRENT_TEST(not_initialized)
{
// check a not initialized empty bitfield
bitfield test1(0);
TEST_EQUAL(test1.none_set(), true);
TEST_EQUAL(test1.all_set(), false);
TEST_EQUAL(test1.size(), 0);
TEST_EQUAL(test1.num_words(), 0);
TEST_EQUAL(test1.empty(), true);
TEST_CHECK(test1.data() == nullptr);
TEST_EQUAL(test1.count(), 0);
TEST_EQUAL(test1.find_first_set(), -1);
TEST_EQUAL(test1.find_last_clear(), -1);
test1.clear_all();
TEST_EQUAL(test1.size(), 0);
test1.clear();
TEST_EQUAL(test1.size(), 0);
test1.set_all();
TEST_EQUAL(test1.size(), 0);
// don't test methods which aren't defined for empty sets:
// get_bit, clear_bit, set_bit
}
TORRENT_TEST(not_initialized_assign)
{
// check a not initialized empty bitfield
bitfield test1(0);
std::uint8_t b1[] = { 0xff };
test1.assign((char*)b1, 8);
TEST_EQUAL(test1.count(), 8);
}
TORRENT_TEST(not_initialized_resize)
{
// check a not initialized empty bitfield
bitfield test1(0);
test1.resize(8, true);
TEST_EQUAL(test1.count(), 8);
bitfield test2(0);
test2.resize(8);
TEST_EQUAL(test2.size(), 8);
}