diff --git a/libasn1fix/asn1fix_compat.c b/libasn1fix/asn1fix_compat.c index 2efa8e85..064e38e5 100644 --- a/libasn1fix/asn1fix_compat.c +++ b/libasn1fix/asn1fix_compat.c @@ -23,25 +23,37 @@ asn1f_check_type_compatibility(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) { assert(atype != A1TC_REFERENCE); assert(btype != A1TC_REFERENCE); + if(a == b) + return 0; /* Fairly obviously */ + if(atype != btype) { /* - * Limited compatibility. + * Limited cross-compatibility of integer types. */ if((atype == A1TC_UNIVERVAL && btype == ASN_BASIC_INTEGER) || (atype == A1TC_UNIVERVAL && btype == ASN_BASIC_ENUMERATED) ) return 0; + + /* Limited cross-compatibility of string types */ + if((atype & ASN_STRING_MASK) + && (btype & ASN_STRING_MASK)) { + /* X.680, B.5 */ + int akm = (atype & ASN_STRING_KM_MASK) + || atype == ASN_STRING_UTF8String; + int bkm = (btype & ASN_STRING_KM_MASK) + || btype == ASN_STRING_UTF8String; + return (akm == bkm) ? 0 : -1; + } + DEBUG("\t%s and %s are not compatible", a->Identifier, b->Identifier); return -1; /* Fairly obviously */ } - if(a == b) - return 0; /* Fairly obviously */ - switch(atype) { case ASN_BASIC_INTEGER: - /* All integers are compatible */ + /* All integers are compatible, X.680, B.4.5 */ return 0; case ASN_BASIC_ENUMERATED: /* @@ -55,6 +67,11 @@ asn1f_check_type_compatibility(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) { } return 0; default: + if((atype & ASN_STRING_MASK) + && (btype & ASN_STRING_MASK)) { + /* String type is compatible with the same type */ + return 0; + } /* Compatibility is not defined yet */ DEBUG("\tCompatibility rule is not defined for %s and %s", a->Identifier, b->Identifier); diff --git a/libasn1fix/asn1fix_value.c b/libasn1fix/asn1fix_value.c index 161d9a38..18d86866 100644 --- a/libasn1fix/asn1fix_value.c +++ b/libasn1fix/asn1fix_value.c @@ -79,6 +79,11 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr, const enum asn1p_constraint_ type_expr, val_type_expr); if(ret == -1) { switch(type_expr->expr_type) { + default: + if(!(type_expr->expr_type & ASN_STRING_MASK)) + break; + /* Compatibility rules are not defined */ + /* Fall through */ case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: FATAL("Incompatible type of \"%s\" (%s) at line %d " @@ -96,10 +101,8 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr, const enum asn1p_constraint_ * We can't deal with OIDs inheritance properly yet. */ return 0; - default: - break; } - WARNING("Incompatible type of \"%s\" (%s) at line %d " + WARNING("Possibly incompatible type of \"%s\" (%s) at line %d " "with \"%s\" (%s) at line %d", type_expr->Identifier, ASN_EXPR_TYPE2STR(type_expr->expr_type), diff --git a/tests/77-str-default-OK.asn1 b/tests/77-str-default-OK.asn1 new file mode 100644 index 00000000..5a4edd0a --- /dev/null +++ b/tests/77-str-default-OK.asn1 @@ -0,0 +1,26 @@ + +-- OK: Everything is fine + +-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) +-- .spelio.software.asn1c.test (9363.1.5.1) +-- .77 + +ModuleTestStringConstraint + { iso org(3) dod(6) internet(1) private(4) enterprise(1) + spelio(9363) software(1) asn1c(5) test(1) 77 } + DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + + Type ::= SEQUENCE { + cntry PRString DEFAULT country1, + cntry1 PrintableString DEFAULT country1, + cntry2 UniversalString DEFAULT country2, + ... + } + + country1 PrintableString ::= "Rwanda" + country2 PRString ::= "United Kingdom" + + PRString ::= PrintableString + +END diff --git a/tests/78-str-default-SE.asn1 b/tests/78-str-default-SE.asn1 new file mode 100644 index 00000000..a158d5d0 --- /dev/null +++ b/tests/78-str-default-SE.asn1 @@ -0,0 +1,21 @@ + +-- SE: Semantic error + +-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) +-- .spelio.software.asn1c.test (9363.1.5.1) +-- .78 + +ModuleTestStringConstraint2 + { iso org(3) dod(6) internet(1) private(4) enterprise(1) + spelio(9363) software(1) asn1c(5) test(1) 78 } + DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + + Type ::= SEQUENCE { + country UTF8String DEFAULT country1, + ... + } + + country1 GeneralString ::= "Cyprus" + +END