SET OF/SEQUENCE OF interaction with named and unnamed CHOICE

diff --git a/ChangeLog b/ChangeLog
index f59da17..742ae50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
 
+0.9.20:	2005-Nov-07
+
+	* SET OF CHOICE, SEQUENCE OF CHOICE and a certain named S/O types
+	  are represented differently in XER. THIS IS AN ICOMPATIBLE CHANGE.
+	  (Test case 70) (Severity: low; Security impact: low)
+
 0.9.19:	2005-Oct-06
 
 	* A proper solution to circular references. No kludge flags
diff --git a/asn1c/tests/check-assembly.sh b/asn1c/tests/check-assembly.sh
index 4eb22d2..d3a5251 100755
--- a/asn1c/tests/check-assembly.sh
+++ b/asn1c/tests/check-assembly.sh
@@ -64,7 +64,7 @@
 check: check-succeeded
 
 clean:
-	@rm -f *.o
+	@rm -f *.o check-executable
 EOM
 
 # Perform building and checking
diff --git a/asn1c/tests/data-70/data-70-27.in b/asn1c/tests/data-70/data-70-27.in
index a2bb84a..f02101c 100644
--- a/asn1c/tests/data-70/data-70-27.in
+++ b/asn1c/tests/data-70/data-70-27.in
@@ -1,5 +1,5 @@
 <PDU>
 	<seqOfZuka>
-		<zuka/>
+		<NULL/>
 	</seqOfZuka>
 </PDU>
diff --git a/asn1c/tests/data-70/data-70-50.in b/asn1c/tests/data-70/data-70-50.in
new file mode 100644
index 0000000..21233c5
--- /dev/null
+++ b/asn1c/tests/data-70/data-70-50.in
@@ -0,0 +1,5 @@
+<PDU>
+	<namedSetOfNULL>
+		<NULL/> <NULL/> <NULL/>
+	</namedSetOfNULL>
+</PDU>
diff --git a/asn1c/tests/data-70/data-70-51.in b/asn1c/tests/data-70/data-70-51.in
new file mode 100644
index 0000000..106bbb8
--- /dev/null
+++ b/asn1c/tests/data-70/data-70-51.in
@@ -0,0 +1,6 @@
+<PDU>
+	<setOfChoice>
+		<a></a>
+		<b>1</b>
+	</setOfChoice>
+</PDU>
diff --git a/asn1c/tests/data-70/data-70-52-D.in b/asn1c/tests/data-70/data-70-52-D.in
new file mode 100644
index 0000000..0a35d3d
--- /dev/null
+++ b/asn1c/tests/data-70/data-70-52-D.in
@@ -0,0 +1,6 @@
+<PDU>
+	<setOfChoice>
+		<a/>
+		<b>1</b>
+	</setOfChoice>
+</PDU>
diff --git a/asn1c/tests/data-70/data-70-53.in b/asn1c/tests/data-70/data-70-53.in
new file mode 100644
index 0000000..20940b6
--- /dev/null
+++ b/asn1c/tests/data-70/data-70-53.in
@@ -0,0 +1,6 @@
+<PDU>
+	<namedSetOfChoice>
+		<a></a>
+		<b>1</b>
+	</namedSetOfChoice>
+</PDU>
diff --git a/asn1c/tests/data-70/data-70-54-D.in b/asn1c/tests/data-70/data-70-54-D.in
new file mode 100644
index 0000000..365026d
--- /dev/null
+++ b/asn1c/tests/data-70/data-70-54-D.in
@@ -0,0 +1,6 @@
+<PDU>
+	<namedSetOfChoice>
+		<a/>
+		<b>1</b>
+	</namedSetOfChoice>
+</PDU>
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 9884bdf..4df9918 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -734,11 +734,12 @@
 		OUT("offsetof(struct ");
 			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", _asn_ctx),\n");
