diff --git a/librz/util/bitvector.c b/librz/util/bitvector.c index 9e2f0f58ec..7685b31f52 100644 --- a/librz/util/bitvector.c +++ b/librz/util/bitvector.c @@ -2258,8 +2258,13 @@ RZ_API bool rz_bv_cast_inplace(RZ_INOUT RZ_NONNULL RzBitVector *bv, ut32 to_size return true; } if (bv->len <= 64 && to_size <= 64) { - rz_bv_set_range(bv, to_size, bv->len - 1, fill_bit); + ut32 old_size = bv->len; bv->len = to_size; + if (to_size > old_size) { + rz_bv_set_range(bv, old_size, to_size - 1, fill_bit); + } else { + bv->bits.small_u &= (1ULL << to_size) - 1; + } return true; } if (NELEM(to_size, BV_ELEM_SIZE) > bv->_elem_len) { diff --git a/test/unit/test_bitvector.c b/test/unit/test_bitvector.c index 877c0d19db..e49ac426fd 100644 --- a/test/unit/test_bitvector.c +++ b/test/unit/test_bitvector.c @@ -1526,6 +1526,26 @@ bool test_rz_bv_cast_inplace(void) { RzBitVector *small = rz_bv_new_from_ut64(20, 0x01234); RzBitVector *large = rz_bv_new_from_bytes_be(array_128, 0, 128); + mu_assert_true(rz_bv_cast_inplace(small, 5, true), "Cast failed"); + mu_assert_eq(rz_bv_to_ut64(small), 0x14, "Mismatch after cast"); + mu_assert_eq(small->len, 5, "New size is off"); + mu_assert_null(small->bits.large_a, "Should have been NULL"); + mu_assert_eq(small->_elem_len, 0, "Should be 0"); + + mu_assert_true(rz_bv_cast_inplace(small, 64, true), "Cast failed"); + mu_assert_eq(rz_bv_to_ut64(small), 0xfffffffffffffff4ULL, "Mismatch after cast"); + mu_assert_eq(small->len, 64, "New size is off"); + mu_assert_null(small->bits.large_a, "Should have been NULL"); + mu_assert_eq(small->_elem_len, 0, "Should be 0"); + + mu_assert_true(rz_bv_cast_inplace(small, 65, true), "Cast failed"); + mu_assert_streq_free(rz_bv_as_hex_string(small, false), "0x1fffffffffffffff4", "small to large cast failed"); + mu_assert_eq(small->len, 65, "New size is off"); + mu_assert_notnull(small->bits.large_a, "Buffer not set"); + mu_assert_eq(small->_elem_len, 9, "Buffer length wrong"); + + rz_bv_free(small); + small = rz_bv_new_from_ut64(20, 0x01234); mu_assert_true(rz_bv_cast_inplace(small, 5, false), "Cast failed"); mu_assert_eq(rz_bv_to_ut64(small), 0x14, "Mismatch after cast"); mu_assert_eq(small->len, 5, "New size is off");