Commit 99b60836 authored by Pau Espin Pedrol's avatar Pau Espin Pedrol Committed by Mouse

APER encoding: Fix aper_put_length() with range=65536

Fixes bug introduced in 0101252e [1].
This is actually mainly a revert of that commit.

That commit introduced a bug in which a small value (under 1 octet) with
range spanning full 2 octets (65536) was encoded incorrectly as 1 octet.

Section 4 of X.691 defines 64K as 65536, and Section 11.5.7 explicitly states
"""
c) "range" is greater than 256 and less than or equal to 64K (the two-octet case).
"""

This was noted while encoding SBc-AP messaged generated with asn1c,
where a SEQUENCE OF uses aper_put_length() to set the number of items.

[1] https://github.com/mouse07410/asn1c/pull/91
parent 3f8f6c8f
...@@ -22,7 +22,7 @@ aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) { ...@@ -22,7 +22,7 @@ aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) {
*repeat = 0; *repeat = 0;
if (range < 65536 && range >= 0) if (range <= 65536 && range >= 0)
return aper_get_nsnnwn(pd, range); return aper_get_nsnnwn(pd, range);
if (aper_get_align(pd) < 0) if (aper_get_align(pd) < 0)
...@@ -163,7 +163,7 @@ aper_put_length(asn_per_outp_t *po, int range, size_t length, int *need_eom) { ...@@ -163,7 +163,7 @@ aper_put_length(asn_per_outp_t *po, int range, size_t length, int *need_eom) {
ASN_DEBUG("APER put length %zu with range %d", length, range); ASN_DEBUG("APER put length %zu with range %d", length, range);
/* 10.9 X.691 Note 2 */ /* 10.9 X.691 Note 2 */
if (range < 65536 && range >= 0) if (range <= 65536 && range >= 0)
return aper_put_nsnnwn(po, range, length) ? -1 : (ssize_t)length; return aper_put_nsnnwn(po, range, length) ? -1 : (ssize_t)length;
if (aper_put_align(po) < 0) if (aper_put_align(po) < 0)
......
...@@ -76,8 +76,6 @@ check_round_trips_range65536() { ...@@ -76,8 +76,6 @@ check_round_trips_range65536() {
check_round_trip(65536, 256); check_round_trip(65536, 256);
check_round_trip(65536, 65534); check_round_trip(65536, 65534);
check_round_trip(65536, 65535); check_round_trip(65536, 65535);
check_round_trip(65536, 65536);
/* BUG: ^ this should fail but there's another unrelated bug, will be fixed in follow-up commit */
} }
/* /*
...@@ -103,6 +101,14 @@ check_encode_number_greater_than_range() { ...@@ -103,6 +101,14 @@ check_encode_number_greater_than_range() {
length = range; length = range;
may_write = aper_put_length(&po, range, length, NULL); may_write = aper_put_length(&po, range, length, NULL);
assert(may_write < 0); assert(may_write < 0);
/* Again value = range, with edge case 65536: */
memset(&po, 0, sizeof(po));
po.buffer = po.tmpspace;
po.nbits = 8 * sizeof(po.tmpspace);
length = range = 65536;
may_write = aper_put_length(&po, range, length, NULL);
assert(may_write < 0);
} }
/* /*
...@@ -123,7 +129,7 @@ check_range65536_encoded_as_2octet() { ...@@ -123,7 +129,7 @@ check_range65536_encoded_as_2octet() {
unsigned int bytes_needed = (po.buffer - po.tmpspace) + po.nboff/8; unsigned int bytes_needed = (po.buffer - po.tmpspace) + po.nboff/8;
fprintf(stderr, "\naper_put_length(range=%d, len=%zu) => bytes_needed=%u\n", fprintf(stderr, "\naper_put_length(range=%d, len=%zu) => bytes_needed=%u\n",
range, length, bytes_needed); range, length, bytes_needed);
assert(bytes_needed == 1); /* BUG: should be 2 octets! */ assert(bytes_needed == 2);
} }
int main() { int main() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment