string type compatibility


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@816 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1fix/asn1fix_compat.c b/libasn1fix/asn1fix_compat.c
index 2efa8e8..064e38e 100644
--- a/libasn1fix/asn1fix_compat.c
+++ b/libasn1fix/asn1fix_compat.c
@@ -23,25 +23,37 @@
 	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 @@
 		}
 		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 161d9a3..18d8686 100644
--- a/libasn1fix/asn1fix_value.c
+++ b/libasn1fix/asn1fix_value.c
@@ -79,6 +79,11 @@
 			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 @@
 			 * 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 0000000..5a4edd0
--- /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 0000000..a158d5d
--- /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