From 5253da42fdf66eec4c96455ab5dbd57e9ccee1fa Mon Sep 17 00:00:00 2001 From: Lev Walkin <vlm@lionet.info> Date: Fri, 20 Aug 2004 13:25:56 +0000 Subject: [PATCH] effective constraint type for walking past SIZE() or FROM() nodes --- libasn1fix/asn1fix.c | 19 +++++++++++++-- libasn1fix/asn1fix.h | 3 ++- libasn1fix/asn1fix_constraint.c | 41 +++++++++++++++++++++++++-------- libasn1fix/asn1fix_constraint.h | 4 +++- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c index dd0d5e73..2a78aa13 100644 --- a/libasn1fix/asn1fix.c +++ b/libasn1fix/asn1fix.c @@ -54,6 +54,16 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags, flags &= ~A1F_DEBUG; } + /* Allow SIZE() constraint for INTEGER and other types */ + if(flags & A1F_EXTENDED_SizeConstraint) { + arg.flags |= A1F_EXTENDED_SizeConstraint; + flags &= ~A1F_EXTENDED_SizeConstraint; + if(arg.debug) { + arg.debug(-1, + "Extended SizeConstraint support enabled"); + } + } + a1f_replace_me_with_proper_interface_arg = arg; /* @@ -273,16 +283,21 @@ asn1f_fix_constructed(arg_t *arg) { static int asn1f_fix_constraints(arg_t *arg) { asn1p_expr_t *top_parent; + asn1p_expr_type_e etype; int rvalue = 0; int ret; - ret = asn1constraint_resolve(arg, arg->expr->constraints); + top_parent = asn1f_find_terminal_type(arg, arg->expr, NULL); + if(top_parent) + etype = top_parent->expr_type; + else etype = A1TC_INVALID; + + ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0); RET2RVAL(ret, rvalue); ret = asn1constraint_pullup(arg); RET2RVAL(ret, rvalue); - top_parent = asn1f_find_terminal_type(arg, arg->expr, NULL); if(top_parent) { static enum asn1p_constraint_type_e test_types[] = { ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM }; diff --git a/libasn1fix/asn1fix.h b/libasn1fix/asn1fix.h index 1bed8581..c75c81cf 100644 --- a/libasn1fix/asn1fix.h +++ b/libasn1fix/asn1fix.h @@ -12,7 +12,8 @@ */ enum asn1f_flags { A1F_NOFLAGS, - A1F_DEBUG = 0x01, /* Print debugging output */ + A1F_DEBUG = 0x01, /* Print debugging output */ + A1F_EXTENDED_SizeConstraint = 0x02, /* Enable constraint gen code */ }; /* diff --git a/libasn1fix/asn1fix_constraint.c b/libasn1fix/asn1fix_constraint.c index b7b66c44..4620ec52 100644 --- a/libasn1fix/asn1fix_constraint.c +++ b/libasn1fix/asn1fix_constraint.c @@ -120,8 +120,7 @@ asn1constraint_pullup(arg_t *arg) { } int -asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { - asn1p_expr_t *top_parent; +asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) { int rvalue = 0; int ret; int el; @@ -130,6 +129,18 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { /* Don't touch information object classes */ switch(ct->type) { + case ACT_CT_SIZE: + case ACT_CT_FROM: + if(effective_type && effective_type != ct->type) { + FATAL("%s at line %d: " + "Incompatible nested %s within %s", + arg->expr->Identifier, ct->_lineno, + asn1p_constraint_type2str(ct->type), + asn1p_constraint_type2str(effective_type) + ); + } + effective_type = ct->type; + break; case ACT_CT_WCOMP: case ACT_CT_WCOMPS: case ACT_CA_CRC: @@ -138,21 +149,26 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { break; } - top_parent = asn1f_find_terminal_type(arg, arg->expr, 0); - if(top_parent) { - ret = asn1constraint_compatible(top_parent->expr_type, - ct->type); + if(etype != A1TC_INVALID) { + enum asn1p_constraint_type_e check_type; + + check_type = effective_type ? effective_type : ct->type; + + ret = asn1constraint_compatible(etype, check_type); switch(ret) { case -1: /* If unknown, assume OK. */ case 1: break; case 0: + if(effective_type == ACT_CT_SIZE + && (arg->flags & A1F_EXTENDED_SizeConstraint)) + break; default: FATAL("%s at line %d: " "Constraint type %s is not applicable to %s", arg->expr->Identifier, ct->_lineno, - asn1p_constraint_type2str(ct->type), - ASN_EXPR_TYPE2STR(top_parent->expr_type) + asn1p_constraint_type2str(check_type), + ASN_EXPR_TYPE2STR(etype) ); rvalue = -1; break; @@ -163,6 +179,9 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { arg->expr->Identifier, arg->expr->_lineno); } + /* + * Resolve all possible references, wherever they occur. + */ if(ct->value && ct->value->type == ATV_REFERENCED) { ret = _constraint_value_resolve(arg, &ct->value); RET2RVAL(ret, rvalue); @@ -176,8 +195,12 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { RET2RVAL(ret, rvalue); } + /* + * Proceed recursively. + */ for(el = 0; el < ct->el_count; el++) { - ret = asn1constraint_resolve(arg, ct->elements[el]); + ret = asn1constraint_resolve(arg, ct->elements[el], + etype, effective_type); RET2RVAL(ret, rvalue); } diff --git a/libasn1fix/asn1fix_constraint.h b/libasn1fix/asn1fix_constraint.h index a04e6a50..9e692efa 100644 --- a/libasn1fix/asn1fix_constraint.h +++ b/libasn1fix/asn1fix_constraint.h @@ -4,7 +4,9 @@ /* * Resolve referenced values inside constraints. */ -int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct); +int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, + asn1p_expr_type_e topmost_parent_expression_type, + enum asn1p_constraint_type_e effective_constraint_type); /* * Collect all subtype constraints from all parents of this type and -- GitLab