Commit 5045dfab authored by Lev Walkin's avatar Lev Walkin
Browse files

ObjectSets

parent 1775697d
......@@ -12,7 +12,7 @@
0.9.20: 2006-Mar-06
* SET OF CHOICE, SEQUENCE OF CHOICE and a certain named S/O types
are represented differently in XER. THIS IS AN ICOMPATIBLE CHANGE.
are represented differently in XER. THIS IS AN INCOMPATIBLE CHANGE.
(Test case 70) (Severity: low; Security impact: low)
* asn1c: Removed -ftypes88 command line option.
* Started PER implementation. Somewhat experimental!
......
......@@ -195,7 +195,6 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_type_e ety
* Resolve all possible references, wherever they occur.
*/
if(ct->containedSubtype) {
assert(ct->containedSubtype->type == ATV_REFERENCED);
ret = constraint_type_resolve(arg, ct);
RET2RVAL(ret, rvalue);
}
......@@ -250,60 +249,68 @@ _remove_extensions(arg_t *arg, asn1p_constraint_t *ct) {
static int
constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
asn1p_expr_t *rtype;
arg_t tmparg;
asn1p_constraint_t *ct_expr;
int ret;
DEBUG("(\"%s\")", asn1f_printable_value(ct->containedSubtype));
assert(ct->containedSubtype->type == ATV_REFERENCED);
if(ct->containedSubtype->type == ATV_VALUESET) {
ct_expr = ct->containedSubtype->value.constraint;
DEBUG("Found %s in constraints", "ValueSet");
} else if(ct->containedSubtype->type == ATV_REFERENCED) {
asn1p_expr_t *rtype;
arg_t tmparg;
rtype = asn1f_lookup_symbol(arg, arg->expr->module,
arg->expr->rhs_pspecs,
ct->containedSubtype->value.reference);
if(!rtype) {
FATAL("Cannot find type \"%s\" in constraints "
"at line %d",
asn1f_printable_value(ct->containedSubtype),
ct->_lineno);
return -1;
}
rtype = asn1f_lookup_symbol(arg, arg->expr->module,
arg->expr->rhs_pspecs,
ct->containedSubtype->value.reference);
if(!rtype) {
FATAL("Cannot find type \"%s\" in constraints at line %d",
asn1f_printable_value(ct->containedSubtype),
ct->_lineno);
tmparg = *arg;
tmparg.expr = rtype;
tmparg.mod = rtype->module;
ret = asn1constraint_pullup(&tmparg);
if(ret) return ret;
ct_expr = rtype->combined_constraints;
if(!ct_expr) return 0;
} else {
FATAL("Unsupported feature at line %d", ct->_lineno);
return -1;
}
ct_expr = asn1p_constraint_clone(ct_expr);
assert(ct_expr);
tmparg = *arg;
tmparg.expr = rtype;
tmparg.mod = rtype->module;
ret = asn1constraint_pullup(&tmparg);
if(ret) return ret;
if(rtype->combined_constraints) {
asn1p_constraint_t *ct_expr;
ct_expr = asn1p_constraint_clone(rtype->combined_constraints);
assert(ct_expr);
_remove_extensions(arg, ct_expr);
_remove_extensions(arg, ct_expr);
if(ct_expr->type == ACT_CA_SET) {
unsigned int i;
for(i = 0; i < ct_expr->el_count; i++) {
if(asn1p_constraint_insert(
ct, ct_expr->elements[i])) {
asn1p_constraint_free(ct_expr);
return -1;
} else {
ct_expr->elements[i] = 0;
}
if(ct_expr->type == ACT_CA_SET) {
unsigned int i;
for(i = 0; i < ct_expr->el_count; i++) {
if(asn1p_constraint_insert(
ct, ct_expr->elements[i])) {
asn1p_constraint_free(ct_expr);
return -1;
} else {
ct_expr->elements[i] = 0;
}
asn1p_constraint_free(ct_expr);
} else {
ret = asn1p_constraint_insert(ct, ct_expr);
assert(ret == 0);
}
ct->type = ACT_CA_SET;
asn1p_value_free(ct->containedSubtype);
ct->containedSubtype = NULL;
asn1p_constraint_free(ct_expr);
} else {
ret = asn1p_constraint_insert(ct, ct_expr);
assert(ret == 0);
}
ct->type = ACT_CA_SET;
asn1p_value_free(ct->containedSubtype);
ct->containedSubtype = NULL;
return 0;
}
......
......@@ -160,6 +160,8 @@ asn1f_printable_value(asn1p_value_t *v) {
assert(reflen == (size_t)(ptr - managedptr));
return managedptr;
}
case ATV_VALUESET:
return "<ValueSet>";
case ATV_CHOICE_IDENTIFIER:
{
char *cid = v->value.choice_identifier.identifier;
......
......@@ -133,9 +133,11 @@ resolve_expr(asn1p_expr_t *expr_to_resolve, void *resolver_arg) {
return NULL;
}
DEBUG("Found target %s", expr->Identifier);
DEBUG("Found target %s (%d/%x)",
expr->Identifier, expr->meta_type, expr->expr_type);
if(expr->meta_type == AMT_TYPE
|| expr->meta_type == AMT_VALUE) {
|| expr->meta_type == AMT_VALUE
|| expr->meta_type == AMT_VALUESET) {
DEBUG("Target is a simple type %s",
ASN_EXPR_TYPE2STR(expr->expr_type));
nex = asn1p_expr_clone(expr, 0);
......@@ -144,8 +146,10 @@ resolve_expr(asn1p_expr_t *expr_to_resolve, void *resolver_arg) {
? strdup(expr_to_resolve->Identifier) : 0;
return nex;
} else {
FATAL("Feature not implemented for %s",
rarg->original_expr->Identifier);
FATAL("Feature not implemented for %s (%d/%x), "
"please contact the asn1c author",
rarg->original_expr->Identifier,
expr->meta_type, expr->expr_type);
errno = EPERM;
return NULL;
}
......
......@@ -176,16 +176,31 @@ value_resolver(asn1p_value_t *value, void *rarg) {
if(!target)
return NULL; /* errno's are compatible */
if(!target->value) {
fprintf(stderr,
"FATAL: Parameterization did not resolve value reference "
"at line %d", ref->_lineno);
asn1p_expr_free(target);
if(target->meta_type == AMT_VALUE) {
if(!target->value) {
fprintf(stderr,
"FATAL: Parameterization did not resolve "
"value reference at line %d\n", ref->_lineno);
asn1p_expr_free(target);
errno = EPERM;
return NULL;
}
cval = asn1p_value_clone(target->value);
} else if(target->meta_type == AMT_VALUESET) {
if(!target->constraints) {
fprintf(stderr,
"FATAL: Parameterization did not resolve "
"value set reference at line %d\n", ref->_lineno);
asn1p_expr_free(target);
errno = EPERM;
return NULL;
}
cval = asn1p_value_fromconstr(target->constraints, 1);
} else {
errno = EPERM;
return NULL;
cval = NULL;
}
cval = asn1p_value_clone(target->value);
asn1p_expr_free(target);
return cval;
}
......
......@@ -29,6 +29,30 @@ asn1p_value_fromref(asn1p_ref_t *ref, int do_copy) {
}
}
asn1p_value_t *
asn1p_value_fromconstr(asn1p_constraint_t *ct, int do_copy) {
if(ct) {
asn1p_value_t *v = calloc(1, sizeof *v);
if(v) {
if(do_copy) {
v->value.constraint
= asn1p_constraint_clone(ct);
if(v->value.constraint == NULL) {
free(v);
return NULL;
}
} else {
v->value.constraint = ct;
}
v->type = ATV_VALUESET;
}
return v;
} else {
errno = EINVAL;
return NULL;
}
}
asn1p_value_t *
asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
if(bits) {
......@@ -155,6 +179,13 @@ asn1p_value_clone_with_resolver(asn1p_value_t *v,
else if(errno != ESRCH) return NULL;
}
return asn1p_value_fromref(v->value.reference, 1);
case ATV_VALUESET:
if(resolver) {
clone = resolver(v, rarg);
if(clone) return clone;
else if(errno != ESRCH) return NULL;
}
return asn1p_value_fromconstr(v->value.constraint, 1);
case ATV_CHOICE_IDENTIFIER: {
char *id = v->value.choice_identifier.identifier;
clone = calloc(1, sizeof(*clone));
......@@ -204,6 +235,9 @@ asn1p_value_free(asn1p_value_t *v) {
case ATV_REFERENCED:
asn1p_ref_free(v->value.reference);
break;
case ATV_VALUESET:
asn1p_constraint_free(v->value.constraint);
break;
case ATV_CHOICE_IDENTIFIER:
free(v->value.choice_identifier.identifier);
asn1p_value_free(v->value.choice_identifier.value);
......
......@@ -4,6 +4,8 @@
#ifndef ASN1_PARSER_VALUE_H
#define ASN1_PARSER_VALUE_H
struct asn1p_constraint_s; /* Forward declaration */
/*
* A wrapper around various kinds of values.
*/
......@@ -25,11 +27,13 @@ typedef struct asn1p_value_s {
ATV_STRING, /* "abcdef" */
ATV_UNPARSED,
ATV_BITVECTOR,
ATV_VALUESET, /* { 1 | 2 | 3 } */
ATV_REFERENCED, /* Reference to a value defined elsewhere */
ATV_CHOICE_IDENTIFIER, /* ChoiceIdentifier value */
} type; /* Value type and location */
union {
struct asn1p_constraint_s *constraint; /* ValueSet */
asn1p_ref_t *reference;
asn1c_integer_t v_integer;
double v_double;
......@@ -59,6 +63,7 @@ typedef struct asn1p_value_s {
*/
void asn1p_value_free(asn1p_value_t *);
asn1p_value_t *asn1p_value_fromref(asn1p_ref_t *ref, int do_copy);
asn1p_value_t *asn1p_value_fromconstr(struct asn1p_constraint_s *ct, int dc);
asn1p_value_t *asn1p_value_frombits(uint8_t *bits, int size_in_bits, int dc);
asn1p_value_t *asn1p_value_frombuf(char *buffer, int size, int do_copy);
asn1p_value_t *asn1p_value_fromdouble(double);
......
This diff is collapsed.
......@@ -272,8 +272,8 @@ static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
%type <tv_str> optIdentifier
%type <a_parg> ParameterArgumentName
%type <a_plist> ParameterArgumentList
%type <a_expr> Specialization
%type <a_expr> Specializations
%type <a_expr> ActualParameter
%type <a_expr> ActualParameterList
%type <a_aid> AssignedIdentifier /* OID/DefinedValue */
%type <a_oid> ObjectIdentifier /* OID */
%type <a_oid> optObjectIdentifier /* Optional OID */
......@@ -747,9 +747,9 @@ DefinedType:
$$->meta_type = AMT_TYPEREF;
}
/*
* A parametrized assignment.
* A parameterized assignment.
*/
| ComplexTypeReference '{' Specializations '}' {
| ComplexTypeReference '{' ActualParameterList '}' {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
$$->reference = $1;
......@@ -782,7 +782,7 @@ DataTypeReference:
assert($$->meta_type == AMT_OBJECTCLASS);
}
/*
* Parametrized <Type> declaration:
* Parameterized <Type> declaration:
* === EXAMPLE ===
* SIGNED { ToBeSigned } ::= SEQUENCE {
* toBeSigned ToBeSigned,
......@@ -793,7 +793,12 @@ DataTypeReference:
*/
| TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
$$ = $6;
assert($$->Identifier == 0);
$$->Identifier = $1;
$$->lhs_params = $3;
}
/* Parameterized CLASS declaration */
| TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ ObjectClass {
$$ = $6;
$$->Identifier = $1;
$$->lhs_params = $3;
}
......@@ -846,21 +851,29 @@ ParameterArgumentName:
checkmem(ret == 0);
$$.argument = $3;
}
| BasicTypeId ':' TypeRefName {
int ret;
$$.governor = asn1p_ref_new(yylineno);
ret = asn1p_ref_add_component($$.governor,
ASN_EXPR_TYPE2STR($1), 1);
checkmem(ret == 0);
$$.argument = $3;
}
;
Specializations:
Specialization {
ActualParameterList:
ActualParameter {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
asn1p_expr_add($$, $1);
}
| Specializations ',' Specialization {
| ActualParameterList ',' ActualParameter {
$$ = $1;
asn1p_expr_add($$, $3);
}
;
Specialization:
ActualParameter:
Type {
$$ = $1;
}
......@@ -883,10 +896,16 @@ Specialization:
asn1p_ref_add_component(ref, $1, RLT_lowercase);
$$->value = asn1p_value_fromref(ref, 0);
}
| ValueSet {
$$ = asn1p_expr_new(yylineno);
$$->expr_type = A1TC_VALUESET;
$$->meta_type = AMT_VALUESET;
$$->constraints = $1;
}
;
/*
| '{' Specialization '}' {
| '{' ActualParameter '}' {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
asn1p_expr_add($$, $2);
......@@ -1255,7 +1274,6 @@ TypeDeclarationSet:
$$->expr_type = ASN_TYPE_ANY;
$$->meta_type = AMT_TYPE;
}
| TOK_INSTANCE TOK_OF ComplexTypeReference {
$$ = asn1p_expr_new(yylineno);
checkmem($$);
......@@ -1674,7 +1692,11 @@ SetOfConstraints:
;
ElementSetSpecs:
ElementSetSpec {
TOK_ThreeDots {
$$ = asn1p_constraint_new(yylineno);
$$->type = ACT_EL_EXT;
}
| ElementSetSpec {
$$ = $1;
}
| ElementSetSpec ',' TOK_ThreeDots {
......
......@@ -259,6 +259,8 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
}
case ATV_REFERENCED:
return asn1print_ref(val->value.reference, flags);
case ATV_VALUESET:
return asn1print_constraint(val->value.constraint, flags);
case ATV_CHOICE_IDENTIFIER:
printf("%s: ", val->value.choice_identifier.identifier);
return asn1print_value(val->value.choice_identifier.value, flags);
......@@ -280,7 +282,7 @@ asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
switch(ct->type) {
case ACT_EL_TYPE:
asn1print_value(ct->value, flags);
asn1print_value(ct->containedSubtype, flags);
break;
case ACT_EL_VALUE:
asn1print_value(ct->value, flags);
......@@ -583,6 +585,8 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
}
printf(" OF");
break;
case A1TC_VALUESET:
break;
default:
{
char *p = ASN_EXPR_TYPE2STR(tc->expr_type);
......@@ -599,7 +603,7 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
asn1print_ref(tc->reference, flags);
}
if(tc->meta_type == AMT_VALUESET)
if(tc->meta_type == AMT_VALUESET && level == 0)
printf(" ::=");
/*
......
-- OK: Everything is fine
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .112
ModuleParameterizationClass
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 112 }
DEFINITIONS ::=
BEGIN
PCLASS {Type, INTEGER:value, INTEGER:ValueSet} ::= CLASS {
&valueField1 Type,
&valueField2 INTEGER DEFAULT value,
&valueField3 INTEGER (ValueSet),
&ValueSetField INTEGER DEFAULT {ValueSet}
} WITH SYNTAX {
&valueField1, &valueField2, &valueField3, &ValueSetField }
SCLASS ::= PCLASS {REAL, 111, {1 | 2 | 3}}
END
ModuleParameterizationClass { iso org(3) dod(6) internet(1) private(4)
enterprise(1) spelio(9363) software(1) asn1c(5) test(1) 112 }
DEFINITIONS ::=
BEGIN
PCLASS{Type, INTEGER:value, INTEGER:ValueSet} ::= CLASS {
&valueField1 Type,
&valueField2 INTEGER DEFAULT value,
&valueField3 INTEGER (ValueSet),
&ValueSetField INTEGER DEFAULT {ValueSet}
} WITH SYNTAX {
&valueField1, &valueField2, &valueField3, &ValueSetField }
SCLASS ::= PCLASS{ REAL, 111, {1 | 2 | 3}}
END
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