fix after UPER round-trip fuzz

This commit is contained in:
Lev Walkin 2017-10-21 00:24:31 -07:00
parent 5de8274266
commit 836686167d
5 changed files with 206 additions and 222 deletions

View File

@ -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 *v;
int elements; /* Number of elements */
int ext_start = -2;
int ext_stop = -2;
int first_extension = -1;
tag2el_t *tag2el = NULL;
int tag2el_count = 0;
int tags_count;
@ -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) {
if(v->expr_type == A1TC_EXTENSIBLE) {
if((++comp_mode) == 1)
ext_start = elements - 1;
else
ext_stop = elements - 1;
first_extension = elements;
continue;
}
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
} else {
OUT("0, 0, 0,\t/* Optional elements (not needed) */\n");
}
OUT("%d,\t/* Start extensions */\n",
ext_start<0 ? -1 : ext_start);
OUT("%d\t/* Stop extensions */\n",
(ext_stop<ext_start)?elements+1:(ext_stop<0?-1:ext_stop));
OUT("%d,\t/* First extension addition */\n", first_extension);
INDENT(-1);
OUT("};\n");
@ -1196,7 +1190,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
OUT("asn_MAP_%s_from_canonical_%d,\n", MKID(expr),
expr->_type_unique_index);
} 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("};\n");
@ -3397,7 +3391,7 @@ compute_canonical_members_order(arg_t *arg, int el_count) {
int *rmap;
asn1p_expr_t *v;
int eidx = 0;
int ext_start = -1;
int first_extension = -1;
int nextmax = -1;
int already_sorted = 1;
@ -3409,18 +3403,18 @@ compute_canonical_members_order(arg_t *arg, int el_count) {
cmap[eidx].eidx = eidx;
cmap[eidx].expr = v;
eidx++;
} else if(ext_start == -1)
ext_start = eidx;
} else if(first_extension == -1)
first_extension = eidx;
}
cameo_arg = arg;
if(ext_start == -1) {
if(first_extension == -1) {
/* Sort the whole thing */
qsort(cmap, el_count, sizeof(*cmap), compar_cameo);
} else {
/* Sort root and extensions independently */
qsort(cmap, ext_start, sizeof(*cmap), compar_cameo);
qsort(cmap + ext_start, el_count - ext_start,
qsort(cmap, first_extension, sizeof(*cmap), compar_cameo);
qsort(cmap + first_extension, el_count - first_extension,
sizeof(*cmap), compar_cameo);
}

View File

@ -1,4 +1,4 @@
/*-
/*
* Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
@ -66,10 +66,9 @@
/*
* Check whether we are inside the extensions group.
*/
#define IN_EXTENSION_GROUP(specs, memb_idx) \
( (((signed)(memb_idx)) > (specs)->ext_after) \
&&(((signed)(memb_idx)) < (specs)->ext_before))
#define IN_EXTENSION_GROUP(specs, memb_idx) \
((specs)->first_extension >= 0 \
&& (unsigned)(specs)->first_extension <= (memb_idx))
/*
* Tags are canonically sorted in the tag2element map.
@ -209,24 +208,19 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
elements[edx].flags, elements[edx].optional,
td->elements_count);
if(ctx->left == 0 /* No more stuff is expected */
&& (
/* Explicit OPTIONAL specification reaches the end */
(edx + elements[edx].optional
== td->elements_count)
||
/* All extensions are optional */
(IN_EXTENSION_GROUP(specs, edx)
&& specs->ext_before > (signed)td->elements_count)
)
) {
ASN_DEBUG("End of SEQUENCE %s", td->name);
/*
* Found the legitimate end of the structure.
*/
PHASE_OUT(ctx);
RETURN(RC_OK);
}
if(ctx->left == 0 /* No more stuff is expected */
&& (
/* Explicit OPTIONAL specification reaches the end */
(edx + elements[edx].optional == td->elements_count) ||
/* All extensions are optional */
IN_EXTENSION_GROUP(specs, edx))) {
ASN_DEBUG("End of SEQUENCE %s", td->name);
/*
* Found the legitimate end of the structure.
*/
PHASE_OUT(ctx);
RETURN(RC_OK);
}
/*
* Fetch the T from TLV.
@ -242,34 +236,31 @@ SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
case -1: RETURN(RC_FAIL);
}
if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
if(LEFT < 2) {
if(SIZE_VIOLATION)
RETURN(RC_FAIL);
else
RETURN(RC_WMORE);
} else if(((const uint8_t *)ptr)[1] == 0) {
ASN_DEBUG("edx = %zu, opt = %d, ec=%d",
edx, elements[edx].optional,
td->elements_count);
if((edx + elements[edx].optional
== td->elements_count)
|| (IN_EXTENSION_GROUP(specs, edx)
&& specs->ext_before
> (signed)td->elements_count)) {
/*
* Yeah, baby! Found the terminator
* of the indefinite length structure.
*/
/*
* Proceed to the canonical
* finalization function.
* No advancing is necessary.
*/
goto phase3;
}
}
}
if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
if(LEFT < 2) {
if(SIZE_VIOLATION) {
RETURN(RC_FAIL);
} else {
RETURN(RC_WMORE);
}
} else if(((const uint8_t *)ptr)[1] == 0) {
ASN_DEBUG("edx = %zu, opt = %d, ec=%d", edx,
elements[edx].optional, td->elements_count);
if((edx + elements[edx].optional == td->elements_count)
|| IN_EXTENSION_GROUP(specs, edx)) {
/*
* Yeah, baby! Found the terminator
* of the indefinite length structure.
*/
/*
* Proceed to the canonical
* finalization function.
* No advancing is necessary.
*/
goto phase3;
}
}
}
/*
* Find the next available type with this tag.
@ -766,19 +757,13 @@ SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
ctx->phase = 0;
/* Fall through */
case XCT_BOTH:
if(ctx->phase == 0) {
if(edx >= td->elements_count
||
/* Explicit OPTIONAL specs reaches the end */
(edx + elements[edx].optional
== td->elements_count)
||
/* All extensions are optional */
(IN_EXTENSION_GROUP(specs, edx)
&& specs->ext_before
> (signed)td->elements_count)
) {
XER_ADVANCE(ch_size);
if(ctx->phase == 0) {
if(edx >= td->elements_count ||
/* Explicit OPTIONAL specs reaches the end */
(edx + elements[edx].optional == td->elements_count) ||
/* All extensions are optional */
IN_EXTENSION_GROUP(specs, edx)) {
XER_ADVANCE(ch_size);
ctx->phase = 4; /* Phase out */
RETURN(RC_OK);
} else {
@ -1113,11 +1098,11 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
/* Handle extensions */
if(specs->ext_before >= 0) {
if(specs->first_extension < 0) {
extpresent = 0;
} else {
extpresent = per_get_few_bits(pd, 1);
if(extpresent < 0) ASN__DECODE_STARVED;
} else {
extpresent = 0;
}
/* Prepare a place and read-in the presence bitmap */
@ -1141,13 +1126,15 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
/*
* Get the sequence ROOT elements.
*/
for(edx = 0; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[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];
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
if(IN_EXTENSION_GROUP(specs, edx))
continue;
assert(!IN_EXTENSION_GROUP(specs, edx));
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
@ -1210,7 +1197,7 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
bmlength = uper_get_nslength(pd);
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);
if(!epres) ASN__DECODE_STARVED;
@ -1228,38 +1215,35 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
td->name, (long)bmlength, *epres);
/* Go over extensions and read them in */
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
int present;
for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
int present;
if(!IN_EXTENSION_GROUP(specs, edx)) {
ASN_DEBUG("%zu is not an extension", edx);
continue;
}
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
} else {
memb_ptr = (void *)((char *)st + elm->memb_offset);
memb_ptr2 = &memb_ptr;
}
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
} else {
memb_ptr = (void *)((char *)st + elm->memb_offset);
memb_ptr2 = &memb_ptr;
}
present = per_get_few_bits(&epmd, 1);
if(present <= 0) {
if(present < 0) break; /* No more extensions */
continue;
}
present = per_get_few_bits(&epmd, 1);
if(present <= 0) {
if(present < 0) break; /* No more extensions */
continue;
}
ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
rv = uper_open_type_get(opt_codec_ctx, elm->type,
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
if(rv.code != RC_OK) {
FREEMEM(epres);
return rv;
}
ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
*memb_ptr2);
rv = uper_open_type_get(opt_codec_ctx, elm->type,
elm->encoding_constraints.per_constraints,
memb_ptr2, pd);
if(rv.code != RC_OK) {
FREEMEM(epres);
return rv;
}
}
/* Skip over overflow extensions which aren't present
@ -1274,6 +1258,8 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
FREEMEM(epres);
ASN__DECODE_STARVED;
}
ASN_DEBUG("Skipped overflow extension");
continue;
}
break;
}
@ -1281,28 +1267,33 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
FREEMEM(epres);
}
/* Fill DEFAULT members in extensions */
for(edx = specs->roms_count; edx < specs->roms_count
+ specs->aoms_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
void **memb_ptr2; /* Pointer to member pointer */
if(specs->first_extension >= 0) {
unsigned i;
/* Fill DEFAULT members in extensions */
for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
i++) {
asn_TYPE_member_t *elm;
void **memb_ptr2; /* Pointer to member pointer */
if(!elm->default_value_set) continue;
edx = specs->oms[i];
elm = &td->elements[edx];
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st
+ elm->memb_offset);
if(*memb_ptr2) continue;
} else {
continue; /* Extensions are all optionals */
}
if(!elm->default_value_set) continue;
/* Set default value */
if(elm->default_value_set(memb_ptr2)) {
ASN__DECODE_FAILED;
}
}
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
if(*memb_ptr2) continue;
} else {
continue; /* Extensions are all optionals */
}
/* Set default value */
if(elm->default_value_set(memb_ptr2)) {
ASN__DECODE_FAILED;
}
}
}
rv.consumed = 0;
rv.code = RC_OK;
@ -1312,54 +1303,52 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
static int
SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_per_outp_t *po1, asn_per_outp_t *po2) {
const asn_SEQUENCE_specifics_t *specs
= (const asn_SEQUENCE_specifics_t *)td->specifics;
int exts_present = 0;
int exts_count = 0;
size_t edx;
const asn_SEQUENCE_specifics_t *specs =
(const asn_SEQUENCE_specifics_t *)td->specifics;
int exts_present = 0;
int exts_count = 0;
size_t edx;
if(specs->ext_before < 0)
return 0;
if(specs->first_extension < 0) {
return 0;
}
/* Find out which extensions are present */
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr; /* Pointer to the member */
/* Find out which extensions are present */
for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr; /* Pointer to the member */
const void *const *memb_ptr2; /* Pointer to that pointer */
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 */
if(elm->flags & ATF_POINTER) {
/* Fetch the pointer to this member */
if(elm->flags & ATF_POINTER) {
memb_ptr2 =
(const void *const *)((const char *)sptr + elm->memb_offset);
present = (*memb_ptr2 != 0);
} else {
} else {
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
memb_ptr2 = &memb_ptr;
present = 1;
}
ASN_DEBUG("checking %s (@%zu) present => %d",
elm->type->name, edx, present);
exts_count++;
exts_present += present;
ASN_DEBUG("checking %s:%s (@%zu) present => %d", elm->name,
elm->type->name, edx, present);
exts_count++;
exts_present += present;
/* Encode as presence marker */
if(po1 && per_put_few_bits(po1, present, 1))
return -1;
/* Encode as open type field */
if(po2 && present && uper_open_type_put(elm->type,
elm->encoding_constraints.per_constraints, *memb_ptr2, po2))
return -1;
/* Encode as presence marker */
if(po1 && per_put_few_bits(po1, present, 1)) {
return -1;
}
/* Encode as open type field */
if(po2 && present
&& uper_open_type_put(elm->type,
elm->encoding_constraints.per_constraints,
*memb_ptr2, po2))
return -1;
}
}
return exts_present ? exts_count : 0;
return exts_present ? exts_count : 0;
}
asn_enc_rval_t
@ -1382,20 +1371,19 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
/*
* X.691#18.1 Whether structure is extensible
* and whether to encode extensions
*/
if(specs->ext_before >= 0) {
n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
if(n_extensions < 0)
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 */
}
if(specs->first_extension < 0) {
n_extensions = 0; /* There are no extensions to encode */
} else {
n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
if(n_extensions < 0) ASN__ENCODE_FAILED;
if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
ASN__ENCODE_FAILED;
}
}
/* Encode a presence bitmap */
for(i = 0; i < specs->roms_count; i++) {
@ -1434,16 +1422,15 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
/*
* Encode the sequence ROOT elements.
*/
ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
for(edx = 0; edx < ((specs->ext_after < 0)
? td->elements_count : (size_t)specs->ext_before - 1); edx++) {
ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
td->elements_count);
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];
const void *memb_ptr; /* Pointer to the member */
const void *const *memb_ptr2; /* Pointer to that pointer */
if(IN_EXTENSION_GROUP(specs, edx))
continue;
const void *memb_ptr; /* Pointer to the member */
const void *const *memb_ptr2; /* Pointer to that pointer */
ASN_DEBUG("About to encode %s", elm->type->name);
@ -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)
continue;
ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
er = elm->type->op->uper_encoder(elm->type, elm->encoding_constraints.per_constraints,
*memb_ptr2, po);
if(er.encoded == -1)
return er;
}
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, *memb_ptr2,
po);
if(er.encoded == -1) return er;
}
/* No extensions to encode */
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. */
if(uper_put_nslength(po, n_extensions))
ASN__ENCODE_FAILED;

