summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-01-03 14:37:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-01-03 14:37:09 (GMT)
commit7b739f256cb88cb627954d4a1ff04bdb4fc49515 (patch)
treee0e2ecd90f8004d44f320c78a69edbe37d6169a6 /src/common
parent755acfaa09e08a355b29081b75f9d547d264ce53 (diff)
Fix some mistakes in bitfield operations.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/bits.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/common/bits.c b/src/common/bits.c
index 590c318..a037078 100644
--- a/src/common/bits.c
+++ b/src/common/bits.c
@@ -533,34 +533,35 @@ void or_bit_field_at(bitfield_t *dest, const bitfield_t *src, size_t first)
size_t start; /* Mot de départ dans le champ */
size_t offset; /* Décalage des mots à basculer*/
size_t remaining; /* Taille du dernier tronçon */
- unsigned long finalcut; /* Limitation du mot final */
+ size_t last_iter; /* Dernière itération à mener */
size_t i; /* Boucle de parcours */
unsigned long word; /* Mot reconstituté à tester */
- assert(dest->length <= (first + src->length));
+ assert((first + src->length) <= dest->length);
start = first / (sizeof(unsigned long) * 8);
offset = first % (sizeof(unsigned long) * 8);
remaining = (first + src->length) % (sizeof(unsigned long) * 8);
- if (remaining == 0)
- finalcut = ~0ul;
+ if ((first + src->length) % (sizeof(unsigned long) * 8) > 0)
+ last_iter = src->requested;
else
- finalcut = (1ul << remaining) - 1;
+ last_iter = src->requested - 1;
- for (i = 0; i < (src->requested + 1); i++)
+
+ for (i = 0; i <= last_iter; i++)
{
if (i < src->requested)
word = src->bits[i] << offset;
else
word = 0;
- if (i > 0)
+ if (i > 0 && offset > 0)
word |= src->bits[i - 1] >> (sizeof(unsigned long) * 8 - offset);
- if (i == src->requested)
- word &= finalcut;
+ if (i == last_iter && remaining > 0)
+ word &= (1ul << remaining) - 1;
dest->bits[start + i] |= word;
@@ -753,6 +754,8 @@ static bool test_state_within_bit_field(const bitfield_t *field, size_t first, c
test = word ^ bitmask;
+ test &= bitmask;
+
if ((i + 1) == mask->requested)
{
bitmask &= finalcut;