aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-05-01 01:02:17 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2016-07-06 17:08:57 +0200
commitb9b7c9e54d079c6093a5e77a79aabed409dc9bfb (patch)
tree34796a81f930bcf9e949c11e4f2cafe1c159c4b8
parent2edc63e3aadeef652c2c82a2c0c6a31bb9d2f4fa (diff)
aper fix for decoding constrained integer with lower boundary3G_2016_09aper-prefix-onto-upstream
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 :/
-rw-r--r--skeletons/INTEGER.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 94b298b..af25341 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -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 {