View File

@ -34,9 +34,10 @@ typedef struct asn_SEQUENCE_specifics_s {
/*
* 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 ext_before; /* Extensions stop before this member */
signed first_extension; /* First extension addition */
} asn_SEQUENCE_specifics_t;

View File

@ -37,9 +37,15 @@
/*
* Check whether we are inside the extensions group.
*/
#define IN_EXTENSION_GROUP(specs, memb_idx) \
( (((ssize_t)(memb_idx)) > (specs)->ext_after) \
&&(((ssize_t)(memb_idx)) < (specs)->ext_before))
#define IN_EXTENSION_GROUP(specs, memb_idx) \
((specs)->first_extension >= 0 \
&& (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.
@ -117,7 +123,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
* Fetch 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_bytes = ((7 + preamble_bits) >> 3);
@ -146,26 +152,23 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
asn_bit_data_t *preamble = ctx->ptr;
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);
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) {
asn_TYPE_member_t *elm = &td->elements[edx];
ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
assert(!IN_EXTENSION_GROUP(specs, edx));
if(ctx->step & 1) {
goto microphase2_decode_continues;
}
if(IN_EXTENSION_GROUP(specs, edx)) {
/* Ignore non-root components in PHASE 1 */
break;
}
if(elm->optional) {
int32_t present = asn_get_few_bits(preamble, 1);
if(present < 0) {
@ -229,7 +232,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
/* Cleanup preamble. */
asn_bit_data_t *preamble = ctx->ptr;
asn_bit_data_t *extadds;
int has_extensions_bit = (specs->ext_before >= 0);
int has_extensions_bit = (specs->first_extension >= 0);
int extensions_present =
has_extensions_bit
&& (preamble->buffer == NULL
@ -286,11 +289,13 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
ADVANCE(len);
}
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 */
case 3:
ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3", td->name);
for(; ctx->step < specs->ext_before - 1; ctx->step++) {
ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3 (Extensions)", td->name);
for(; ctx->step < (signed)td->elements_count; ctx->step++) {
asn_bit_data_t *extadds = ctx->ptr;
size_t edx = ctx->step;
asn_TYPE_member_t *elm = &td->elements[edx];
@ -378,7 +383,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
asn_app_consume_bytes_f *cb, void *app_key) {
const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
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);
uint32_t has_extensions = 0;
size_t edx;
@ -394,8 +399,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
preamble.op_key = app_key;
if(has_extensions_bit) {
for(edx = specs->ext_after + 1;
(ssize_t)edx < specs->ext_before - 1; edx++) {
for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm);
if(memb_ptr) {
@ -419,7 +423,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
* Encode optional components bitmap.
*/
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];
if(IN_EXTENSION_GROUP(specs, edx)) break;
@ -507,8 +511,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
if(ret < 0) ASN__ENCODE_FAILED;
/* Encode presence bitmap #16.4.3 */
for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1;
edx++) {
for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm);
if(memb_ptr && elm->default_value_cmp
@ -523,8 +526,7 @@ SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
computed_size += extadds.flushed_bytes;
/* Now, encode extensions */
for(edx = specs->ext_after + 1; (ssize_t)edx < specs->ext_before - 1;
edx++) {
for(edx = specs->first_extension; edx < td->elements_count; edx++) {
asn_TYPE_member_t *elm = &td->elements[edx];
const void *memb_ptr = element_ptr(sptr, elm);

View File

@ -70,6 +70,6 @@ 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 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)) }
-- 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)) }