extensions in CHOICE types properly marked


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@591 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/ChangeLog b/ChangeLog
index 763edb4..d007ff0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,5 @@
 
-0.9.8:	2004-Oct-30
+0.9.8:	2005-Jan-17
 
 	* [NEW PLATFORM] Compiled and tested on Linux @ alpha64 (LP64).
 	  Some code needed to be fixed regarding int-long conversions
@@ -15,6 +15,9 @@
 	* ber_dec_rval_t renamed into asn_dec_rval_t: more generality.
 	* Removed order dependency in DEFAULT references to ENUMERATED
 	  identifiers (./tests/68-*-OK.asn1).
+	* Extensions in CHOICE types are properly marked as non-pointers
+	  (Test case 59) (Severity: medium, Secruity impact: medium)
+	  Reported by <roman.pfender@sdm.de>.
 	* Implemented der_encode_to_buffer() procedure.
 
 0.9.7.1:	2004-Oct-12
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 2cbe258..5a4d1d8 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -655,22 +655,18 @@
 	 * Print out the table according to which the parsing is performed.
 	 */
 	if(expr_elements_count(arg, expr)) {
-		int comp_mode = 0;	/* {root,ext=1,root,root,...} */
 
 		p = MKID(expr->Identifier);
 		OUT("static asn_TYPE_member_t asn_MBR_%s[] = {\n", p);
 
 		elements = 0;
 		INDENTED(TQ_FOR(v, &(expr->members), next) {
-			if(v->expr_type == A1TC_EXTENSIBLE) {
-				if(comp_mode < 3) comp_mode++;
-			} else {
-				if(comp_mode == 1
-				|| expr_better_indirect(arg, v))
-					v->marker.flags |= EM_INDIRECT;
-				elements++;
-				emit_member_table(arg, v);
-			}
+			if(v->expr_type == A1TC_EXTENSIBLE)
+				continue;
+			if(expr_better_indirect(arg, v))
+				v->marker.flags |= EM_INDIRECT;
+			elements++;
+			emit_member_table(arg, v);
 		});
 		OUT("};\n");
 	} else {
diff --git a/tests/59-choice-extended-OK.asn1 b/tests/59-choice-extended-OK.asn1
new file mode 100644
index 0000000..06b3bc7
--- /dev/null
+++ b/tests/59-choice-extended-OK.asn1
@@ -0,0 +1,21 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .59
+
+ModuleTestExtensibleChoice
+	{ iso org(3) dod(6) internet(1) private(4) enterprise(1)
+		spelio(9363) software(1) asn1c(5) test(1) 59 }
+	DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+	Choice ::= CHOICE {
+		a	INTEGER,
+		...,
+		b	INTEGER,
+		c	Choice		-- A reference to itself
+	}
+
+END
diff --git a/tests/59-choice-extended-OK.asn1.-P b/tests/59-choice-extended-OK.asn1.-P
new file mode 100644
index 0000000..15941e0
--- /dev/null
+++ b/tests/59-choice-extended-OK.asn1.-P
@@ -0,0 +1,98 @@
+
+/*** <<< INCLUDES [Choice] >>> ***/
+
+#include <INTEGER.h>
+#include <Choice.h>
+#include <constr_CHOICE.h>
+
+/*** <<< DEPS [Choice] >>> ***/
+
+typedef enum Choice_PR {
+	Choice_PR_NOTHING,	/* No components present */
+	Choice_PR_a,
+	/* Extensions may appear below */
+	Choice_PR_b,
+	Choice_PR_c,
+} Choice_PR;
+
+struct Choice;	/* Forward declaration */
+extern asn_TYPE_descriptor_t asn_DEF_Choice;
+
+/*** <<< TYPE-DECLS [Choice] >>> ***/
+
+
+typedef struct Choice {
+	Choice_PR present;
+	union {
+		INTEGER_t	 a;
+		/*
+		 * This type is extensible,
+		 * possible extensions are below.
+		 */
+		INTEGER_t	 b;
+		struct Choice	*c;
+	} choice;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} Choice_t;
+
+/*** <<< STAT-DEFS [Choice] >>> ***/
+
+static asn_TYPE_member_t asn_MBR_Choice[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct Choice, choice.a),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+		.tag_mode = -1,	/* IMPLICIT tag at current level */
+		.type = (void *)&asn_DEF_INTEGER,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "a"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct Choice, choice.b),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		.tag_mode = -1,	/* IMPLICIT tag at current level */
+		.type = (void *)&asn_DEF_INTEGER,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "b"
+		},
+	{ ATF_POINTER, 0, offsetof(struct Choice, choice.c),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		.tag_mode = +1,	/* EXPLICIT tag at current level */
+		.type = (void *)&asn_DEF_Choice,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "c"
+		},
+};
+static asn_TYPE_tag2member_t asn_DEF_Choice_tag2el[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* a at 15 */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* b at 17 */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* c at 19 */
+};
+static asn_CHOICE_specifics_t asn_DEF_Choice_specs = {
+	sizeof(struct Choice),
+	offsetof(struct Choice, _asn_ctx),
+	offsetof(struct Choice, present),
+	sizeof(((struct Choice *)0)->present),
+	asn_DEF_Choice_tag2el,
+	3,	/* Count of tags in the map */
+	1	/* Whether extensible */
+};
+asn_TYPE_descriptor_t asn_DEF_Choice = {
+	"Choice",
+	"Choice",
+	CHOICE_free,
+	CHOICE_print,
+	CHOICE_constraint,
+	CHOICE_decode_ber,
+	CHOICE_encode_der,
+	CHOICE_decode_xer,
+	CHOICE_encode_xer,
+	CHOICE_outmost_tag,
+	0,	/* No effective tags (pointer) */
+	0,	/* No effective tags (count) */
+	0,	/* No tags (pointer) */
+	0,	/* No tags (count) */
+	asn_MBR_Choice,
+	3,	/* Elements count */
+	&asn_DEF_Choice_specs	/* Additional specs */
+};
+