-
-		if(expr_as_xmlvaluelist(arg, v))
-			OUT("1,\t/* XER encoding is XMLValueList */\n");
-		else
-			OUT("0,\t/* XER encoding is XMLDelimitedItemList */\n");
+		{
+		int as_xvl = expr_as_xmlvaluelist(arg, v);
+		OUT("%d,\t/* XER encoding is %s */\n",
+			as_xvl,
+			as_xvl ? "XMLValueList" : "XMLDelimitedItemList");
+		}
 	);
 	OUT("};\n");
 
@@ -1866,12 +1867,16 @@
 	expr = asn1f_find_terminal_type_ex(arg->asn, expr);
 	if(!expr) return 0;
 
-	/* X.680, 25.5, Table 5 */
+	/*
+	 * X.680, 25.5, Table 5
+	 */
 	switch(expr->expr_type) {
 	case ASN_BASIC_BOOLEAN:
 	case ASN_BASIC_ENUMERATED:
 	case ASN_BASIC_NULL:
 		return 1;
+	case ASN_CONSTR_CHOICE:
+		return 2;
 	default:
 		return 0;
 	}
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index b43c18f..de53c1d 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -549,6 +549,8 @@
 
 	if(!cb) {
 		er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
+		er.structure_ptr = 0;
+		er.failed_type = 0;
 		return er;
 	}
 
@@ -572,6 +574,8 @@
 	}
 
 	er.encoded += st->size;
+	er.structure_ptr = 0;
+	er.failed_type = 0;
 	return er;
 cb_failed:
 	_ASN_ENCODE_FAILED;
diff --git a/skeletons/asn-decoder-template.c b/skeletons/asn-decoder-template.c
index 0febbf4..348c373 100644
--- a/skeletons/asn-decoder-template.c
+++ b/skeletons/asn-decoder-template.c
@@ -1,5 +1,5 @@
 /*
- * Generic BER decoder template for any defined ASN.1 type.
+ * Generic decoder template for a selected ASN.1 type.
  * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * 
  * To compile with your own ASN.1 type, please redefine the asn_DEF as shown:
@@ -21,21 +21,32 @@
 #include <asn_application.h>
 
 extern asn_TYPE_descriptor_t asn_DEF;	/* ASN.1 type to be decoded */
+static asn_TYPE_descriptor_t *pduType = &asn_DEF;
 
 /*
  * Open file and parse its contens.
  */
 static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
 	const char *fname, ssize_t suggested_bufsize);
+static int write_out(const void *buffer, size_t size, void *key);
 
        int opt_debug;	/* -d */
 static int opt_check;	/* -c */
 static int opt_stack;	/* -s */
-static enum output_method {
-	OUT_NONE,	/* No pretty-printing */
-	OUT_PRINT,	/* -p flag */
-	OUT_XML		/* -x flag */
-}          opt_ometh;	/* -p or -x */
+
+/* Input data format selector */
+static enum input_format {
+	INP_BER,	/* -iber: BER input */
+	INP_XER		/* -ixer: XER input */
+} iform;	/* -i<format> */
+
+/* Output data format selector */
+static enum output_format {
+	OUT_XER,	/* -oxer: XER (XML) output */
+	OUT_DER,	/* -oder: DER output */
+	OUT_TEXT,	/* -otext: semi-structured text */
+	OUT_NULL	/* -onull: No pretty-printing */
+} oform;	/* -o<format> */
 
 #define	DEBUG(fmt, args...)	do {		\
 	if(!opt_debug) break;			\
