BMPString and UniversalString fuzz testing
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 539f792..264b8a6 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -2129,7 +2129,9 @@
 	if((arg->flags & A1C_GEN_PER)
 	&& (expr->combined_constraints
 		|| etype == ASN_BASIC_ENUMERATED
-		|| etype == ASN_CONSTR_CHOICE)
+		|| etype == ASN_CONSTR_CHOICE
+		|| (etype & ASN_STRING_KM_MASK)
+        )
 	) {
 		/* Fall through */
 	} else {
@@ -2978,10 +2980,11 @@
         OUT(", ");
 
 		if(arg->flags & A1C_GEN_PER) {
-			if(expr->combined_constraints
-			|| expr->expr_type == ASN_BASIC_ENUMERATED
-			|| expr->expr_type == ASN_CONSTR_CHOICE) {
-				OUT("&asn_PER_type_%s_constr_%d",
+            if(expr->combined_constraints
+               || expr->expr_type == ASN_BASIC_ENUMERATED
+               || expr->expr_type == ASN_CONSTR_CHOICE
+               || (expr->expr_type & ASN_STRING_KM_MASK)) {
+                OUT("&asn_PER_type_%s_constr_%d",
 					expr_id, expr->_type_unique_index);
 			} else {
 				OUT("0");
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 942fc6b..e618609 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -1313,28 +1313,32 @@
 		return per_put_many_bits(po, buf, unit_bits * units);
 	}
 
-	for(ub -= lb; buf < end; buf += bpc) {
-		int ch;
-		uint32_t value;
-		switch(bpc) {
-		case 1: value = *(const uint8_t *)buf; break;
-		case 2: value = (buf[0] << 8) | buf[1]; break;
-		case 4: value = (buf[0] << 24) | (buf[1] << 16)
-				| (buf[2] << 8) | buf[3]; break;
-		default: return -1;
-		}
-		ch = value - lb;
-		if(ch < 0 || ch > ub) {
-			ASN_DEBUG("Character %d (0x%02x)"
-			" is out of range (%ld..%ld)",
-				*buf, *buf, lb, ub + lb);
-			return -1;
-		}
-		if(per_put_few_bits(po, ch, unit_bits))
-			return -1;
-	}
+    for(ub -= lb; buf < end; buf += bpc) {
+        int ch;
+        uint32_t value;
+        switch(bpc) {
+        case 1:
+            value = *(const uint8_t *)buf;
+            break;
+        case 2:
+            value = (buf[0] << 8) | buf[1];
+            break;
+        case 4:
+            value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+            break;
+        default:
+            return -1;
+        }
+        ch = value - lb;
+        if(ch < 0 || ch > ub) {
+            ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf,
+                      value, lb, ub + lb);
+            return -1;
+        }
+        if(per_put_few_bits(po, ch, unit_bits)) return -1;
+    }
 
-	return 0;
+    return 0;
 }
 
 static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
@@ -1998,13 +2002,19 @@
         break;
     case 2:
         for(b = buf; b < bend; b += unit_bytes) {
-            *(uint16_t *)b = OCTET_STRING__random_char(clb, cub);
+            uint32_t code = OCTET_STRING__random_char(clb, cub);
+            b[0] = code >> 8;
+            b[1] = code;
         }
         *(uint16_t *)b = 0;
         break;
     case 4:
         for(b = buf; b < bend; b += unit_bytes) {
-            *(uint32_t *)b = OCTET_STRING__random_char(clb, cub);
+            uint32_t code = OCTET_STRING__random_char(clb, cub);
+            b[0] = code >> 24;
+            b[1] = code >> 16;
+            b[2] = code >> 8;
+            b[3] = code;
         }
         *(uint32_t *)b = 0;
         break;
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 8d99cad..67fb6a1 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
@@ -236,3 +236,36 @@
 	return 0;
 }
 
+/*
+ * Biased function for randomizing UCS-4 sequences.
+ */
+static size_t
+UniversalString__random_char(uint8_t *b) {
+    uint32_t code;
+
+    switch(asn_random_between(0, 4)) {
+    case 0:
+        code = 0;
+        break;
+    case 1:
+        code = 1;
+        break;
+    case 2:
+        code = 0xd7ff;  /* End of pre-surrogate block */
+        break;
+    case 3:
+        code = 0xe000;  /* Beginning of post-surrogate block */
+        break;
+    case 4:
+        code = 0x10ffff;
+        break;
+    }
+
+    b[0] = code >> 24;
+    b[1] = code >> 16;
+    b[2] = code >> 8;
+    b[3] = code;
+
+    return 4;
+}
+
diff --git a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER
index c1b6fd8..c588c01 100644
--- a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER
+++ b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER
@@ -472,6 +472,7 @@
 
 /*** <<< FUNC-DECLS [Str1] >>> ***/
 
+extern asn_per_constraints_t asn_PER_type_Str1_constr_1;
 extern asn_TYPE_descriptor_t asn_DEF_Str1;
 asn_struct_free_f Str1_free;
 asn_struct_print_f Str1_print;
@@ -490,6 +491,14 @@
  * so here we adjust the DEF accordingly.
  */
 
+/*** <<< CTDEFS [Str1] >>> ***/
+
+asn_per_constraints_t asn_PER_type_Str1_constr_1 CC_NOTUSED = {
+	{ APC_CONSTRAINED,	 7,  7,  0,  127 }	/* (0..127) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Str1] >>> ***/
 
 static const ber_tlv_tag_t asn_DEF_Str1_tags_1[] = {
@@ -505,7 +514,7 @@
 	asn_DEF_Str1_tags_1,	/* Same as above */
 	sizeof(asn_DEF_Str1_tags_1)
 		/sizeof(asn_DEF_Str1_tags_1[0]), /* 1 */
-	{ 0, 0, IA5String_constraint },
+	{ 0, &asn_PER_type_Str1_constr_1, IA5String_constraint },
 	0, 0,	/* No members */
 	0	/* No specifics */
 };
diff --git a/tests/tests-randomized/Makefile.am b/tests/tests-randomized/Makefile.am
index 4e6415f..be433ab 100644
--- a/tests/tests-randomized/Makefile.am
+++ b/tests/tests-randomized/Makefile.am
@@ -34,8 +34,10 @@
 TESTS += bundles/08-OBJECT-IDENTIFIER-bundle.txt
 TESTS += bundles/09-RELATIVE-OID-bundle.txt
 TESTS += bundles/10-UTF8String-bundle.txt
-TESTS += bundles/11-UTCTime-bundle.txt
-TESTS += bundles/12-GeneralizedTime-bundle.txt
+TESTS += bundles/11-BMPString-bundle.txt
+TESTS += bundles/12-UniversalString-bundle.txt
+TESTS += bundles/13-UTCTime-bundle.txt
+TESTS += bundles/14-GeneralizedTime-bundle.txt
 
 EXTRA_DIST =                    \
     random-test-driver.c        \
diff --git a/tests/tests-randomized/bundles/10-UTF8String-bundle.txt b/tests/tests-randomized/bundles/10-UTF8String-bundle.txt
index b2581e9..206c59d 100644
--- a/tests/tests-randomized/bundles/10-UTF8String-bundle.txt
+++ b/tests/tests-randomized/bundles/10-UTF8String-bundle.txt
@@ -1,4 +1,7 @@
 UTF8String
+UTF8String (SIZE(0))
+UTF8String (SIZE(1))
 UTF8String (SIZE(3))
 UTF8String (FROM("A".."Z"))
+UTF8String (FROM("A".."Z") INTERSECTION SIZE(0))
 UTF8String (FROM("A".."Z") INTERSECTION SIZE(3))
diff --git a/tests/tests-randomized/bundles/11-BMPString-bundle.txt b/tests/tests-randomized/bundles/11-BMPString-bundle.txt
new file mode 100644
index 0000000..b56c8df
--- /dev/null
+++ b/tests/tests-randomized/bundles/11-BMPString-bundle.txt
@@ -0,0 +1,7 @@
+BMPString
+BMPString (SIZE(0))
+BMPString (SIZE(1))
+BMPString (SIZE(3))
+BMPString (FROM("A".."Z"))
+BMPString (FROM("A".."Z") INTERSECTION SIZE(0))
+BMPString (FROM("A".."Z") INTERSECTION SIZE(3))
diff --git a/tests/tests-randomized/bundles/12-UniversalString-bundle.txt b/tests/tests-randomized/bundles/12-UniversalString-bundle.txt
new file mode 100644
index 0000000..aa99882
--- /dev/null
+++ b/tests/tests-randomized/bundles/12-UniversalString-bundle.txt
@@ -0,0 +1,7 @@
+UniversalString
+UniversalString (SIZE(0))
+UniversalString (SIZE(1))
+UniversalString (SIZE(3))
+UniversalString (FROM("A".."Z"))
+UniversalString (FROM("A".."Z") INTERSECTION SIZE(0))
+UniversalString (FROM("A".."Z") INTERSECTION SIZE(3))
diff --git a/tests/tests-randomized/bundles/11-UTCTime-bundle.txt b/tests/tests-randomized/bundles/13-UTCTime-bundle.txt
similarity index 100%
rename from tests/tests-randomized/bundles/11-UTCTime-bundle.txt
rename to tests/tests-randomized/bundles/13-UTCTime-bundle.txt
diff --git a/tests/tests-randomized/bundles/12-GeneralizedTime-bundle.txt b/tests/tests-randomized/bundles/14-GeneralizedTime-bundle.txt
similarity index 100%
rename from tests/tests-randomized/bundles/12-GeneralizedTime-bundle.txt
rename to tests/tests-randomized/bundles/14-GeneralizedTime-bundle.txt