Fix copied bit count in rz_copy_nbits and add unit test (#2547)

This commit is contained in:
Heersin 2022-04-19 00:47:08 +08:00 committed by GitHub
parent 55fc4dfac1
commit 2fdb8ac07e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 2 deletions

View file

@ -182,7 +182,7 @@ RZ_API ut32 rz_bv_copy(RZ_NONNULL const RzBitVector *src, RZ_NONNULL RzBitVector
}
/**
* Copy n bits from start position of source to start position of dest
* Copy n bits from start position of source to start position of dest, return num of copied bits
* \param src RzBitVector, data source
* \param src_start_pos ut32, start position in source bitvector of copy
* \param dst RzBitVector, destination of copy
@ -202,7 +202,7 @@ RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_p
}
// normal case here
for (ut32 i = 0; i < max_nbit; ++i) {
for (ut32 i = 0; i < nbit; ++i) {
bool c = rz_bv_get(src, src_start_pos + i);
rz_bv_set(dst, dst_start_pos + i, c);
}

View file

@ -1030,6 +1030,62 @@ static bool test_rz_bv_set_to_bytes_le(void) {
mu_end;
}
bool test_rz_bv_copy_nbits(void) {
const ut32 size = 20;
const ut32 part_sz = 8;
ut32 actual_copy = 0;
/// 1010 0000 0000 1111 1111
RzBitVector *src = rz_bv_new(size);
for (ut32 i = 0; i < part_sz; ++i) {
rz_bv_set(src, i, true);
}
rz_bv_set(src, src->len - 1, true);
rz_bv_set(src, src->len - 3, true);
/// copy part of bv to a new one with the same size
RzBitVector *small = rz_bv_new(part_sz);
actual_copy = rz_bv_copy_nbits(src, 0, small, 0, part_sz);
mu_assert_eq(actual_copy, part_sz, "copy part_sz to normal");
mu_assert_streq_free(rz_bv_as_string(small), "11111111", "copy nbits small bv");
/// copy part of bv to a new one which has more spaces
RzBitVector *normal = rz_bv_new(size);
actual_copy = rz_bv_copy_nbits(src, 0, normal, 0, part_sz);
mu_assert_eq(actual_copy, part_sz, "copy part_sz bits to normal");
mu_assert_streq_free(rz_bv_as_string(normal), "00000000000011111111", "copy nbits normal length bv");
/// copy part of bv to the medium
RzBitVector *res = rz_bv_new(size);
actual_copy = rz_bv_copy_nbits(src, 0, res, 8, part_sz);
mu_assert_eq(actual_copy, part_sz, "copy part_sz bits to medium");
mu_assert_streq_free(rz_bv_as_string(res), "00001111111100000000", "copy nbits to medium");
/// copy non-zero, copy last 11 bits of `b` to the head of `a`
/// dst : a = 0001 0010 0011 ...
/// src : b = ... .001 1000 0110
/// expect : 0011 0000 1101 ... = 0x30d45678
RzBitVector *a = rz_bv_new_from_ut64(32, 0x12345678);
RzBitVector *b = rz_bv_new_from_ut64(32, 0x1986);
actual_copy = rz_bv_copy_nbits(b, 0, a, a->len - 11, 11);
mu_assert_eq(actual_copy, 11, "copy non-zero 11 bits");
mu_assert_streq_free(rz_bv_as_hex_string(a, false), "0x30d45678", "copy non zero");
/// would fail (do nothing) if copy overflow is possible
RzBitVector *too_small = rz_bv_new(part_sz);
actual_copy = rz_bv_copy_nbits(src, 0, too_small, 0, part_sz + 2);
mu_assert_eq(actual_copy, 0, "copy 0 bits");
mu_assert_true(rz_bv_is_zero_vector(too_small), "copy nothing");
rz_bv_free(src);
rz_bv_free(small);
rz_bv_free(normal);
rz_bv_free(res);
rz_bv_free(too_small);
rz_bv_free(a);
rz_bv_free(b);
mu_end;
}
bool all_tests() {
mu_run_test(test_rz_bv_init32);
mu_run_test(test_rz_bv_init64);
@ -1053,6 +1109,8 @@ bool all_tests() {
mu_run_test(test_rz_bv_len_bytes);
mu_run_test(test_rz_bv_set_all);
mu_run_test(test_rz_bv_set_to_bytes_le);
mu_run_test(test_rz_bv_copy_nbits);
return tests_passed != tests_run;
}