@@ -46,7 +57,6 @@
 int
 main(int ac, char **av) {
 	ssize_t suggested_bufsize = 8192;  /* close or equal to stdio buffer */
-	asn_TYPE_descriptor_t *pduType = &asn_DEF;
 	int number_of_iterations = 1;
 	int num;
 	int ch;
@@ -54,8 +64,22 @@
 	/*
 	 * Pocess the command-line argments.
 	 */
-	while((ch = getopt(ac, av, "b:cdn:hps:x")) != -1)
+	while((ch = getopt(ac, av, "i:o:b:cdn:hs:")) != -1)
 	switch(ch) {
+	case 'i':
+		if(optarg[0] == 'b') { iform = INP_BER; break; }
+		if(optarg[0] == 'x') { iform = INP_XER; break; }
+		fprintf(stderr, "-i<format>: '%s': improper format selector",
+			optarg);
+		exit(EX_UNAVAILABLE);
+	case 'o':
+		if(optarg[0] == 'd') { oform = OUT_DER; break; }
+		if(optarg[0] == 'x') { oform = OUT_XER; break; }
+		if(optarg[0] == 't') { oform = OUT_TEXT; break; }
+		if(optarg[0] == 'n') { oform = OUT_NULL; break; }
+		fprintf(stderr, "-o<format>: '%s': improper format selector",
+			optarg);
+		exit(EX_UNAVAILABLE);
 	case 'b':
 		suggested_bufsize = atoi(optarg);
 		if(suggested_bufsize < 1
@@ -80,9 +104,6 @@
 			exit(EX_UNAVAILABLE);
 		}
 		break;
-	case 'p':
-		opt_ometh = OUT_PRINT;
-		break;
 	case 's':
 		opt_stack = atoi(optarg);
 		if(opt_stack <= 0) {
@@ -92,25 +113,22 @@
 			exit(EX_UNAVAILABLE);
 		}
 		break;
-	case 'x':
-		opt_ometh = OUT_XML;
-		break;
 	case 'h':
 	default:
 		fprintf(stderr,
 		"Usage: %s [options] <data.ber> ...\n"
 		"Where options are:\n"
+		"  -iber   (I)  Input is in BER (Basic Encoding Rules)\n"
+		"  -ixer        Input is in XER (XML Encoding Rules)\n"
+		"  -oder        Output in DER (Distinguished Encoding Rules)\n"
+		"  -oxer   (O)  Output in XER (XML Encoding Rules)\n"
+		"  -otext       Output in plain semi-structured text (dump)\n"
+		"  -onull       Verify (decode) input, but do not output\n"
 		"  -b <size>    Set the i/o buffer size (default is %ld)\n"
 		"  -c           Check ASN.1 constraints after decoding\n"
 		"  -d           Enable debugging (-dd is even better)\n"
 		"  -n <num>     Process files <num> times\n"
 		"  -s <size>    Set the stack usage limit\n"
-		"  -p           Print out the decoded contents\n"
-		"  -x           Print out as XML"
-#ifdef	ASN_DECODER_DEFAULT_OUTPUT_XML
-		" (default)"
-#endif
-		"\n"
 		, av[0], (long)suggested_bufsize);
 		exit(EX_USAGE);
 	}
@@ -119,14 +137,12 @@
 	av += optind;
 
 	if(ac < 1) {
-		fprintf(stderr, "Error: missing filename\n");
+		fprintf(stderr, "%s: No input files specified. "
+				"Try '-h' for more information\n",
+				av[-optind]);
 		exit(EX_USAGE);
 	}
 
-#ifdef	ASN_DECODER_DEFAULT_OUTPUT_XML
-	if(opt_ometh == OUT_NONE) opt_ometh = OUT_XML;
-#endif
-
 	setvbuf(stdout, 0, _IOLBF, 0);
 
 	for(num = 0; num < number_of_iterations; num++) {
@@ -137,6 +153,7 @@
 	  for(ac_i = 0; ac_i < ac; ac_i++) {
 		char *fname = av[ac_i];
 		void *structure;
+		asn_enc_rval_t erv;
 
 		/*
 		 * Decode the encoded structure from file.
@@ -148,22 +165,6 @@
 			exit(EX_DATAERR);
 		}
 
-		switch(opt_ometh) {
-		case OUT_NONE:
-			fprintf(stderr, "%s: decoded successfully\n", fname);
-			break;
-		case OUT_PRINT:	/* -p */
-			asn_fprint(stdout, pduType, structure);
-			break;
-		case OUT_XML:	/* -x */
-			if(xer_fprint(stdout, pduType, structure)) {
-				fprintf(stderr, "%s: Cannot convert into XML\n",
-					fname);
-				exit(EX_UNAVAILABLE);
-			}
-			break;
-		}
-
 		/* Check ASN.1 constraints */
 		if(opt_check) {
 			char errbuf[128];
@@ -176,6 +177,30 @@
 			}
 		}
 
+		switch(oform) {
+		case OUT_NULL:
+			fprintf(stderr, "%s: decoded successfully\n", fname);
+			break;
+		case OUT_TEXT:	/* -otext */
+			asn_fprint(stdout, pduType, structure);
+			break;
+		case OUT_XER:	/* -oxer */
+			if(xer_fprint(stdout, pduType, structure)) {
+				fprintf(stderr, "%s: Cannot convert into XML\n",
+					fname);
+				exit(EX_UNAVAILABLE);
+			}
+			break;
+		case OUT_DER:
+			erv = der_encode(pduType, structure, write_out, stdout);
+			if(erv.encoded < 0) {
+				fprintf(stderr, "%s: Cannot convert into DER\n",
+					fname);
+				exit(EX_UNAVAILABLE);
+			}
+			break;
+		}
+
 		pduType->free_struct(pduType, structure, 0);
 	  }
 	}
