mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
features: have clear_feature_bit correctly resize bitfield
There's a spec rule about only ever sending a correctly sized feature-bits, so as a precaution we have `clear_feature_bit` correctly resize when a bit is cleared.
This commit is contained in:
@@ -121,6 +121,21 @@ static const struct dependency feature_deps[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void trim_features(u8 **features)
|
||||||
|
{
|
||||||
|
size_t trim, len = tal_bytelen(*features);
|
||||||
|
|
||||||
|
/* Don't try to tal_resize a NULL array */
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Big-endian bitfields are weird, but it means we trim
|
||||||
|
* from the front: */
|
||||||
|
for (trim = 0; trim < len && (*features)[trim] == 0; trim++);
|
||||||
|
memmove(*features, *features + trim, len - trim);
|
||||||
|
tal_resize(features, len - trim);
|
||||||
|
}
|
||||||
|
|
||||||
static void clear_feature_bit(u8 *features, u32 bit)
|
static void clear_feature_bit(u8 *features, u32 bit)
|
||||||
{
|
{
|
||||||
size_t bytenum = bit / 8, bitnum = bit % 8, len = tal_count(features);
|
size_t bytenum = bit / 8, bitnum = bit % 8, len = tal_count(features);
|
||||||
@@ -234,6 +249,7 @@ u8 *get_agreed_channelfeatures(const tal_t *ctx,
|
|||||||
if (!feature_offered(their_features, i)) {
|
if (!feature_offered(their_features, i)) {
|
||||||
clear_feature_bit(f, COMPULSORY_FEATURE(i));
|
clear_feature_bit(f, COMPULSORY_FEATURE(i));
|
||||||
clear_feature_bit(f, OPTIONAL_FEATURE(i));
|
clear_feature_bit(f, OPTIONAL_FEATURE(i));
|
||||||
|
trim_features(&f);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
max_len = (i / 8) + 1;
|
max_len = (i / 8) + 1;
|
||||||
|
|||||||
@@ -179,6 +179,39 @@ static void test_feature_set_or(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_feature_trim(void)
|
||||||
|
{
|
||||||
|
struct feature_set *f;
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(f->bits); i++) {
|
||||||
|
f = talz(tmpctx, struct feature_set);
|
||||||
|
|
||||||
|
f->bits[i] = tal_arr(f, u8, 0);
|
||||||
|
set_feature_bit(&f->bits[i], 255);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 32);
|
||||||
|
clear_feature_bit(f->bits[i], 255);
|
||||||
|
trim_features(&f->bits[i]);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 0);
|
||||||
|
|
||||||
|
set_feature_bit(&f->bits[i], 7);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 1);
|
||||||
|
set_feature_bit(&f->bits[i], 255);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 32);
|
||||||
|
clear_feature_bit(f->bits[i], 255);
|
||||||
|
trim_features(&f->bits[i]);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 1);
|
||||||
|
clear_feature_bit(f->bits[i], 7);
|
||||||
|
trim_features(&f->bits[i]);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 0);
|
||||||
|
|
||||||
|
set_feature_bit(&f->bits[i], 8);
|
||||||
|
set_feature_bit(&f->bits[i], 10);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 2);
|
||||||
|
clear_feature_bit(f->bits[i], 10);
|
||||||
|
trim_features(&f->bits[i]);
|
||||||
|
assert(tal_bytelen(f->bits[i]) == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
u8 *bits;
|
u8 *bits;
|
||||||
@@ -265,6 +298,7 @@ int main(void)
|
|||||||
|
|
||||||
test_featurebits_or();
|
test_featurebits_or();
|
||||||
test_feature_set_or();
|
test_feature_set_or();
|
||||||
|
test_feature_trim();
|
||||||
|
|
||||||
wally_cleanup(0);
|
wally_cleanup(0);
|
||||||
tal_free(tmpctx);
|
tal_free(tmpctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user