aper fix for decoding constrained integer with lower boundary

When decoding a constrained integer with a lower boundary, we need
to make sure the lower bound is added after decoding the raw offset
inside the range.

Before this change, RANAP_CauseMisc_unspecified_failure (115) would be
encoded as 2 (115 - 113 = 2), but would be decoded as 2, rather than
113+2 = 115.

Code for this was taken from
openairinterface5g/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 which
unfortunately doesn't carry much of a revision history :/
This commit is contained in:
Harald Welte 2016-05-01 01:02:17 +02:00
parent c867ddeb30
commit 20d668cbd3
1 changed files with 21 additions and 12 deletions

View File

@ -716,34 +716,43 @@ INTEGER_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN_DEBUG("Integer with range %d bits", ct->range_bits);
if(ct->range_bits >= 0) {
if (ct->range_bits > 16) {
int max_range_bytes = (ct->range_bits >> 3) + 1;
int length, i;
int max_range_bytes = (ct->range_bits >> 3) +
(((ct->range_bits % 8) > 0) ? 1 : 0);
int length = 0, i;
int64_t value = 0;
for (i = 0; i < max_range_bytes; i++) {
int upper = 1 << (i + 1);
if (upper > max_range_bytes)
for (i = 1; ; i++) {
int upper = 1 << i;
if (upper >= max_range_bytes)
break;
}
if ((length = per_get_few_bits(pd, i + 1)) < 0)
_ASN_DECODE_STARVED;
ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits,
max_range_bytes, i);
if ((length = per_get_few_bits(pd, i)) < 0)
_ASN_DECODE_FAILED;
/* X.691 #12.2.6 length determinant + lb (1) */
length += 1;
ASN_DEBUG("Got length %d", length);
if (aper_get_align(pd) != 0)
_ASN_DECODE_STARVED;
ASN_DEBUG("Got length %d", length + 1);
for (i = 0; i < length + 1; i++) {
while (length--) {
int buf = per_get_few_bits(pd, 8);
if (buf < 0)
_ASN_DECODE_STARVED;
value += (((int64_t)buf) << (8 * i));
value += (((int64_t)buf) << (8 * length));
}
value += ct->lower_bound;
if((specs && specs->field_unsigned)
? asn_uint642INTEGER(st, value)
: asn_int642INTEGER(st, value))
_ASN_DECODE_FAILED;
ASN_DEBUG("Got value %lld + low %lld",
value, ct->lower_bound);
value += ct->lower_bound;
} else {
long value = 0;
if (ct->range_bits < 8) {
@ -761,13 +770,13 @@ INTEGER_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
value = per_get_few_bits(pd, 16);
if(value < 0) _ASN_DECODE_STARVED;
}
value += ct->lower_bound;
if((specs && specs->field_unsigned)
? asn_ulong2INTEGER(st, value)
: asn_long2INTEGER(st, value))
_ASN_DECODE_FAILED;
ASN_DEBUG("Got value %ld + low %lld",
value, ct->lower_bound);
value += ct->lower_bound;
}
return rval;
} else {