@@ -183,6 +208,10 @@
 	return 0;
 }
 
+/* Dump the buffer */
+static int write_out(const void *buffer, size_t size, void *key) {
+	return (fwrite(buffer, 1, size, key) == size) ? 0 : -1;
+}
 
 static char *buffer;
 static size_t buf_offset;	/* Offset from the start */
@@ -194,7 +223,7 @@
 #define	bufend	(buffer + buf_offset + buf_len)
 
 /*
- * Ensure that the buffer contains at least this amoount of free space.
+ * Ensure that the buffer contains at least this amount of free space.
  */
 static void buf_extend(size_t bySize) {
 
@@ -231,6 +260,7 @@
 	static asn_codec_ctx_t s_codec_ctx;
 	asn_codec_ctx_t *opt_codec_ctx = 0;
 	void *structure = 0;
+	asn_dec_rval_t rval;
 	size_t rd;
 	FILE *fp;
 
@@ -239,9 +269,14 @@
 		opt_codec_ctx = &s_codec_ctx;
 	}
 
-	DEBUG("Processing file %s", fname);
-
-	fp = fopen(fname, "r");
+	if(strcmp(fname, "-")) {
+		DEBUG("Processing file %s", fname);
+		fp = fopen(fname, "r");
+	} else {
+		DEBUG("Processing standard input");
+		fname = "stdin";
+		fp = stdin;
+	}
 
 	if(!fp) {
 		fprintf(stderr, "%s: %s\n", fname, strerror(errno));
@@ -262,9 +297,13 @@
 	buf_offset = 0;
 	buf_len = 0;
 
+	/* Pretend immediate EOF */
+	rval.code = RC_WMORE;
+	rval.consumed = 0;
+
 	while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) {
-		asn_dec_rval_t rval;
-		int using_local_buf;
+		char  *i_bptr;
+		size_t i_size;
 
 		/*
 		 * Copy the data over, or use the original buffer.
@@ -275,26 +314,27 @@
 			memcpy(bufend, fbuf, rd);
 			buf_len += rd;
 
-			rval = ber_decode(opt_codec_ctx, pduType,
-				(void **)&structure, bufptr, buf_len);
-			DEBUG("ber_decode(%ld) consumed %ld, code %d",
-				(long)buf_len, (long)rval.consumed, rval.code);
-
-			/*
-			 * Adjust position inside the source buffer.
-			 */
-			assert(rval.consumed <= buf_len);
-			buf_offset += rval.consumed;
-			buf_len -= rval.consumed;
+			i_bptr = bufptr;
+			i_size = buf_len;
 		} else {
-			using_local_buf = 1;
+			i_bptr = fbuf;
+			i_size = rd;
+		}
 
