Commit b45e067b authored by Lev Walkin's avatar Lev Walkin

constraint groking code

parent 9095adab
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = -I${top_srcdir}/libasn1parser
AM_CPPFLAGS = \
-I$(top_srcdir)/libasn1parser \
-I$(top_srcdir)/libasn1cnst
noinst_LTLIBRARIES = libasn1fix.la
libasn1fix_la_LDFLAGS = -all-static
libasn1fix_la_SOURCES = \
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h
libasn1fix_la_LIBADD = ${top_builddir}/libasn1parser/libasn1parser.la
libasn1fix_la_SOURCES = \
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_constraint.c asn1fix_constraint.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_crange.c asn1fix_crange.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h \
asn1fix_constraint_compat.c
check_PROGRAMS = check_fixer
LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD}
DEPENDENCIES = ${LDADD}
check_fixer_LDADD = $(noinst_LTLIBRARIES) \
$(top_builddir)/libasn1cnst/libasn1cnst.la \
$(top_builddir)/libasn1parser/libasn1parser.la
check_fixer_DEPENDENCIES = $(check_fixer_LDADD)
TESTS_ENVIRONMENT= ./check_fixer
TESTS = ${top_srcdir}/tests/*.asn1
## TESTS = ${check_PROGRAMS} # This is an alternate form of testing
......@@ -50,21 +50,18 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libasn1fix_la_DEPENDENCIES = \
${top_builddir}/libasn1parser/libasn1parser.la
libasn1fix_la_LIBADD =
am_libasn1fix_la_OBJECTS = asn1fix.lo asn1fix_misc.lo asn1fix_value.lo \
asn1fix_compat.lo asn1fix_constr.lo asn1fix_cstring.lo \
asn1fix_retrieve.lo asn1fix_bitstring.lo asn1fix_integer.lo \
asn1fix_dereft.lo asn1fix_derefv.lo asn1fix_export.lo \
asn1fix_param.lo asn1fix_class.lo asn1fix_tags.lo \
asn1fix_enum.lo
asn1fix_retrieve.lo asn1fix_bitstring.lo asn1fix_constraint.lo \
asn1fix_integer.lo asn1fix_crange.lo asn1fix_dereft.lo \
asn1fix_derefv.lo asn1fix_export.lo asn1fix_param.lo \
asn1fix_class.lo asn1fix_tags.lo asn1fix_enum.lo \
asn1fix_constraint_compat.lo
libasn1fix_la_OBJECTS = $(am_libasn1fix_la_OBJECTS)
check_fixer_SOURCES = check_fixer.c
check_fixer_OBJECTS = check_fixer.$(OBJEXT)
check_fixer_LDADD = $(LDADD)
am__DEPENDENCIES_1 = libasn1fix.la
am__DEPENDENCIES_2 = ${top_builddir}/libasn1parser/libasn1parser.la
check_fixer_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
......@@ -73,6 +70,9 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_class.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_compat.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_constr.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_constraint.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_constraint_compat.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_crange.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_cstring.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_dereft.Plo \
@AMDEP_TRUE@ ./$(DEPDIR)/asn1fix_derefv.Plo \
......@@ -209,31 +209,39 @@ target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = -I${top_srcdir}/libasn1parser
AM_CPPFLAGS = \
-I$(top_srcdir)/libasn1parser \
-I$(top_srcdir)/libasn1cnst
noinst_LTLIBRARIES = libasn1fix.la
libasn1fix_la_LDFLAGS = -all-static
libasn1fix_la_SOURCES = \
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h
libasn1fix_la_LIBADD = ${top_builddir}/libasn1parser/libasn1parser.la
LDADD = ${noinst_LTLIBRARIES} ${libasn1fix_la_LIBADD}
DEPENDENCIES = ${LDADD}
asn1fix.c asn1fix.h \
asn1fix_internal.h \
asn1fix_misc.c asn1fix_misc.h \
asn1fix_value.c asn1fix_value.h \
asn1fix_compat.c asn1fix_compat.h \
asn1fix_constr.c asn1fix_constr.h \
asn1fix_cstring.c asn1fix_cstring.h \
asn1fix_retrieve.c asn1fix_retrieve.h \
asn1fix_bitstring.c asn1fix_bitstring.h \
asn1fix_constraint.c asn1fix_constraint.h \
asn1fix_integer.c asn1fix_integer.h \
asn1fix_crange.c asn1fix_crange.h \
asn1fix_dereft.c asn1fix_dereft.h \
asn1fix_derefv.c asn1fix_derefv.h \
asn1fix_export.c asn1fix_export.h \
asn1fix_param.c asn1fix_param.h \
asn1fix_class.c asn1fix_class.h \
asn1fix_tags.c asn1fix_tags.h \
asn1fix_enum.c asn1fix_enum.h \
asn1fix_constraint_compat.c
check_fixer_LDADD = $(noinst_LTLIBRARIES) \
$(top_builddir)/libasn1cnst/libasn1cnst.la \
$(top_builddir)/libasn1parser/libasn1parser.la
check_fixer_DEPENDENCIES = $(check_fixer_LDADD)
TESTS_ENVIRONMENT = ./check_fixer
TESTS = ${top_srcdir}/tests/*.asn1
all: all-am
......@@ -302,6 +310,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_class.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_compat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_constr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_constraint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_constraint_compat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_crange.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_cstring.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_dereft.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1fix_derefv.Plo@am__quote@
......
......@@ -17,6 +17,7 @@ static int asn1f_fix_simple(arg_t *arg); /* For INTEGER/ENUMERATED */
static int asn1f_fix_constructed(arg_t *arg); /* For SEQUENCE/SET/CHOICE */
static int asn1f_fix_constraints(arg_t *arg); /* For subtype constraints */
arg_t a1f_replace_me_with_proper_interface_arg;
/*
* Scan every module defined here in search for inconsistences.
......@@ -53,6 +54,8 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
flags &= ~A1F_DEBUG;
}
a1f_replace_me_with_proper_interface_arg = arg;
/*
* Check that we haven't missed an unknown flag.
*/
......@@ -74,6 +77,8 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
if(ret == 1) warnings++;
}
memset(&a1f_replace_me_with_proper_interface_arg, 0, sizeof(arg_t));
/*
* Compute a return value.
*/
......@@ -88,8 +93,7 @@ asn1f_fix_module(arg_t *arg) {
asn1p_expr_t *expr;
int rvalue = 0;
switch((arg->mod->module_flags
& (MSF_EXPLICIT_TAGS | MSF_IMPLICIT_TAGS | MSF_AUTOMATIC_TAGS))) {
switch((arg->mod->module_flags & MSF_MASK_TAGS)) {
case MSF_NOFLAGS:
case MSF_EXPLICIT_TAGS:
case MSF_IMPLICIT_TAGS:
......@@ -101,6 +105,24 @@ asn1f_fix_module(arg_t *arg) {
RET2RVAL(-1, rvalue);
}
switch((arg->mod->module_flags & MSF_MASK_INSTRUCTIONS)) {
case MSF_NOFLAGS:
//arg->mod->module_flags |= MSF_TAG_INSTRUCTIONS;
break;
case MSF_unk_INSTRUCTIONS:
WARNING("Module %s defined with unrecognized "
"encoding reference", arg->mod->Identifier);
RET2RVAL(1, rvalue);
/* Fall through */
case MSF_TAG_INSTRUCTIONS:
case MSF_XER_INSTRUCTIONS:
break;
default:
FATAL("Module %s defined with ambiguous encoding reference",
arg->mod->Identifier);
RET2RVAL(-1, rvalue);
}
/*
* Do various non-recursive transformations.
* Order is not important.
......@@ -249,86 +271,34 @@ asn1f_fix_constructed(arg_t *arg) {
}
static int
_constraint_value_resolve(arg_t *arg, asn1p_value_t **value) {
asn1p_expr_t expr;
asn1p_expr_t *tmp_expr;
asn1p_module_t *tmp_mod;
asn1p_module_t *mod_r = NULL;
asn1f_fix_constraints(arg_t *arg) {
asn1p_expr_t *top_parent;
int rvalue = 0;
int ret;
tmp_expr = asn1f_lookup_symbol(arg, (*value)->value.reference, &mod_r);
if(tmp_expr == NULL) {
FATAL("Cannot find symbol %s "
"used in %s subtype constraint at line %d",
asn1f_printable_reference((*value)->value.reference),
arg->expr->Identifier, arg->expr->_lineno);
assert((*value)->type == ATV_REFERENCED);
return -1;
}
memset(&expr, 0, sizeof(expr));
expr.meta_type = tmp_expr->meta_type;
expr.expr_type = tmp_expr->expr_type;
expr.Identifier = tmp_expr->Identifier;
expr.value = *value;
tmp_expr = arg->expr;
tmp_mod = arg->mod;
arg->expr = &expr;
arg->mod = mod_r;
ret = asn1f_fix_dereference_values(arg);
ret = asn1constraint_resolve(arg, arg->expr->constraints);
RET2RVAL(ret, rvalue);
arg->expr = tmp_expr;
arg->mod = tmp_mod;
assert(expr.value);
*value = expr.value;
return rvalue;
}
static int
_resolve_constraints(arg_t *arg, asn1p_constraint_t *ct) {
int rvalue = 0;
int ret;
int el;
/* Don't touch information object classes */
if(ct->type == ACT_CT_WCOMP
|| ct->type == ACT_CT_WCOMPS
|| ct->type == ACT_CA_CRC)
return 0;
if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->value);
RET2RVAL(ret, rvalue);
}
if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_start);
RET2RVAL(ret, rvalue);
}
if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_stop);
RET2RVAL(ret, rvalue);
}
for(el = 0; el < ct->el_count; el++) {
ret = _resolve_constraints(arg, ct->elements[el]);
RET2RVAL(ret, rvalue);
}
return rvalue;
}
static int
asn1f_fix_constraints(arg_t *arg) {
int rvalue = 0;
int ret;
ret = asn1constraint_pullup(arg);
RET2RVAL(ret, rvalue);
if(arg->expr->constraints) {
ret = _resolve_constraints(arg, arg->expr->constraints);
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 };
unsigned int i;
for(i = 0; i < sizeof(test_types)/sizeof(test_types[0]); i++) {
asn1cnst_range_t *range;
range = asn1constraint_compute_PER_range(
top_parent->expr_type,
arg->expr->combined_constraints,
test_types[i], 0, 0);
if(!range && errno == EPERM)
return -1;
asn1constraint_range_free(range);
}
}
return rvalue;
}
......
......@@ -12,7 +12,7 @@
*/
enum asn1f_flags {
A1F_NOFLAGS,
A1F_DEBUG, /* Print debugging output using (_is_fatal = -1) */
A1F_DEBUG = 0x01, /* Print debugging output */
};
/*
......
#include <asn1fix_internal.h>
#include <asn1fix_constraint.h>
#include <asn1fix_crange.h>
static void _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct);
static int _constraint_value_resolve(arg_t *arg, asn1p_value_t **value);
int
asn1constraint_pullup(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_constraint_t *ct_parent;
asn1p_constraint_t *ct_expr;
int ret;
if(expr->combined_constraints)
return 0; /* Operation already performed earlier */
switch(expr->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
break;
default:
return 0; /* Nothing to do */
}
if(expr->expr_type == A1TC_REFERENCE) {
asn1p_ref_t *ref = expr->reference;
asn1p_module_t *mod_rw = arg->mod;
asn1p_expr_t *parent_expr;
assert(ref);
parent_expr = asn1f_lookup_symbol(arg, ref, &mod_rw);
if(!parent_expr) {
if(errno != EEXIST) {
DEBUG("\tWhile fetching parent constraints: "
"type \"%s\" not found: %s",
asn1f_printable_reference(ref),
strerror(errno));
return -1;
} else {
/*
* -fknown-extern-type is given.
* Assume there are no constraints there.
*/
WARNING("External type \"%s\": "
"assuming no constraints",
asn1f_printable_reference(ref));
ct_parent = 0;
}
} else {
arg->expr = parent_expr;
ret = asn1constraint_pullup(arg);
arg->expr = expr;
if(ret) return ret;
ct_parent = parent_expr->combined_constraints;
}
} else {
ct_parent = 0;
}
ct_expr = expr->constraints;
if(!ct_parent && !ct_expr)
return 0; /* No constraints to consider */
if(ct_parent) {
ct_parent = asn1p_constraint_clone(ct_parent);
assert(ct_parent);
}
/*
* If the current type does not have constraints, it inherits
* the constraints of a parent.
*/
if(ct_parent && !ct_expr) {
expr->combined_constraints = ct_parent;
return 0;
}
ct_expr = asn1p_constraint_clone(ct_expr);
assert(ct_expr);
/*
* Now we have a set of current expression's constraints,
* and an optional set of the parent expression's constraints.
*/
if(ct_parent) {
/*
* If we have a parent, remove all the extensions (46.4).
*/
_remove_exceptions(arg, ct_parent);
expr->combined_constraints = ct_parent;
if(ct_expr->type == ACT_CA_SET) {
int i;
for(i = 0; i < ct_expr->el_count; i++) {
if(asn1p_constraint_insert(
expr->combined_constraints,
ct_expr->elements[i])) {
expr->combined_constraints = 0;
asn1p_constraint_free(ct_expr);
asn1p_constraint_free(ct_parent);
return -1;
} else {
ct_expr->elements[i] = 0;
}
}
asn1p_constraint_free(ct_expr);
} else {
asn1p_constraint_insert(expr->combined_constraints,
ct_expr);
}
} else {
expr->combined_constraints = ct_expr;
}
return 0;
}
int
asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) {
asn1p_expr_t *top_parent;
int rvalue = 0;
int ret;
int el;
if(!ct) return 0;
/* Don't touch information object classes */
switch(ct->type) {
case ACT_CT_WCOMP:
case ACT_CT_WCOMPS:
case ACT_CA_CRC:
return 0;
default:
break;
}
top_parent = asn1f_find_terminal_type(arg, arg->expr, 0);
if(top_parent) {
ret = asn1constraint_compatible(top_parent->expr_type,
ct->type);
switch(ret) {
case -1: /* If unknown, assume OK. */
case 1:
break;
case 0:
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)
);
rvalue = -1;
break;
}
} else {
WARNING("%s at line %d: "
"Constraints ignored: Unresolved parent type",
arg->expr->Identifier, arg->expr->_lineno);
}
if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->value);
RET2RVAL(ret, rvalue);
}
if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_start);
RET2RVAL(ret, rvalue);
}
if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->range_stop);
RET2RVAL(ret, rvalue);
}
for(el = 0; el < ct->el_count; el++) {
ret = asn1constraint_resolve(arg, ct->elements[el]);
RET2RVAL(ret, rvalue);
}
return rvalue;
}
static void
_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
int i;
for(i = 0; i < ct->el_count; i++) {
if(ct->elements[i]->type == ACT_EL_EXT)
break;
_remove_exceptions(arg, ct->elements[i]);
}
/* Remove the elements at and after the extensibility mark */
for(; i < ct->el_count; ct->el_count--) {
asn1p_constraint_t *rm;
rm = ct->elements[ct->el_count-1];
asn1p_constraint_free(rm);
}
if(i < ct->el_size)
ct->elements[i] = 0;
}
static int
_constraint_value_resolve(arg_t *arg, asn1p_value_t **value) {
asn1p_expr_t static_expr;
asn1p_expr_t *tmp_expr;
asn1p_module_t *mod_rw = arg->mod;
arg_t tmp_arg;
int rvalue = 0;
int ret;
tmp_expr = asn1f_lookup_symbol(arg, (*value)->value.reference, &mod_rw);
if(tmp_expr == NULL) {
FATAL("Cannot find symbol %s "
"used in %s subtype constraint at line %d",
asn1f_printable_reference((*value)->value.reference),
arg->expr->Identifier, arg->expr->_lineno);
assert((*value)->type == ATV_REFERENCED);
return -1;
}
static_expr = *tmp_expr;
static_expr.value = *value;
tmp_arg = *arg;
tmp_arg.mod = mod_rw;
tmp_arg.expr = &static_expr;
ret = asn1f_fix_dereference_values(&tmp_arg);
RET2RVAL(ret, rvalue);
assert(static_expr.value);
*value = static_expr.value;
return rvalue;
}
#ifndef _ASN1FIX_CONSTRAINT_H_
#define _ASN1FIX_CONSTRAINT_H_
/*
* Resolve referenced values inside constraints.
*/
int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct);
/*
* Collect all subtype constraints from all parents of this type and
* the type itself, forming a full constraint structure.
* Honors the constraints extensibility rules (46.8)
* and does other useful transformations.
*/
int asn1constraint_pullup(arg_t *arg);
#endif /* _ASN1FIX_CONSTRAINT_H_ */
#include <asn1fix_internal.h>
#include <asn1fix_crange.h>
/*
* Check that a specific constraint is compatible
* with the given expression type.
*/
int
asn1constraint_compatible(asn1p_expr_type_e expr_type,
enum asn1p_constraint_type_e constr_type) {
/*
* X.680-0207, Table 9.
*/
switch(constr_type) {
case ACT_INVALID:
return 0;
case ACT_EL_VALUE:
return 1;
case ACT_EL_RANGE:
case ACT_EL_LLRANGE:
case ACT_EL_RLRANGE:
case ACT_EL_ULRANGE:
switch(expr_type) {
case ASN_BASIC_ENUMERATED:
case ASN_BASIC_BOOLEAN:
/*
* The ValueRange constraint is not formally
* applicable to the above types. However, we
* support it just fine.
*/
/* Fall through */
case ASN_BASIC_INTEGER:
case ASN_BASIC_REAL:
return 1;
default:
if(expr_type & ASN_STRING_MASK)
return 1;
}
return 0;
case ACT_EL_EXT:
return -1;
case ACT_CT_FROM:
if(expr_type & ASN_STRING_MASK)
return 1;
return 0;
case ACT_CT_SIZE:
switch(expr_type) {
case ASN_BASIC_BIT_STRING:
case ASN_BASIC_OCTET_STRING:
case ASN_BASIC_CHARACTER_STRING:
case ASN_CONSTR_SEQUENCE_OF:
case ASN_CONSTR_SET_OF:
return 1;
default:
if(expr_type & ASN_STRING_MASK)
return 1;
}
return 0;
case ACT_CT_WCOMP:
case ACT_CT_WCOMPS:
switch(expr_type) {
case A1TC_INSTANCE:
case ASN_BASIC_EXTERNAL:
case ASN_BASIC_EMBEDDED_PDV:
case ASN_BASIC_REAL:
case ASN_BASIC_CHARACTER_STRING:
case ASN_CONSTR_CHOICE:
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SEQUENCE_OF:
case ASN_CONSTR_SET:
case ASN_CONSTR_SET_OF:
return 1;
default: break;
}
return 0;
case ACT_CA_SET:
case ACT_CA_CRC:
case ACT_CA_CSV:
case ACT_CA_UNI:
case ACT_CA_INT:
case ACT_CA_EXC:
return 1;
}
return -1;
}
#define DECL(foo, val1, val2) \
static asn1cnst_range_t range_ ## foo = { \
{ ARE_VALUE, 0, val1 }, \
{ ARE_VALUE, 0, val2 }, \
0, 0, 0, 0, 0, 0 };
asn1cnst_range_t *
asn1constraint_default_alphabet(asn1p_expr_type_e expr_type) {
DECL(uint7, 0x00, 0x7f);
DECL(uint8, 0x00, 0xff);
DECL(Space, 0x20, 0x20);
DECL(ApostropheAndParens, 0x27, 0x29);
DECL(PlusTillColon, 0x2b, 0x3a);
DECL(Equal, 0x3d, 0x3d);
DECL(QuestionMark, 0x3f, 0x3f);
DECL(Digits, 0x30, 0x39);
DECL(AlphaCap, 0x41, 0x5a);
DECL(AlphaLow, 0x61, 0x7a);
DECL(PlusCommaMinusDot, 0x2b, 0x2e);
DECL(Plus, 0x2b, 0x2b);
DECL(MinusDot, 0x2d, 0x2e);
DECL(Z, 0x5a, 0x5a);
static asn1cnst_range_t *range_NumericString_array[] = {
&range_Space, &range_Digits };
static asn1cnst_range_t *range_PrintableString_array[] = {
&range_Space,
&range_ApostropheAndParens,
&range_PlusTillColon,
&range_Equal,
&range_QuestionMark,
&range_AlphaCap,
&range_AlphaLow
};
static asn1cnst_range_t *range_UTCTime_array[] = {
&range_Plus, &range_MinusDot, &range_Digits, &range_Z };
static asn1cnst_range_t *range_GeneralizedTime_array[] = {
&range_PlusCommaMinusDot, &range_Digits, &range_Z };
static asn1cnst_range_t range_NumericString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x39 },
range_NumericString_array,
sizeof(range_NumericString_array)
/sizeof(range_NumericString_array[0]),
0, 0, 0, 0 };
static asn1cnst_range_t range_PrintableString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x7a },
range_PrintableString_array,
sizeof(range_PrintableString_array)
/sizeof(range_PrintableString_array[0]),
0, 0, 0, 0 };
static asn1cnst_range_t range_VisibleString = {
{ ARE_VALUE, 0, 0x20 },
{ ARE_VALUE, 0, 0x7e },
0, 0, 0, 0, 0, 0 };
static asn1cnst_range_t range_UTCTime = {
{ ARE_VALUE, 0, 0x2b },
{ ARE_VALUE, 0, 0x5a },
range_UTCTime_array,
sizeof(range_UTCTime_array)
/sizeof(range_UTCTime_array[0]),
0, 0, 0, 0 };
static asn1cnst_range_t range_GeneralizedTime = {
{ ARE_VALUE, 0, 0x2b },
{ ARE_VALUE, 0, 0x5a },
range_GeneralizedTime_array,
sizeof(range_GeneralizedTime_array)
/sizeof(range_GeneralizedTime_array[0]),
0, 0, 0, 0 };
switch(expr_type) {
case ASN_STRING_NumericString:
return &range_NumericString;
case ASN_STRING_PrintableString:
return &range_PrintableString;
case ASN_STRING_VisibleString:
return &range_VisibleString;
case ASN_STRING_IA5String:
return &range_uint7;
case ASN_BASIC_OCTET_STRING:
return &range_uint8;
case ASN_BASIC_UTCTime:
return &range_UTCTime;
case ASN_BASIC_GeneralizedTime:
return &range_GeneralizedTime;
default:
break;
}
return NULL;
}
This diff is collapsed.
#ifndef ASN1FIX_CRANGE_H
#define ASN1FIX_CRANGE_H
typedef struct asn1cnst_edge_s {
enum asn1cnst_range_edge {
ARE_MIN,
ARE_MAX,
ARE_VALUE,
} type;
int lineno; /* Line where the corresponding token was found */
asn1_integer_t value; /* Value when type is ARE_VALUE */
} asn1cnst_edge_t;
typedef struct asn1cnst_range_s {
asn1cnst_edge_t left; /* MIN from (MIN..10) */
asn1cnst_edge_t right; /* 10 from (MIN..10) */
/* If range is split in parts, these are the parts */
struct asn1cnst_range_s **elements;
int el_count;
int el_size;
int empty_constraint; /* If yes, too bad. */
int extensible; /* Extension marker (...) present. */
int not_PER_visible; /* Contains non PER-visible components */
} asn1cnst_range_t;
/*
* Compute the PER-visible constraint range.
*
* (expr_type) must have the type of the top-level parent ASN.1 type.
* (required_type) must be one of ACT_EL_RANGE, ACT_CT_SIZE or ACT_CT_FROM.
* (minmax) and (expectation_met) should be 0.
* ERRORS:
* EINVAL: Mandatory arguments missing.
* ENOMEM: Memory allocation failure.
* EPERM: Invalid constraint reference.
*/
asn1cnst_range_t *asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type,
const asn1p_constraint_t *ct,
enum asn1p_constraint_type_e required_type,
const asn1cnst_range_t *minmax,
int *expectation_met);
void asn1constraint_range_free(asn1cnst_range_t *);
/*
* Check that a specific constraint is compatible
* with the given expression type.
*/
int asn1constraint_compatible(asn1p_expr_type_e expr_type,
enum asn1p_constraint_type_e constr_type);
/*
* Fetch a default alphabet for this type.
*/
asn1cnst_range_t *asn1constraint_default_alphabet(asn1p_expr_type_e expr_type);
#endif /* ASN1FIX_CRANGE_H */
#include "asn1fix_internal.h"
#include "asn1fix_export.h"
extern arg_t a1f_replace_me_with_proper_interface_arg;
asn1p_expr_t *
asn1f_lookup_symbol_ex(
asn1p_t *asn,
......@@ -14,6 +17,9 @@ asn1f_lookup_symbol_ex(
arg.asn = asn;
arg.mod = *module_rw;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_lookup_symbol(&arg, ref, module_rw);
}
......@@ -24,11 +30,15 @@ asn1f_class_access_ex(asn1p_t *asn,
asn1p_expr_t *expr,
asn1p_ref_t *ref,
asn1p_module_t **mod_r) {
static arg_t arg;
arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_class_access(&arg, ref, mod_r);
}
......@@ -38,11 +48,32 @@ asn1f_find_terminal_type_ex(asn1p_t *asn,
asn1p_module_t *mod,
asn1p_expr_t *expr,
asn1p_module_t **mod_r) {
static arg_t arg;
arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_find_terminal_type(&arg, expr, mod_r);
}
int
asn1f_fix_dereference_values_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *expr) {
arg_t arg;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_fix_dereference_values(&arg);
}
......@@ -7,6 +7,12 @@
#include <asn1fix_tags.h>
/*
* Create a human-readable representation of a reference and value.
*/
char const *asn1f_printable_reference(asn1p_ref_t *ref);
char const *asn1f_printable_value(asn1p_value_t *value);
/*
* Exportable version of an asn1f_lookup_symbol().
*/
......@@ -28,5 +34,10 @@ asn1p_expr_t *asn1f_class_access_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *asn1f_find_terminal_type_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *tc, asn1p_module_t **opt_module_r);
#endif /* _ASN1FIX_EXPORT_H_ */
/*
* Exportable version of asn1f_fix_dereference_values();
*/
int asn1f_fix_dereference_values_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *expr);
#endif /* _ASN1FIX_EXPORT_H_ */
......@@ -16,6 +16,7 @@
#include <assert.h>
#include <asn1parser.h> /* Our lovely ASN.1 parser module */
#include <asn1fix.h>
/*
* A definition of a function that will log error messages.
......@@ -32,6 +33,7 @@ typedef struct arg_s {
error_logger_f eh;
error_logger_f debug;
void *key; /* The next level key */
enum asn1f_flags flags;
} arg_t;
/*
......@@ -51,6 +53,9 @@ typedef struct arg_s {
#include "asn1fix_dereft.h" /* Dereference types */
#include "asn1fix_derefv.h" /* Dereference values */
#include "asn1fix_tags.h" /* Tags-related stuff */
#include "asn1fix_constraint.h" /* Constraint manipulation */
#include "asn1fix_crange.h" /* Constraint groking, exportable */
#include "asn1fix_export.h" /* Exported functions */
/*
......
......@@ -4,18 +4,6 @@
#ifndef _ASN1FIX_MISC_H_
#define _ASN1FIX_MISC_H_
/*
* Return a pointer to the locally held string with human-readable
* definition of the value.
*/
char const *asn1f_printable_value(asn1p_value_t *);
/*
* Return a pointer to the locally held string with human-readable
* definition of the reference.
*/
char const *asn1f_printable_reference(asn1p_ref_t *);
/*
* Recursively invoke a given function over the given expr and all its
* children.
......
......@@ -21,6 +21,7 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) {
* 1. Find the terminal type for this assignment.
*/
type_expr = asn1f_find_terminal_type(arg, expr, 0);
DEBUG("%s(): terminal type %p", __func__, type_expr);
if(type_expr == 0) {
DEBUG("\tTerminal type for %s not found", expr->Identifier);
return -1;
......
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