aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-09-05 10:36:22 +0000
committerLev Walkin <vlm@lionet.info>2004-09-05 10:36:22 +0000
commitd541c25aeacb6a7088e7c990255180f32d45c95c (patch)
tree45d37f30015b811b7d6889a747fcbe7583465c54
parent8b03ea35d3269c0cc720fb18b0fbeefb5b1dd645 (diff)
more support for parametrized type; additional ANY support
-rw-r--r--libasn1fix/asn1fix.c33
-rw-r--r--libasn1fix/asn1fix_constr.c144
-rw-r--r--libasn1fix/asn1fix_constr.h2
-rw-r--r--libasn1fix/asn1fix_constraint.c6
-rw-r--r--libasn1fix/asn1fix_crange.c2
-rw-r--r--libasn1fix/asn1fix_param.c131
-rw-r--r--libasn1fix/asn1fix_tags.c10
-rw-r--r--libasn1fix/asn1fix_tags.h2
8 files changed, 248 insertions, 82 deletions
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index 46a32727..4a279325 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -159,15 +159,21 @@ asn1f_fix_module(arg_t *arg) {
RET2RVAL(ret, rvalue);
/*
- * 2.[234] Process SEQUENCE/SET/CHOICE types.
+ * 2.5.4
*/
- ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
+ ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
RET2RVAL(ret, rvalue);
/*
- * 2.5.4
+ * Fix tagging of top-level types.
*/
- ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
+ ret = asn1f_fix_constr_tag(arg, 1);
+ RET2RVAL(ret, rvalue);
+
+ /*
+ * 2.[234] Process SEQUENCE/SET/CHOICE types.
+ */
+ ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
RET2RVAL(ret, rvalue);
/*
@@ -239,6 +245,10 @@ asn1f_fix_module(arg_t *arg) {
TQ_FOR(expr, &(arg->mod->members), next) {
arg->expr = expr;
+ if(arg->expr->meta_type == AMT_PARAMTYPE)
+ /* Do not process the parametrized types here */
+ continue;
+
ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
RET2RVAL(ret, rvalue);
@@ -286,7 +296,7 @@ asn1f_fix_constructed(arg_t *arg) {
RET2RVAL(ret, rvalue);
/* Fix tagging */
- ret = asn1f_fix_constr_tag(arg);
+ ret = asn1f_fix_constr_tag(arg, 0);
RET2RVAL(ret, rvalue);
/* Import COMPONENTS OF stuff */
@@ -308,6 +318,8 @@ asn1f_resolve_constraints(arg_t *arg) {
etype = top_parent->expr_type;
else etype = A1TC_INVALID;
+ DEBUG("asn1f_resolve_constraints(%s)", arg->expr->Identifier);
+
ret = asn1constraint_resolve(arg, arg->expr->module,
arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue);
@@ -326,6 +338,10 @@ asn1f_check_constraints(arg_t *arg) {
int rvalue = 0;
int ret;
+ DEBUG("asn1f_check_constraints(%s{%d/%d})",
+ arg->expr->Identifier,
+ arg->expr->meta_type, arg->expr->expr_type);
+
top_parent = asn1f_find_terminal_type(arg, arg->expr);
if(!top_parent)
return 0;
@@ -339,8 +355,13 @@ asn1f_check_constraints(arg_t *arg) {
etype,
arg->expr->combined_constraints,
test_types[i], 0, 0, 0);
- if(!range && errno == EPERM)
+ if(!range && errno == EPERM) {
+ FATAL("This error happened for %s (%d) at line %d",
+ arg->expr->Identifier,
+ arg->expr->meta_type,
+ arg->expr->_lineno);
return -1;
+ }
asn1constraint_range_free(range);
}
diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c
index fab78d37..8c9dd383 100644
--- a/libasn1fix/asn1fix_constr.c
+++ b/libasn1fix/asn1fix_constr.c
@@ -1,7 +1,10 @@
#include "asn1fix_internal.h"
+#define AFT_IMAGINARY_ANY 1 /* _fetch_tag() flag */
+
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
+static int _asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr);
int
asn1f_pull_components_of(arg_t *arg) {
@@ -77,6 +80,9 @@ asn1f_pull_components_of(arg_t *arg) {
return r_value;
}
+/*
+ * Fix extensibility parts inside constructed types (SEQUENCE, SET, CHOICE).
+ */
int
asn1f_fix_constr_ext(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
@@ -103,6 +109,10 @@ asn1f_fix_constr_ext(arg_t *arg) {
TQ_INIT(&ext_list);
cur_list = (void *)&root_list;
+ /*
+ * Split the set of fields into two lists, the root list
+ * and the extensions list.
+ */
while((v = TQ_REMOVE(&(expr->members), next))) {
if(v->expr_type == A1TC_EXTENSIBLE) {
ext_count++;
@@ -161,16 +171,30 @@ asn1f_fix_constr_ext(arg_t *arg) {
int
-asn1f_fix_constr_tag(arg_t *arg) {
+asn1f_fix_constr_tag(arg_t *arg, int fix_top_level) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
- int fl_impl_tags = 0;
- int fl_auto_tags = 0;
int root_tagged = 0; /* The root component is manually tagged */
int ext_tagged = 0; /* The extensions are manually tagged */
int component_number = 0;
int r_value = 0;
+ DEBUG("%s(%s) for line %d", __func__,
+ expr->Identifier, expr->_lineno);
+
+ /*
+ * Fix the top-level type itself first.
+ */
+ if(fix_top_level) {
+ if(expr->tag.tag_class == TC_NOCLASS)
+ return r_value;
+
+ if(_asn1f_fix_type_tag(arg, expr))
+ r_value = -1;
+
+ return r_value;
+ }
+
switch(expr->expr_type) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
@@ -180,14 +204,7 @@ asn1f_fix_constr_tag(arg_t *arg) {
return 0;
}
- fl_impl_tags = (arg->mod->module_flags & MSF_IMPLICIT_TAGS);
- fl_auto_tags = (arg->mod->module_flags & MSF_AUTOMATIC_TAGS);
-
- DEBUG("%s(%s) {%d, %d} for line %d", __func__,
- expr->Identifier, fl_impl_tags, fl_auto_tags, expr->_lineno);
-
TQ_FOR(v, &(expr->members), next) {
- int must_explicit = 0;
if(v->expr_type == A1TC_EXTENSIBLE) {
component_number++;
@@ -196,43 +213,18 @@ asn1f_fix_constr_tag(arg_t *arg) {
if(v->tag.tag_class == TC_NOCLASS) {
continue;
- } else {
- switch(component_number) {
- case 0: case 2:
- root_tagged = 1; break;
- default:
- ext_tagged = 1; break;
- }
}
- must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);
-
- if(fl_impl_tags) {
- if(v->tag.tag_mode != TM_EXPLICIT) {
- if(must_explicit)
- v->tag.tag_mode = TM_EXPLICIT;
- else
- v->tag.tag_mode = TM_IMPLICIT;
- }
- } else {
- if(v->tag.tag_mode == TM_DEFAULT) {
- v->tag.tag_mode = TM_EXPLICIT;
- }
+ switch(component_number) {
+ case 0: case 2:
+ root_tagged = 1; break;
+ default:
+ ext_tagged = 1; break;
}
- /*
- * Perform a final sanity check.
- */
- if(must_explicit) {
- if(v->tag.tag_mode == TM_IMPLICIT) {
- FATAL("%s tagged in IMPLICIT mode "
- "but must be EXPLICIT at line %d",
- v->Identifier, v->_lineno);
- r_value = -1;
- } else {
- v->tag.tag_mode = TM_EXPLICIT;
- }
- }
+ if(_asn1f_fix_type_tag(arg, v))
+ r_value = -1;
+
}
if(ext_tagged && !root_tagged) {
@@ -241,13 +233,51 @@ asn1f_fix_constr_tag(arg_t *arg) {
"but root components are not",
expr->Identifier, expr->_lineno);
r_value = -1;
- } else if(!root_tagged && !ext_tagged && fl_auto_tags) {
+ } else if(!root_tagged && !ext_tagged
+ && (arg->mod->module_flags & MSF_AUTOMATIC_TAGS)) {
+ /* Make a decision on automatic tagging */
expr->auto_tags_OK = 1;
}
return r_value;
}
+static int
+_asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr) {
+ int must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, expr);
+ int fl_impl_tags = (arg->mod->module_flags & MSF_IMPLICIT_TAGS);
+ int r_value = 0;
+
+ if(fl_impl_tags) {
+ if(expr->tag.tag_mode != TM_EXPLICIT) {
+ if(must_explicit)
+ expr->tag.tag_mode = TM_EXPLICIT;
+ else
+ expr->tag.tag_mode = TM_IMPLICIT;
+ }
+ } else {
+ if(expr->tag.tag_mode == TM_DEFAULT) {
+ expr->tag.tag_mode = TM_EXPLICIT;
+ }
+ }
+
+ /*
+ * Perform a final sanity check.
+ */
+ if(must_explicit) {
+ if(expr->tag.tag_mode == TM_IMPLICIT) {
+ FATAL("%s tagged in IMPLICIT mode "
+ "but must be EXPLICIT at line %d",
+ expr->Identifier, expr->_lineno);
+ r_value = -1;
+ } else {
+ expr->tag.tag_mode = TM_EXPLICIT;
+ }
+ }
+
+ return r_value;
+}
+
int
asn1f_fix_constr_autotag(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
@@ -333,11 +363,25 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
static int
_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
+ struct asn1p_type_tag_s tag;
+ struct asn1p_type_tag_s save_tag;
asn1p_expr_t *reft;
+ int ret;
+
+ /*
+ * Fetch the _next_ tag for this type.
+ */
+ save_tag = v->tag; /* Save existing tag */
+ memset(&v->tag, 0, sizeof(v->tag)); /* Remove it temporarily */
+ ret = asn1f_fetch_tag(arg->asn, arg->mod, v, &tag, 0);
+ v->tag = save_tag; /* Restore the tag back */
+
+ if(ret == 0) return 0; /* If found tag, it's okay */
reft = asn1f_find_terminal_type(arg, v);
if(reft) {
switch(reft->expr_type) {
+ case ASN_TYPE_ANY:
case ASN_CONSTR_CHOICE:
return 1;
default:
@@ -357,8 +401,8 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
int ra, rb;
int ret;
- ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta);
- rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb);
+ ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta, AFT_IMAGINARY_ANY);
+ rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb, AFT_IMAGINARY_ANY);
/*
* If both tags are explicitly or implicitly given, use them.
@@ -367,8 +411,12 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
/*
* Simple case: fetched both tags.
*/
- if(ta.tag_value == tb.tag_value
- && ta.tag_class == tb.tag_class) {
+
+ if((ta.tag_value == tb.tag_value
+ && ta.tag_class == tb.tag_class)
+ || ta.tag_value == -1 /* Spread IMAGINARY ANY tag... */
+ || tb.tag_value == -1 /* ...it is an evil virus, fear it! */
+ ) {
char *p = (a->expr_type == A1TC_EXTENSIBLE)
?"potentially ":"";
FATAL("Component \"%s\" at line %d %shas the same tag "
diff --git a/libasn1fix/asn1fix_constr.h b/libasn1fix/asn1fix_constr.h
index 59970adf..ffed1437 100644
--- a/libasn1fix/asn1fix_constr.h
+++ b/libasn1fix/asn1fix_constr.h
@@ -14,7 +14,7 @@ int asn1f_fix_constr_ext(arg_t *);
/*
* Fix tagging in constructed types.
*/
-int asn1f_fix_constr_tag(arg_t *);
+int asn1f_fix_constr_tag(arg_t *, int fix_top_level);
/*
* Check distinctive tagging in constructed types.
diff --git a/libasn1fix/asn1fix_constraint.c b/libasn1fix/asn1fix_constraint.c
index 4a25faee..3f30009e 100644
--- a/libasn1fix/asn1fix_constraint.c
+++ b/libasn1fix/asn1fix_constraint.c
@@ -93,7 +93,7 @@ asn1constraint_pullup(arg_t *arg) {
expr->combined_constraints = ct_parent;
if(ct_expr->type == ACT_CA_SET) {
- int i;
+ unsigned int i;
for(i = 0; i < ct_expr->el_count; i++) {
if(asn1p_constraint_insert(
expr->combined_constraints,
@@ -120,9 +120,9 @@ asn1constraint_pullup(arg_t *arg) {
int
asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
+ unsigned int el;
int rvalue = 0;
int ret;
- int el;
if(!ct) return 0;
@@ -208,7 +208,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct,
static void
_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
- int i;
+ unsigned int i;
for(i = 0; i < ct->el_count; i++) {
if(ct->elements[i]->type == ACT_EL_EXT)
diff --git a/libasn1fix/asn1fix_crange.c b/libasn1fix/asn1fix_crange.c
index 6ef8c8ac..53d46407 100644
--- a/libasn1fix/asn1fix_crange.c
+++ b/libasn1fix/asn1fix_crange.c
@@ -699,8 +699,8 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
asn1p_value_t *vmin;
asn1p_value_t *vmax;
int expectation_met;
+ unsigned int i;
int ret;
- int i;
if(!exmet) {
exmet = &expectation_met;
diff --git a/libasn1fix/asn1fix_param.c b/libasn1fix/asn1fix_param.c
index c399ae42..5ce6b933 100644
--- a/libasn1fix/asn1fix_param.c
+++ b/libasn1fix/asn1fix_param.c
@@ -2,7 +2,10 @@
static int asn1f_parametrize(arg_t *arg, asn1p_expr_t *ex, asn1p_expr_t *ptype);
static int asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
+static int asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
+
static asn1p_expr_t *_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
+static int _process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
int
asn1f_fix_parametrized_assignment(arg_t *arg) {
@@ -79,6 +82,7 @@ asn1f_parametrize(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype) {
* as a child of the expression, replacing all occurences of
* symbols which are defined as parametrized type arguments
* with the actual values.
+ * 3. Don't forget to parametrize the subtype constraints.
*/
nex = asn1p_expr_clone(ptype, 0);
@@ -117,34 +121,40 @@ asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptyp
TQ_FOR(child, &(expr->members), next) {
asn1p_expr_t *ra;
- asn1p_expr_t *ne;
-
- ra = _referenced_argument(child->reference, ptype, actargs);
- if(ra == NULL) continue;
-
- DEBUG("Substituting parameter for %s %s at line %d",
- child->Identifier,
- asn1f_printable_reference(child->reference),
- child->_lineno
- );
+ asn1p_expr_t *ne; /* new expression (clone) */
- assert(child->meta_type == AMT_TYPEREF);
- assert(child->expr_type == A1TC_REFERENCE);
-
- ne = asn1p_expr_clone(ra, 0);
- if(ne == NULL) return -1;
- assert(ne->Identifier == 0);
- ne->Identifier = strdup(child->Identifier);
- if(ne->Identifier == 0) {
- asn1p_expr_free(ne);
+ if(asn1f_param_process_constraints(arg, child, ptype, actargs))
return -1;
+
+ ra = _referenced_argument(child->reference, ptype, actargs);
+ if(ra) {
+ DEBUG("Substituting parameter for %s %s at line %d",
+ child->Identifier,
+ asn1f_printable_reference(child->reference),
+ child->_lineno
+ );
+
+ assert(child->meta_type == AMT_TYPEREF);
+ assert(child->expr_type == A1TC_REFERENCE);
+
+ ne = asn1p_expr_clone(ra, 0);
+ if(ne == NULL) return -1;
+ assert(ne->Identifier == 0);
+ ne->Identifier = strdup(child->Identifier);
+ if(ne->Identifier == 0) {
+ asn1p_expr_free(ne);
+ return -1;
+ }
+ SUBSTITUTE(child, ne);
}
- SUBSTITUTE(child, ne);
}
return 0;
}
+/*
+ * Check that the given ref looks like an argument of a parametrized type.
+ */
static asn1p_expr_t *
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
asn1p_expr_t *aa;
@@ -163,3 +173,84 @@ _referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actarg
return NULL;
}
+
+/*
+ * Search for parameters inside constraints.
+ */
+static int
+asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
+ asn1p_constraint_t *cts;
+ int ret;
+
+ if(!expr->constraints) return 0;
+
+ cts = asn1p_constraint_clone(expr->constraints);
+ assert(cts);
+
+ ret = _process_constraints(arg, cts, ptype, actargs);
+ if(ret == 1) {
+ asn1p_constraint_free(expr->constraints);
+ expr->constraints = cts;
+ ret = 0;
+ } else {
+ asn1p_constraint_free(cts);
+ }
+
+ return ret;
+}
+
+static int
+_process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
+ asn1p_value_t *values[3];
+ int rvalue = 0;
+ size_t i;
+
+ values[0] = ct->value;
+ values[1] = ct->range_start;
+ values[2] = ct->range_stop;
+
+ for(i = 0; i < sizeof(values)/sizeof(values[0]); i++) {
+ asn1p_value_t *v = values[i];
+ asn1p_expr_t *ra;
+ asn1p_ref_t *ref;
+ char *str;
+
+ if(!v || v->type != ATV_REFERENCED) continue;
+
+ ref = v->value.reference;
+ ra = _referenced_argument(ref, ptype, actargs);
+ if(!ra) continue;
+
+ DEBUG("_process_constraints(%s), ra=%s",
+ asn1f_printable_reference(ref), ra->Identifier);
+
+ str = strdup(ra->Identifier);
+ if(!str) return -1;
+
+ assert(ref->comp_count == 1);
+ ref = asn1p_ref_new(ref->_lineno);
+ if(!ref) { free(str); return -1; }
+
+ if(asn1p_ref_add_component(ref, str, 0)) {
+ free(str);
+ return -1;
+ }
+
+ asn1p_ref_free(v->value.reference);
+ v->value.reference = ref;
+ rvalue = 1;
+ }
+
+ /* Process the rest of constraints recursively */
+ for(i = 0; i < ct->el_count; i++) {
+ int ret = _process_constraints(arg, ct->elements[i],
+ ptype, actargs);
+ if(ret == -1)
+ rvalue = -1;
+ else if(ret == 1 && rvalue != -1)
+ rvalue = 1;
+ }
+
+ return rvalue;
+}
+
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
index de80fad5..22ba422c 100644
--- a/libasn1fix/asn1fix_tags.c
+++ b/libasn1fix/asn1fix_tags.c
@@ -1,7 +1,7 @@
#include "asn1fix_internal.h"
int
-asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag) {
+asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int flags) {
int ret;
if(expr->tag.tag_class != TC_NOCLASS) {
@@ -19,6 +19,11 @@ asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct as
memset(tag, 0, sizeof(*tag));
tag->tag_class = TC_UNIVERSAL;
tag->tag_value = expr_type2uclass_value[expr->expr_type];
+ if(flags && expr->expr_type == ASN_TYPE_ANY) {
+ assert(tag->tag_value == 0);
+ tag->tag_value = -1;
+ return 0;
+ }
return (tag->tag_value == 0) ? -1 : 0;
}
@@ -37,7 +42,8 @@ asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct as
return -1;
expr->_mark |= TM_RECURSION;
- ret = asn1f_fetch_tag(asn, expr->module, expr, tag);
+ ret = asn1f_fetch_tag(asn, expr->module, expr, tag,
+ flags);
expr->_mark &= ~TM_RECURSION;
return ret;
}
diff --git a/libasn1fix/asn1fix_tags.h b/libasn1fix/asn1fix_tags.h
index 9d3595b9..429e56d7 100644
--- a/libasn1fix/asn1fix_tags.h
+++ b/libasn1fix/asn1fix_tags.h
@@ -1,6 +1,6 @@
#ifndef _ASN1FIX_TAGS_H_
#define _ASN1FIX_TAGS_H_
-int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag);
+int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int special_ANY_handling);
#endif /* _ASN1FIX_TAGS_H_ */