1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-01 11:35:37 +00:00

AK: Fix one-off error in BitmapView::find_first and find_one_anywhere

The mentioned functions used m_size / 8 instead of size_in_bytes()
(division with ceiling rounding mode), which resulted in an off-by-one
error such that the functions didn't search in the last not-fully-8-bits
byte.

Using size_in_bytes() instead of m_size / 8 fixes this.
This commit is contained in:
Martin Janiczek 2023-10-11 13:52:38 +02:00 committed by Tim Schumacher
parent 2e615b5316
commit efa5fb5c3a
2 changed files with 21 additions and 3 deletions

View File

@ -94,7 +94,7 @@ public:
Optional<size_t> find_one_anywhere(size_t hint = 0) const
{
VERIFY(hint < m_size);
u8 const* end = &m_data[m_size / 8];
u8 const* end = &m_data[size_in_bytes()];
for (;;) {
// We will use hint as what it is: a hint. Because we try to
@ -128,7 +128,7 @@ public:
// We didn't find anything, check the remaining few bytes (if any)
u8 byte = VALUE ? 0x00 : 0xff;
size_t i = reinterpret_cast<u8 const*>(ptr_large) - &m_data[0];
size_t byte_count = m_size / 8;
size_t byte_count = size_in_bytes();
VERIFY(i <= byte_count);
while (i < byte_count && m_data[i] == byte)
i++;
@ -171,7 +171,7 @@ public:
template<bool VALUE>
Optional<size_t> find_first() const
{
size_t byte_count = m_size / 8;
size_t byte_count = size_in_bytes();
size_t i = 0;
u8 byte = VALUE ? 0x00 : 0xff;

View File

@ -276,3 +276,21 @@ TEST_CASE(byte_aligned_access)
EXPECT_EQ(bitmap.count_in_range(4, 4, true), 1u);
}
}
TEST_CASE(find_one_anywhere_edge_case)
{
{
auto bitmap = MUST(Bitmap::create(1, false));
bitmap.set(0, false);
EXPECT_EQ(bitmap.find_one_anywhere_unset(0).value(), 0UL);
}
}
TEST_CASE(find_first_edge_case)
{
{
auto bitmap = MUST(Bitmap::create(1, false));
bitmap.set(0, false);
EXPECT_EQ(bitmap.find_first_unset().value(), 0UL);
}
}