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);
} }
......
This diff is collapsed.
...@@ -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;
......
...@@ -37,9 +37,15 @@ ...@@ -37,9 +37,15 @@
/* /*
* 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