Interface name wildcards are received as ranges from prefix with zero
padding to prefix with ones padding. E.g. with "abcd*" (in hex):
61626364000000000000000000000000 -
61626364ffffffffffffffffffffffff
The faulty code tries to export the prefix from the lower boundary (r1)
into a buffer, append "*" and allocate a constant expression from the
resulting string. This does not work on Big Endian though:
mpz_export_data() seems to zero-pad data upon export and not necessarily
respect the passed length value. Moreover, this padding appears in the
first bytes of the buffer. The amount of padding seems illogical, too:
While a 6B prefix causes 2B padding and 8B prefix no padding, 10B prefix
causes 4B padding and 12B prefix even 8B padding.
Work around the odd behaviour by exporting the full data into a larger
buffer.
A similar issue is caused by increasing the constant expression's length
to match the upper boundary data length: Data export when printing puts
the padding upfront, so the resulting string starts with NUL-chars.
Since this length adjustment seems not to have any effect in practice,
just drop it.
Fixes: 88b2345a215ef ("segtree: add pretty-print support for wildcard strings in concatenated sets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
if (prefix_len >= 0 &&
(prefix_len % BITS_PER_BYTE) == 0 &&
string_type) {
+ unsigned int r1len = div_round_up(r1->len, BITS_PER_BYTE);
unsigned int str_len = prefix_len / BITS_PER_BYTE;
- char data[str_len + 2];
+ char data[r1len + 1] = {};
- mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, str_len);
+ mpz_export_data(data, r1->value, BYTEORDER_HOST_ENDIAN, r1len);
data[str_len] = '*';
tmp = constant_expr_alloc(&r1->location, r1->dtype,
BYTEORDER_HOST_ENDIAN,
(str_len + 1) * BITS_PER_BYTE, data);
- tmp->len = r2->len;
list_replace(&r2->list, &tmp->list);
r2_next = tmp->list.next;
expr_free(r2);