Fix reachable invalid state, for bitvector in-place casts from large to large. (#5746)

This commit is contained in:
Rot127 2026-01-08 13:47:53 +00:00 committed by GitHub
parent 7ebfa58fe2
commit 4213ddfecc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 6 deletions

View file

@ -2082,16 +2082,26 @@ RZ_API bool rz_bv_cast_inplace(RZ_INOUT RZ_NONNULL RzBitVector *bv, ut32 to_size
// The bit vector needs a larger buffer.
resize_large_a(bv, NELEM(to_size, BV_ELEM_SIZE));
}
size_t old_size = bv->len;
if (bv->len <= 64) {
// This was a small bit vector and now is a large one.
// Copy bits to the buffer.
bv_copy_nbits_small_to_large(bv, 0, bv, 0, bv->len);
if (bv_copy_nbits_small_to_large(bv, 0, bv, 0, old_size) != old_size) {
return false;
}
} else if (to_size <= 64) {
if (bv_copy_nbits_large_to_small(bv, 0, bv, 0, to_size) != to_size) {
return false;
}
} else if (to_size >= old_size) {
if (bv_copy_nbits_large_aligned(bv, 0, bv, 0, old_size) != old_size) {
return false;
}
} else {
bv_copy_nbits_large_to_small(bv, 0, bv, 0, to_size);
if (bv_copy_nbits_large_aligned(bv, 0, bv, 0, to_size) != to_size) {
return false;
}
}
size_t old_len = bv->len;
bv->len = to_size;
rz_bv_set_range(bv, old_len, to_size - 1, fill_bit);
rz_bv_set_range(bv, old_size, to_size - 1, fill_bit);
return true;
}

View file

@ -1370,6 +1370,7 @@ bool test_rz_bv_cast_inplace(void) {
mu_assert_notnull(small->bits.large_a, "Buffer not set");
mu_assert_eq(small->_elem_len, 9, "Buffer length wrong");
// Cast large to small
mu_assert_true(rz_bv_cast_inplace(large, 32, true), "Cast failed");
mu_assert_eq(rz_bv_to_ut64(large), 0x0c0d0e0f, "Mismatch after cast");
mu_assert_streq_free(rz_bv_as_hex_string(large, true), "0x0c0d0e0f", "small to large cast failed");
@ -1377,12 +1378,20 @@ bool test_rz_bv_cast_inplace(void) {
mu_assert_notnull(large->bits.large_a, "Buffer not set");
mu_assert_eq(large->_elem_len, 16, "Buffer length wrong");
// Cast small to large
mu_assert_true(rz_bv_cast_inplace(large, 256, true), "Cast failed");
mu_assert_streq_free(rz_bv_as_hex_string(large, false), "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c0d0e0f", "small to large cast failed");
mu_assert_eq(large->len, 256, "New size is off");
mu_assert_notnull(large->bits.large_a, "Buffer not set");
mu_assert_eq(large->_elem_len, 32, "Buffer length wrong");
// Cast large 256 bit to 128 bit.
mu_assert_true(rz_bv_cast_inplace(large, 128, true), "Cast failed");
mu_assert_streq_free(rz_bv_as_hex_string(large, false), "0xffffffffffffffffffffffff0c0d0e0f", "large to large cast failed");
mu_assert_eq(large->len, 128, "New size is off");
mu_assert_notnull(large->bits.large_a, "Buffer not set");
mu_assert_eq(large->_elem_len, 32, "Buffer length wrong");
rz_bv_free(small);
rz_bv_free(large);
mu_end;