-			/* Feed the chunk of data into a decoder routine */
+		switch(iform) {
+		case INP_BER:
 			rval = ber_decode(opt_codec_ctx, pduType,
-				(void **)&structure, fbuf, rd);
-			DEBUG("ber_decode(%ld) consumed %ld, code %d",
-				(long)rd, (long)rval.consumed, rval.code);
+				(void **)&structure, i_bptr, i_size);
+			break;
+		case INP_XER:
+			rval = xer_decode(opt_codec_ctx, pduType,
+				(void **)&structure, i_bptr, i_size);
+			break;
+		}
+		DEBUG("decode(%ld) consumed %ld, code %d",
+			(long)buf_len, (long)rval.consumed, rval.code);
 
+		if(buf_len == 0) {
 			/*
 			 * Switch the remainder into the intermediate buffer.
 			 */
@@ -310,10 +350,16 @@
 		switch(rval.code) {
 		case RC_OK:
 			DEBUG("RC_OK, finishing up");
-			fclose(fp);
+			if(fp != stdin) fclose(fp);
 			return structure;
 		case RC_WMORE:
 			DEBUG("RC_WMORE, continuing...");
+			/*
+			 * Adjust position inside the source buffer.
+			 */
+			buf_offset += rval.consumed;
+			buf_len -= rval.consumed;
+			rval.consumed = 0;
 			continue;
 		case RC_FAIL:
 			break;
@@ -327,8 +373,11 @@
 	pduType->free_struct(pduType, structure, 0);
 
 	fprintf(stderr, "%s: "
-		"Decode failed past %lld byte\n",
-		fname, (long long)(buf_shifted + buf_offset));
+		"Decode failed past byte %ld: %s\n",
+		fname, (long)(buf_shifted + buf_offset + rval.consumed),
+		(rval.code == RC_WMORE)
+			? "Unexpected end of input"
+			: "Input processing error");
 
 	return 0;
 }
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index 09d407c..4a86141 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -20,7 +20,7 @@
 #endif
 
 /* Environment version might be used to avoid running with the old library */
-#define	ASN1C_ENVIRONMENT_VERSION	919	/* Compile-time version */
+#define	ASN1C_ENVIRONMENT_VERSION	920	/* Compile-time version */
 int get_asn1c_environment_version(void);	/* Run-time version */
 
 #define	CALLOC(nmemb, size)	calloc(nmemb, size)
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index b3af333..f832812 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -572,7 +572,8 @@
 	 * Restore parsing context.
 	 */
 	ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
+	if(ctx->phase == 0 && !*xml_tag)
+		ctx->phase = 1;	/* Skip the outer tag checking phase */
 
 	/*
 	 * Phases of XER/XML processing:
@@ -625,6 +626,12 @@
 			/* Fall through */
 		}
 
+		/* No need to wait for closing tag; special mode. */
+		if(ctx->phase == 3 && !*xml_tag) {
+			ctx->phase = 5;	/* Phase out */
+			RETURN(RC_OK);
+		}
+
 		/*
 		 * Get the next part of the XML stream.
 		 */
@@ -644,6 +651,12 @@
 		}
 
 		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+		ASN_DEBUG("XER/CHOICE checked [%c%c%c%c] vs [%s], tcv=%d",
+			ch_size>0?((uint8_t *)buf_ptr)[0]:'?',
+			ch_size>1?((uint8_t *)buf_ptr)[1]:'?',
+			ch_size>2?((uint8_t *)buf_ptr)[2]:'?',
+			ch_size>3?((uint8_t *)buf_ptr)[3]:'?',
+		xml_tag, tcv);
 
 		/* Skip the extensions section */
 		if(ctx->phase == 4) {
@@ -739,7 +752,8 @@
 			break;
 		}
 
