Commit 24247e28 authored by Pau Espin Pedrol's avatar Pau Espin Pedrol Committed by Mouse

aper: Rework aper_get_length to gain lb & ub information

This should help aper_put_length() to take proper decisions on the way
to encode the length, since the range alone is not enough.
A contraint of lb=1 ub=65536 would yield a range=65536, but according to
ITU-T X.691 11.9 it shouldn't be encoded using nsnnwn since that only
applies in case ub<65536.
As a result, it would end up encoding/decoding it using 2 bytes while it
should use only 1.

Related: https://github.com/mouse07410/asn1c/issues/94
parent 9f198236
...@@ -132,7 +132,7 @@ ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -132,7 +132,7 @@ ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
int ret; int ret;
/* Get the PER length */ /* Get the PER length */
raw_len = aper_get_length(pd, -1, 0, &repeat); raw_len = aper_get_length(pd, -1, -1, 0, &repeat);
if(raw_len < 0) RETURN(RC_WMORE); if(raw_len < 0) RETURN(RC_WMORE);
if(raw_len == 0 && st->buf) break; if(raw_len == 0 && st->buf) break;
......
...@@ -129,7 +129,7 @@ INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -129,7 +129,7 @@ INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
int ret; int ret;
/* Get the PER length */ /* Get the PER length */
len = aper_get_length(pd, -1, -1, &repeat); len = aper_get_length(pd, -1, -1, -1, &repeat);
if(len < 0) ASN__DECODE_STARVED; if(len < 0) ASN__DECODE_STARVED;
p = REALLOC(st->buf, st->size + len + 1); p = REALLOC(st->buf, st->size + len + 1);
......
...@@ -173,9 +173,10 @@ OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -173,9 +173,10 @@ OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
/* Get the PER length */ /* Get the PER length */
if (csiz->upper_bound - csiz->lower_bound == 0) if (csiz->upper_bound - csiz->lower_bound == 0)
/* Indefinite length case */ /* Indefinite length case */
raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat); raw_len = aper_get_length(pd, -1, -1, csiz->effective_bits, &repeat);
else else
raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat); raw_len = aper_get_length(pd, csiz->lower_bound, csiz->upper_bound,
csiz->effective_bits, &repeat);
if(raw_len < 0) RETURN(RC_WMORE); if(raw_len < 0) RETURN(RC_WMORE);
raw_len += csiz->lower_bound; raw_len += csiz->lower_bound;
......
...@@ -146,7 +146,7 @@ OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) { ...@@ -146,7 +146,7 @@ OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) {
rv.code = RC_FAIL; rv.code = RC_FAIL;
do { do {
bytes = aper_get_length(pd, -1, -1, &repeat); bytes = aper_get_length(pd, -1, -1, -1, &repeat);
if (bytes > 10 * ASN_DUMMY_BYTES) if (bytes > 10 * ASN_DUMMY_BYTES)
{ {
return rv; return rv;
...@@ -171,4 +171,3 @@ OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) { ...@@ -171,4 +171,3 @@ OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) {
return rv; return rv;
#undef ASN_DUMMY_BYTES #undef ASN_DUMMY_BYTES
} }
...@@ -25,7 +25,7 @@ aper_open_type_get_simple(const asn_codec_ctx_t *ctx, ...@@ -25,7 +25,7 @@ aper_open_type_get_simple(const asn_codec_ctx_t *ctx,
ASN_DEBUG("Getting open type %s...", td->name); ASN_DEBUG("Getting open type %s...", td->name);
do { do {
chunk_bytes = aper_get_length(pd, -1, -1, &repeat); chunk_bytes = aper_get_length(pd, -1, -1, -1, &repeat);
if(chunk_bytes < 0) { if(chunk_bytes < 0) {
FREEMEM(buf); FREEMEM(buf);
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
......
...@@ -17,13 +17,17 @@ aper_get_align(asn_per_data_t *pd) { ...@@ -17,13 +17,17 @@ aper_get_align(asn_per_data_t *pd) {
} }
ssize_t ssize_t
aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) { aper_get_length(asn_per_data_t *pd, ssize_t lb, ssize_t ub,
int ebits, int *repeat) {
int constrained = (lb >= 0) && (ub >= 0);
ssize_t value; ssize_t value;
*repeat = 0; *repeat = 0;
if (range <= 65536 && range >= 0) if (constrained && ub < 65536) {
int range = ub - lb + 1;
return aper_get_nsnnwn(pd, range); return aper_get_nsnnwn(pd, range);
}
if (aper_get_align(pd) < 0) if (aper_get_align(pd) < 0)
return -1; return -1;
...@@ -59,7 +63,7 @@ aper_get_nslength(asn_per_data_t *pd) { ...@@ -59,7 +63,7 @@ aper_get_nslength(asn_per_data_t *pd) {
return length; return length;
} else { } else {
int repeat; int repeat;
length = aper_get_length(pd, -1, -1, &repeat); length = aper_get_length(pd, -1, -1, -1, &repeat);
if(length >= 0 && !repeat) return length; if(length >= 0 && !repeat) return length;
return -1; /* Error, or do not support >16K extensions */ return -1; /* Error, or do not support >16K extensions */
} }
......
...@@ -16,7 +16,7 @@ extern "C" { ...@@ -16,7 +16,7 @@ extern "C" {
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant" * X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
* Get the length "n" from the Aligned PER stream. * Get the length "n" from the Aligned PER stream.
*/ */
ssize_t aper_get_length(asn_per_data_t *pd, int range, ssize_t aper_get_length(asn_per_data_t *pd, ssize_t lb, ssize_t ub,
int effective_bound_bits, int *repeat); int effective_bound_bits, int *repeat);
/* /*
......
...@@ -141,8 +141,11 @@ SET_OF_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -141,8 +141,11 @@ SET_OF_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
do { do {
int i; int i;
if(nelems < 0) { if(nelems < 0) {
nelems = aper_get_length(pd, ct ? ct->upper_bound - ct->lower_bound + 1 : -1, if (ct)
ct ? ct->effective_bits : -1, &repeat); nelems = aper_get_length(pd, ct->lower_bound, ct->upper_bound,
ct->effective_bits, &repeat);
else
nelems = aper_get_length(pd, -1, -1, -1, &repeat);
ASN_DEBUG("Got to decode %d elements (eff %d)", ASN_DEBUG("Got to decode %d elements (eff %d)",
(int)nelems, (int)(ct ? ct->effective_bits : -1)); (int)nelems, (int)(ct ? ct->effective_bits : -1));
if(nelems < 0) ASN__DECODE_STARVED; if(nelems < 0) ASN__DECODE_STARVED;
......
...@@ -36,7 +36,7 @@ static size_t get(asn_per_outp_t *po, ssize_t lb, ssize_t ub) { ...@@ -36,7 +36,7 @@ static size_t get(asn_per_outp_t *po, ssize_t lb, ssize_t ub) {
size_t length = 0; size_t length = 0;
int repeat = 0; int repeat = 0;
do { do {
ssize_t n = aper_get_length(&data, ub - lb + 1, -1, &repeat); ssize_t n = aper_get_length(&data, lb, ub, -1, &repeat);
fprintf(stderr, " get = %zu +%zd\n", length, n); fprintf(stderr, " get = %zu +%zd\n", length, n);
assert(n >= 0); assert(n >= 0);
length += n; length += n;
......
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