Commit 83668616 authored by Lev Walkin's avatar Lev Walkin

fix after UPER round-trip fuzz

parent 5de82742
...@@ -415,8 +415,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc ...@@ -415,8 +415,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc
asn1p_expr_t *expr = arg->expr; asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v; asn1p_expr_t *v;
int elements; /* Number of elements */ int elements; /* Number of elements */
int ext_start = -2; int first_extension = -1;
int ext_stop = -2;
tag2el_t *tag2el = NULL; tag2el_t *tag2el = NULL;
int tag2el_count = 0; int tag2el_count = 0;
int tags_count; int tags_count;
...@@ -456,9 +455,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc ...@@ -456,9 +455,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc
INDENTED(TQ_FOR(v, &(expr->members), next) { INDENTED(TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) { if(v->expr_type == A1TC_EXTENSIBLE) {
if((++comp_mode) == 1) if((++comp_mode) == 1)
ext_start = elements - 1; first_extension = elements;
else
ext_stop = elements - 1;
continue; continue;
} }
if(v->marker.flags & EM_OMITABLE) if(v->marker.flags & EM_OMITABLE)
...@@ -546,10 +543,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc ...@@ -546,10 +543,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc
} else { } else {
OUT("0, 0, 0,\t/* Optional elements (not needed) */\n"); OUT("0, 0, 0,\t/* Optional elements (not needed) */\n");
} }
OUT("%d,\t/* Start extensions */\n", OUT("%d,\t/* First extension addition */\n", first_extension);
ext_start<0 ? -1 : ext_start);
OUT("%d\t/* Stop extensions */\n",
(ext_stop<ext_start)?elements+1:(ext_stop<0?-1:ext_stop));
INDENT(-1); INDENT(-1);
OUT("};\n"); OUT("};\n");
...@@ -1196,7 +1190,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { ...@@ -1196,7 +1190,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
OUT("asn_MAP_%s_from_canonical_%d,\n", MKID(expr), OUT("asn_MAP_%s_from_canonical_%d,\n", MKID(expr),
expr->_type_unique_index); expr->_type_unique_index);
} else { OUT("0, 0,\n"); } } else { OUT("0, 0,\n"); }
if(C99_MODE) OUT(".ext_start = "); if(C99_MODE) OUT(".first_extension = ");
OUT("%d\t/* Extensions start */\n", compute_extensions_start(expr)); OUT("%d\t/* Extensions start */\n", compute_extensions_start(expr));
); );
OUT("};\n"); OUT("};\n");
...@@ -3397,7 +3391,7 @@ compute_canonical_members_order(arg_t *arg, int el_count) { ...@@ -3397,7 +3391,7 @@ compute_canonical_members_order(arg_t *arg, int el_count) {
int *rmap; int *rmap;
asn1p_expr_t *v; asn1p_expr_t *v;
int eidx = 0; int eidx = 0;
int ext_start = -1; int first_extension = -1;
int nextmax = -1; int nextmax = -1;
int already_sorted = 1; int already_sorted = 1;
...@@ -3409,18 +3403,18 @@ compute_canonical_members_order(arg_t *arg, int el_count) { ...@@ -3409,18 +3403,18 @@ compute_canonical_members_order(arg_t *arg, int el_count) {
cmap[eidx].eidx = eidx; cmap[eidx].eidx = eidx;
cmap[eidx].expr = v; cmap[eidx].expr = v;
eidx++; eidx++;
} else if(ext_start == -1) } else if(first_extension == -1)
ext_start = eidx; first_extension = eidx;
} }
cameo_arg = arg; cameo_arg = arg;
if(ext_start == -1) { if(first_extension == -1) {
/* Sort the whole thing */ /* Sort the whole thing */
qsort(cmap, el_count, sizeof(*cmap), compar_cameo); qsort(cmap, el_count, sizeof(*cmap), compar_cameo);
} else { } else {
/* Sort root and extensions independently */ /* Sort root and extensions independently */
qsort(cmap, ext_start, sizeof(*cmap), compar_cameo); qsort(cmap, first_extension, sizeof(*cmap), compar_cameo);
qsort(cmap + ext_start, el_count - ext_start, qsort(cmap + first_extension, el_count - first_extension,
sizeof(*cmap), compar_cameo); sizeof(*cmap), compar_cameo);
} }
......
/*- /*
* Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved. * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
...@@ -67,9 +67,8 @@ ...@@ -67,9 +67,8 @@
* Check whether we are inside the extensions group. * Check whether we are inside the extensions group.
*/ */
#define IN_EXTENSION_GROUP(specs, memb_idx) \ #define IN_EXTENSION_GROUP(specs, memb_idx) \
( (((signed)(memb_idx)) > (specs)->ext_after) \ ((specs)->first_extension >= 0 \
&&(((signed)(memb_idx)) < (specs)->ext_before)) && (unsigned)(specs)->first_extension <= (memb_idx))
/* /*
* Tags are canonically sorted in the tag2element map. * Tags are canonically sorted in the tag2element map.
...@@ -212,14 +211,9 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -212,14 +211,9 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
if(ctx->left == 0 /* No more stuff is expected */ if(ctx->left == 0 /* No more stuff is expected */
&& ( && (
/* Explicit OPTIONAL specification reaches the end */ /* Explicit OPTIONAL specification reaches the end */
(edx + elements[edx].optional (edx + elements[edx].optional == td->elements_count) ||
== td->elements_count)
||
/* All extensions are optional */ /* All extensions are optional */
(IN_EXTENSION_GROUP(specs, edx) IN_EXTENSION_GROUP(specs, edx))) {
&& specs->ext_before > (signed)td->elements_count)
)
) {
ASN_DEBUG("End of SEQUENCE %s", td->name); ASN_DEBUG("End of SEQUENCE %s", td->name);
/* /*
* Found the legitimate end of the structure. * Found the legitimate end of the structure.
...@@ -244,19 +238,16 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -244,19 +238,16 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) { if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
if(LEFT < 2) { if(LEFT < 2) {
if(SIZE_VIOLATION) if(SIZE_VIOLATION) {
RETURN(RC_FAIL); RETURN(RC_FAIL);
else } else {
RETURN(RC_WMORE); RETURN(RC_WMORE);
}
} else if(((const uint8_t *)ptr)[1] == 0) { } else if(((const uint8_t *)ptr)[1] == 0) {
ASN_DEBUG("edx = %zu, opt = %d, ec=%d", ASN_DEBUG("edx = %zu, opt = %d, ec=%d", edx,
edx, elements[edx].optional, elements[edx].optional, td->elements_count);
td->elements_count); if((edx + elements[edx].optional == td->elements_count)
if((edx + elements[edx].optional || IN_EXTENSION_GROUP(specs, edx)) {
== td->elements_count)
|| (IN_EXTENSION_GROUP(specs, edx)
&& specs->ext_before
> (signed)td->elements_count)) {
/* /*
* Yeah, baby! Found the terminator * Yeah, baby! Found the terminator
* of the indefinite length structure. * of the indefinite length structure.
...@@ -767,17 +758,11 @@ SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -767,17 +758,11 @@ SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
/* Fall through */ /* Fall through */
case XCT_BOTH: case XCT_BOTH:
if(ctx->phase == 0) { if(ctx->phase == 0) {
if(edx >= td->elements_count if(edx >= td->elements_count ||
||
/* Explicit OPTIONAL specs reaches the end */ /* Explicit OPTIONAL specs reaches the end */
(edx + elements[edx].optional (edx + elements[edx].optional == td->elements_count) ||
== td->elements_count)
||
/* All extensions are optional */ /* All extensions are optional */
(IN_EXTENSION_GROUP(specs, edx) IN_EXTENSION_GROUP(specs, edx)) {
&& specs->ext_before
> (signed)td->elements_count)
) {
XER_ADVANCE(ch_size); XER_ADVANCE(ch_size);
ctx->phase = 4; /* Phase out */ ctx->phase = 4; /* Phase out */
RETURN(RC_OK); RETURN(RC_OK);
...@@ -1113,11 +1098,11 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1113,11 +1098,11 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name); ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
/* Handle extensions */ /* Handle extensions */
if(specs->ext_before >= 0) { if(specs->first_extension < 0) {
extpresent = 0;
} else {
extpresent = per_get_few_bits(pd, 1); extpresent = per_get_few_bits(pd, 1);
if(extpresent < 0) ASN__DECODE_STARVED; if(extpresent < 0) ASN__DECODE_STARVED;
} else {
extpresent = 0;
} }
/* Prepare a place and read-in the presence bitmap */ /* Prepare a place and read-in the presence bitmap */
...@@ -1141,13 +1126,15 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1141,13 +1126,15 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
/* /*
* Get the sequence ROOT elements. * Get the sequence ROOT elements.
*/ */
for(edx = 0; edx < td->elements_count; edx++) { for(edx = 0;
edx < (specs->first_extension < 0 ? td->elements_count
: (size_t)specs->first_extension);
edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
void *memb_ptr; /* Pointer to the member */ void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */ void **memb_ptr2; /* Pointer to that pointer */
if(IN_EXTENSION_GROUP(specs, edx)) assert(!IN_EXTENSION_GROUP(specs, edx));
continue;
/* Fetch the pointer to this member */ /* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) { if(elm->flags & ATF_POINTER) {
...@@ -1210,7 +1197,7 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1210,7 +1197,7 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
bmlength = uper_get_nslength(pd); bmlength = uper_get_nslength(pd);
if(bmlength < 0) ASN__DECODE_STARVED; if(bmlength < 0) ASN__DECODE_STARVED;
ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name); ASN_DEBUG("Extensions %zd present in %s", bmlength, td->name);
epres = (uint8_t *)MALLOC((bmlength + 15) >> 3); epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
if(!epres) ASN__DECODE_STARVED; if(!epres) ASN__DECODE_STARVED;
...@@ -1228,17 +1215,12 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1228,17 +1215,12 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
td->name, (long)bmlength, *epres); td->name, (long)bmlength, *epres);
/* Go over extensions and read them in */ /* Go over extensions and read them in */
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
void *memb_ptr; /* Pointer to the member */ void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */ void **memb_ptr2; /* Pointer to that pointer */
int present; int present;
if(!IN_EXTENSION_GROUP(specs, edx)) {
ASN_DEBUG("%zu is not an extension", edx);
continue;
}
/* Fetch the pointer to this member */ /* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) { if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st + elm->memb_offset); memb_ptr2 = (void **)((char *)st + elm->memb_offset);
...@@ -1253,9 +1235,11 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1253,9 +1235,11 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
continue; continue;
} }
ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2); ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
*memb_ptr2);
rv = uper_open_type_get(opt_codec_ctx, elm->type, rv = uper_open_type_get(opt_codec_ctx, elm->type,
elm->encoding_constraints.per_constraints, memb_ptr2, pd); elm->encoding_constraints.per_constraints,
memb_ptr2, pd);
if(rv.code != RC_OK) { if(rv.code != RC_OK) {
FREEMEM(epres); FREEMEM(epres);
return rv; return rv;
...@@ -1274,6 +1258,8 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1274,6 +1258,8 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
FREEMEM(epres); FREEMEM(epres);
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
} }
ASN_DEBUG("Skipped overflow extension");
continue;
} }
break; break;
} }
...@@ -1281,18 +1267,22 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1281,18 +1267,22 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
FREEMEM(epres); FREEMEM(epres);
} }
if(specs->first_extension >= 0) {
unsigned i;
/* Fill DEFAULT members in extensions */ /* Fill DEFAULT members in extensions */
for(edx = specs->roms_count; edx < specs->roms_count for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
+ specs->aoms_count; edx++) { i++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm;
void **memb_ptr2; /* Pointer to member pointer */ void **memb_ptr2; /* Pointer to member pointer */
edx = specs->oms[i];
elm = &td->elements[edx];
if(!elm->default_value_set) continue; if(!elm->default_value_set) continue;
/* Fetch the pointer to this member */ /* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) { if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ elm->memb_offset);
if(*memb_ptr2) continue; if(*memb_ptr2) continue;
} else { } else {
continue; /* Extensions are all optionals */ continue; /* Extensions are all optionals */
...@@ -1303,6 +1293,7 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1303,6 +1293,7 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
ASN__DECODE_FAILED; ASN__DECODE_FAILED;
} }
} }
}
rv.consumed = 0; rv.consumed = 0;
rv.code = RC_OK; rv.code = RC_OK;
...@@ -1312,27 +1303,23 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1312,27 +1303,23 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
static int static int
SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr, SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_per_outp_t *po1, asn_per_outp_t *po2) { asn_per_outp_t *po1, asn_per_outp_t *po2) {
const asn_SEQUENCE_specifics_t *specs const asn_SEQUENCE_specifics_t *specs =
= (const asn_SEQUENCE_specifics_t *)td->specifics; (const asn_SEQUENCE_specifics_t *)td->specifics;
int exts_present = 0; int exts_present = 0;
int exts_count = 0; int exts_count = 0;
size_t edx; size_t edx;
if(specs->ext_before < 0) if(specs->first_extension < 0) {
return 0; return 0;
}
/* Find out which extensions are present */ /* Find out which extensions are present */
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr; /* Pointer to the member */ const void *memb_ptr; /* Pointer to the member */
const void *const *memb_ptr2; /* Pointer to that pointer */ const void *const *memb_ptr2; /* Pointer to that pointer */
int present; int present;
if(!IN_EXTENSION_GROUP(specs, edx)) {
ASN_DEBUG("%s (@%zu) is not extension", elm->type->name, edx);
continue;
}
/* Fetch the pointer to this member */ /* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) { if(elm->flags & ATF_POINTER) {
memb_ptr2 = memb_ptr2 =
...@@ -1344,19 +1331,21 @@ SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -1344,19 +1331,21 @@ SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
present = 1; present = 1;
} }
ASN_DEBUG("checking %s (@%zu) present => %d", ASN_DEBUG("checking %s:%s (@%zu) present => %d", elm->name,
elm->type->name, edx, present); elm->type->name, edx, present);
exts_count++; exts_count++;
exts_present += present; exts_present += present;
/* Encode as presence marker */ /* Encode as presence marker */
if(po1 && per_put_few_bits(po1, present, 1)) if(po1 && per_put_few_bits(po1, present, 1)) {
return -1; return -1;
}
/* Encode as open type field */ /* Encode as open type field */
if(po2 && present && uper_open_type_put(elm->type, if(po2 && present
elm->encoding_constraints.per_constraints, *memb_ptr2, po2)) && uper_open_type_put(elm->type,
elm->encoding_constraints.per_constraints,
*memb_ptr2, po2))
return -1; return -1;
} }
return exts_present ? exts_count : 0; return exts_present ? exts_count : 0;
...@@ -1382,19 +1371,18 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, ...@@ -1382,19 +1371,18 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name); ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
/* /*
* X.691#18.1 Whether structure is extensible * X.691#18.1 Whether structure is extensible
* and whether to encode extensions * and whether to encode extensions
*/ */
if(specs->ext_before >= 0) { if(specs->first_extension < 0) {
n_extensions = 0; /* There are no extensions to encode */
} else {
n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0); n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
if(n_extensions < 0) if(n_extensions < 0) ASN__ENCODE_FAILED;
if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) }
ASN__ENCODE_FAILED;
} else {
n_extensions = 0; /* There are no extensions to encode */
} }
/* Encode a presence bitmap */ /* Encode a presence bitmap */
...@@ -1434,17 +1422,16 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, ...@@ -1434,17 +1422,16 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
/* /*
* Encode the sequence ROOT elements. * Encode the sequence ROOT elements.
*/ */
ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before); ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
for(edx = 0; edx < ((specs->ext_after < 0) td->elements_count);
? td->elements_count : (size_t)specs->ext_before - 1); edx++) { for(edx = 0;
edx < ((specs->first_extension < 0) ? td->elements_count
: (size_t)specs->first_extension);
edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr; /* Pointer to the member */ const void *memb_ptr; /* Pointer to the member */
const void *const *memb_ptr2; /* Pointer to that pointer */ const void *const *memb_ptr2; /* Pointer to that pointer */
if(IN_EXTENSION_GROUP(specs, edx))
continue;
ASN_DEBUG("About to encode %s", elm->type->name); ASN_DEBUG("About to encode %s", elm->type->name);
/* Fetch the pointer to this member */ /* Fetch the pointer to this member */
...@@ -1468,17 +1455,17 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, ...@@ -1468,17 +1455,17 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0) if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
continue; continue;
ASN_DEBUG("Encoding %s->%s", td->name, elm->name); ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
er = elm->type->op->uper_encoder(elm->type, elm->encoding_constraints.per_constraints, er = elm->type->op->uper_encoder(
*memb_ptr2, po); elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
if(er.encoded == -1) po);
return er; if(er.encoded == -1) return er;
} }
/* No extensions to encode */ /* No extensions to encode */
if(!n_extensions) ASN__ENCODED_OK(er); if(!n_extensions) ASN__ENCODED_OK(er);
ASN_DEBUG("Length of %d bit-map", n_extensions); ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
/* #18.8. Write down the presence bit-map length. */ /* #18.8. Write down the presence bit-map length. */
if(uper_put_nslength(po, n_extensions)) if(uper_put_nslength(po, n_extensions))
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
......
...@@ -34,9 +34,10 @@ typedef struct asn_SEQUENCE_specifics_s { ...@@ -34,9 +34,10 @@ typedef struct asn_SEQUENCE_specifics_s {
/* /*
* Description of an extensions group. * Description of an extensions group.
* Root components are clustered at the beginning of the structure,
* whereas extensions are clustered at the end. -1 means not extensible.
*/ */
signed ext_after; /* Extensions start after this member */ signed first_extension; /* First extension addition */
signed ext_before; /* Extensions stop before this member */
} asn_SEQUENCE_specifics_t; } asn_SEQUENCE_specifics_t;
......
...@@ -38,8 +38,14 @@ ...@@ -38,8 +38,14 @@
* Check whether we are inside the extensions group. * Check whether we are inside the extensions group.
*/ */
#define IN_EXTENSION_GROUP(specs, memb_idx) \ #define IN_EXTENSION_GROUP(specs, memb_idx) \
( (((ssize_t)(memb_idx)) > (specs)->ext_after) \ ((specs)->first_extension >= 0 \
&&(((ssize_t)(memb_idx)) < (specs)->ext_before)) && (unsigned)(specs)->first_extension <= (memb_idx))
#define IN_ROOT_GROUP_PRED(edx) \
edx < (specs->first_extension < 0 ? td->elements_count \
: (size_t)specs->first_extension)
#define FOR_IN_ROOT_GROUP(edx) for(edx = 0; IN_ROOT_GROUP_PRED(edx); edx++)
/* /*
* Return a standardized complex structure. * Return a standardized complex structure.
...@@ -117,7 +123,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -117,7 +123,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
* Fetch preamble. * Fetch preamble.
*/ */
asn_bit_data_t *preamble; asn_bit_data_t *preamble;
int has_extensions_bit = (specs->ext_before >= 0); int has_extensions_bit = (specs->first_extension >= 0);
size_t preamble_bits = (has_extensions_bit + specs->roms_count); size_t preamble_bits = (has_extensions_bit + specs->roms_count);
size_t preamble_bytes = ((7 + preamble_bits) >> 3); size_t preamble_bytes = ((7 + preamble_bits) >> 3);
...@@ -146,26 +152,23 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -146,26 +152,23 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
asn_bit_data_t *preamble = ctx->ptr; asn_bit_data_t *preamble = ctx->ptr;
size_t edx; size_t edx;
ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1", td->name); ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1 (Root)", td->name);
assert(preamble); assert(preamble);
for(edx = (ctx->step >> 1); edx < td->elements_count; for(edx = (ctx->step >> 1); IN_ROOT_GROUP_PRED(edx);
edx++, ctx->step = (ctx->step & ~1) + 2) { edx++, ctx->step = (ctx->step & ~1) + 2) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
ASN_DEBUG("Decoding %s->%s", td->name, elm->name); ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
assert(!IN_EXTENSION_GROUP(specs, edx));
if(ctx->step & 1) { if(ctx->step & 1) {
goto microphase2_decode_continues; goto microphase2_decode_continues;
} }
if(IN_EXTENSION_GROUP(specs, edx)) {
/* Ignore non-root components in PHASE 1 */
break;
}
if(elm->optional) { if(elm->optional) {
int32_t present = asn_get_few_bits(preamble, 1); int32_t present = asn_get_few_bits(preamble, 1);
if(present < 0) { if(present < 0) {
...@@ -229,7 +232,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -229,7 +232,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
/* Cleanup preamble. */ /* Cleanup preamble. */
asn_bit_data_t *preamble = ctx->ptr; asn_bit_data_t *preamble = ctx->ptr;
asn_bit_data_t *extadds; asn_bit_data_t *extadds;
int has_extensions_bit = (specs->ext_before >= 0); int has_extensions_bit = (specs->first_extension >= 0);
int extensions_present = int extensions_present =
has_extensions_bit has_extensions_bit
&& (preamble->buffer == NULL && (preamble->buffer == NULL
...@@ -286,11 +289,13 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -286,11 +289,13 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
ADVANCE(len); ADVANCE(len);
} }
NEXT_PHASE(ctx); NEXT_PHASE(ctx);
ctx->step = (specs->ext_after + 1); ctx->step =
(specs->first_extension < 0 ? td->elements_count
: (size_t)specs->first_extension);
/* Fall through */ /* Fall through */
case 3: case 3:
ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3", td->name); ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3 (Extensions)", td->name);
for(; ctx->step < specs->ext_before - 1; ctx->step++) { for(; ctx->step < (signed)td->elements_count; ctx->step++) {
asn_bit_data_t *extadds = ctx->ptr; asn_bit_data_t *extadds = ctx->ptr;
size_t edx = ctx->step; size_t edx = ctx->step;
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
...@@ -378,7 +383,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, ...@@ -378,7 +383,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
asn_app_consume_bytes_f *cb, void *app_key) { asn_app_consume_bytes_f *cb, void *app_key) {
const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics; const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
size_t computed_size = 0; size_t computed_size = 0;
int has_extensions_bit = (specs->ext_before >= 0); int has_extensions_bit = (specs->first_extension >= 0);
size_t preamble_bits = (has_extensions_bit + specs->roms_count); size_t preamble_bits = (has_extensions_bit + specs->roms_count);
uint32_t has_extensions = 0; uint32_t has_extensions = 0;
size_t edx; size_t edx;
...@@ -394,8 +399,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, ...@@ -394,8 +399,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
preamble.op_key = app_key; preamble.op_key = app_key;
if(has_extensions_bit) { if(has_extensions_bit) {
for(edx = specs->ext_after + 1; for(edx = specs->first_extension; edx < td->elements_count; edx++) {
(ssize_t)edx < specs->ext_before - 1; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm); const void *memb_ptr = element_ptr(sptr, elm);
if(memb_ptr) { if(memb_ptr) {
...@@ -419,7 +423,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, ...@@ -419,7 +423,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
* Encode optional components bitmap. * Encode optional components bitmap.
*/ */
if(specs->roms_count) { if(specs->roms_count) {
for(edx = 0; edx < td->elements_count; edx++) { FOR_IN_ROOT_GROUP(edx) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
if(IN_EXTENSION_GROUP(specs, edx)) break; if(IN_EXTENSION_GROUP(specs, edx)) break;
...@@ -507,8 +511,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, ...@@ -507,8 +511,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
if(ret < 0) ASN__ENCODE_FAILED; if(ret < 0) ASN__ENCODE_FAILED;
/* Encode presence bitmap #16.4.3 */ /* Encode presence bitmap #16.4.3 */
for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1; for(edx = specs->first_extension; edx < td->elements_count; edx++) {
edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm); const void *memb_ptr = element_ptr(sptr, elm);
if(memb_ptr && elm->default_value_cmp if(memb_ptr && elm->default_value_cmp
...@@ -523,8 +526,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td, ...@@ -523,8 +526,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
computed_size += extadds.flushed_bytes; computed_size += extadds.flushed_bytes;
/* Now, encode extensions */ /* Now, encode extensions */
for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1; for(edx = specs->first_extension; edx < td->elements_count; edx++) {
edx++) {
asn_TYPE_member_t *elm = &td->elements[edx]; asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm); const void *memb_ptr = element_ptr(sptr, elm);
......
...@@ -70,6 +70,6 @@ SEQUENCE { ..., one NULL, two [2] NULL, ..., three [3] NULL } ...@@ -70,6 +70,6 @@ SEQUENCE { ..., one NULL, two [2] NULL, ..., three [3] NULL }
SEQUENCE { ..., one NULL, ..., two [2] NULL, three [3] NULL } SEQUENCE { ..., one NULL, ..., two [2] NULL, three [3] NULL }
SEQUENCE { ..., one BOOLEAN, ..., two [2] BOOLEAN, three [3] BOOLEAN } SEQUENCE { ..., one BOOLEAN, ..., two [2] BOOLEAN, three [3] BOOLEAN }
SEQUENCE { ..., one BOOLEAN, two BIT STRING (SIZE(1..3)) } SEQUENCE { ..., one BOOLEAN, two BIT STRING (SIZE(1..3)) }
-- not yet SEQUENCE { ..., null NULL, ..., one BOOLEAN, two BIT STRING (SIZE(1..3)) } SEQUENCE { ..., null NULL, ..., one BOOLEAN, two BIT STRING (SIZE(1..3)) }
SEQUENCE { ..., one NULL, two BOOLEAN, three BIT STRING (SIZE(1..3)) } SEQUENCE { ..., one NULL, two BOOLEAN, three BIT STRING (SIZE(1..3)) }
-- not yet SEQUENCE { ..., null NULL, ..., one [1] NULL, two BOOLEAN, three BIT STRING (SIZE(1..3)) } SEQUENCE { ..., null NULL, ..., one [1] NULL, two BOOLEAN, three BIT STRING (SIZE(1..3)) }
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