-		ASN_DEBUG("Unexpected XML tag in CHOICE");
+		ASN_DEBUG("Unexpected XML tag in CHOICE (ph=%d, tag=%s)",
+			ctx->phase, xml_tag);
 		break;
 	}
 
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index 5530764..12233a6 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -51,6 +51,8 @@
 	computed_size += encoding_size;
 	if(!cb) {
 		erval.encoded = computed_size;
+		erval.structure_ptr = 0;
+		erval.failed_type = 0;
 		return erval;
 	}
 
@@ -79,6 +81,8 @@
 		erval.structure_ptr = ptr;
 	} else {
 		erval.encoded = computed_size;
+		erval.structure_ptr = 0;
+		erval.failed_type = 0;
 	}
 
 	return erval;
@@ -116,8 +120,7 @@
 				ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
                 if(tmper.encoded == 0 && specs->as_XMLValueList) {
-                        const char *name = (*elm->name)
-                                ? elm->name : elm->type->xml_tag;
+                        const char *name = elm->type->xml_tag;
 			size_t len = strlen(name);
 			if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
 			_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index e578ccb..bd25b3d 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -471,8 +471,7 @@
 	 */
 	asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
 	asn_TYPE_member_t *element = td->elements;
-	const char *elm_tag = ((*element->name)
-			? element->name : element->type->xml_tag);
+	const char *elm_tag;
 	const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
 
 	/*
@@ -492,6 +491,14 @@
 		if(st == 0) RETURN(RC_FAIL);
 	}
 
+	/* Which tag is expected for the downstream */
+	if(specs->as_XMLValueList) {
+		elm_tag = (specs->as_XMLValueList == 1) ? 0 : "";
+	} else {
+		elm_tag = (*element->name)
+				? element->name : element->type->xml_tag;
+	}
+
 	/*
 	 * Restore parsing context.
 	 */
@@ -515,6 +522,7 @@
 			asn_dec_rval_t tmprval;
 
 			/* Invoke the inner type decoder, m.b. multiple times */
+			ASN_DEBUG("XER/SET OF element [%s]", elm_tag);
 			tmprval = element->type->xer_decoder(opt_codec_ctx,
 					element->type, &ctx->ptr, elm_tag,
 					buf_ptr, size);
@@ -553,7 +561,8 @@
 		}
 
 		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
-		ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d", tcv, ctx->phase);
+		ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d t=%s",
+			tcv, ctx->phase, xml_tag);
 		switch(tcv) {
 		case XCT_CLOSING:
 			if(ctx->phase == 0) break;
@@ -682,18 +691,18 @@
 			_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
 		}
 
-		if(!xcan && specs->as_XMLValueList)
+		if(!xcan && specs->as_XMLValueList == 1)
 			_i_ASN_TEXT_INDENT(1, ilevel + 1);
 		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
-				ilevel + 1, flags, cb, app_key);
+				ilevel + (specs->as_XMLValueList != 2),
+				flags, cb, app_key);
 		if(tmper.encoded == -1) {
 			td = tmper.failed_type;
 			sptr = tmper.structure_ptr;
 			goto cb_failed;
 		}
 		if(tmper.encoded == 0 && specs->as_XMLValueList) {
-			const char *name = (*elm->name)
-				? elm->name : elm->type->xml_tag;
+			const char *name = elm->type->xml_tag;
 			size_t len = strlen(name);
 			_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
 		}
diff --git a/skeletons/tests/check-XER.c b/skeletons/tests/check-XER.c
index 10b0a31..6e2f1ce 100644
--- a/skeletons/tests/check-XER.c
+++ b/skeletons/tests/check-XER.c
@@ -46,8 +46,8 @@
 	check("</", "", XCT_BROKEN);
 	check("/>", "", XCT_BROKEN);
 
-	check("<>", "", XCT_OPENING);
-	check("</>", "", XCT_CLOSING);
+	check("<>", "", XCT_UNKNOWN_OP);
+	check("</>", "", XCT_UNKNOWN_CL);
 
 	check("", "a", XCT_BROKEN);
 	check("<>", "a", XCT_UNKNOWN_OP);
diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c
index b112a72..e48a5ed 100644
--- a/skeletons/xer_decoder.c
+++ b/skeletons/xer_decoder.c
@@ -124,6 +124,10 @@
 		}
 	}
 
+	/* Sometimes we don't care about the tag */
+	if(!need_tag || !*need_tag)
+		return (xer_check_tag_e)(XCT__UNK__MASK | ct);
+
 	/*
 	 * Determine the tag name.
 	 */
diff --git a/tests/42-real-life-OK.asn1.-PR b/tests/42-real-life-OK.asn1.-PR
index 6bc0c22..cd46263 100644
--- a/tests/42-real-life-OK.asn1.-PR
+++ b/tests/42-real-life-OK.asn1.-PR
@@ -239,7 +239,7 @@
 static asn_SET_OF_specifics_t asn_SPC_vparts_2_specs = {
 	sizeof(struct vparts),
 	offsetof(struct vparts, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_vparts_2 = {
diff --git a/tests/43-recursion-OK.asn1.-P b/tests/43-recursion-OK.asn1.-P
index 6416d4b..a348036 100644
--- a/tests/43-recursion-OK.asn1.-P
+++ b/tests/43-recursion-OK.asn1.-P
@@ -261,7 +261,7 @@
 static asn_SET_OF_specifics_t asn_SPC_or_3_specs = {
 	sizeof(struct or),
 	offsetof(struct or, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_or_3 = {
diff --git a/tests/70-xer-test-OK.asn1.-P b/tests/70-xer-test-OK.asn1.-P
index a0e273c..72483fd 100644
--- a/tests/70-xer-test-OK.asn1.-P
+++ b/tests/70-xer-test-OK.asn1.-P
@@ -1590,7 +1590,7 @@
 static asn_SET_OF_specifics_t asn_SPC_SetOfChoice_1_specs = {
 	sizeof(struct SetOfChoice),
 	offsetof(struct SetOfChoice, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 asn_TYPE_descriptor_t asn_DEF_SetOfChoice = {
 	"SetOfChoice",
@@ -1658,7 +1658,7 @@
 static asn_SET_OF_specifics_t asn_SPC_NamedSetOfChoice_1_specs = {
 	sizeof(struct NamedSetOfChoice),
 	offsetof(struct NamedSetOfChoice, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 asn_TYPE_descriptor_t asn_DEF_NamedSetOfChoice = {
 	"NamedSetOfChoice",
diff --git a/tests/92-circular-loops-OK.asn1.-P b/tests/92-circular-loops-OK.asn1.-P
index 4bfcab5..a45b9bf 100644
--- a/tests/92-circular-loops-OK.asn1.-P
+++ b/tests/92-circular-loops-OK.asn1.-P
@@ -472,7 +472,7 @@
 static asn_SET_OF_specifics_t asn_SPC_c_5_specs = {
 	sizeof(struct c),
 	offsetof(struct c, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_c_5 = {
diff --git a/tests/92-circular-loops-OK.asn1.-Pfindirect-choice b/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
index fd06d82..391ca91 100644
--- a/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
+++ b/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
@@ -473,7 +473,7 @@
 static asn_SET_OF_specifics_t asn_SPC_c_5_specs = {
 	sizeof(struct c),
 	offsetof(struct c, _asn_ctx),
-	0,	/* XER encoding is XMLDelimitedItemList */
+	2,	/* XER encoding is XMLValueList */
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_c_5 = {