aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2007-06-27 01:54:57 +0000
committerLev Walkin <vlm@lionet.info>2007-06-27 01:54:57 +0000
commit8032f7ab447fb09b2fdcf5743509c0a8880fc825 (patch)
tree34bf1b55bfdcd7f7cbf004c3857fa41a2e51e1b6
parent9774fd15fef655341f062c6fb488610ca2df0766 (diff)
optionality handling
-rw-r--r--ChangeLog3
-rw-r--r--asn1c/tests/check-126.-gen-PER.c5
-rw-r--r--asn1c/tests/data-126/data-126-15.outbin7 -> 6 bytes
-rw-r--r--asn1c/tests/data-126/data-126-16.outbin8 -> 7 bytes
-rw-r--r--libasn1compiler/asn1c_C.c90
-rw-r--r--skeletons/constr_SEQUENCE.c6
-rw-r--r--tests/126-per-extensions-OK.asn1.-Pgen-PER28
7 files changed, 121 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index eb8c8da0..56273dda 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,5 @@
-0.9.22: 2007-Jun-23
+0.9.22: 2007-Jun-26
* Added -pdu=all and -pdu=<type> switches to asn1c.
* Added PER support for most known-multiplier string types:
@@ -15,6 +15,7 @@
is encountered. (Severity: medium; Security impact: low)
* Fixed extensibility handling of second SEQUENCE production.
(Severity: low; Security impact: none)
+ * Added DEFAULT handling for known multiplier string.
0.9.21: 2006-Sep-17
diff --git a/asn1c/tests/check-126.-gen-PER.c b/asn1c/tests/check-126.-gen-PER.c
index 8b590b18..6a8e866f 100644
--- a/asn1c/tests/check-126.-gen-PER.c
+++ b/asn1c/tests/check-126.-gen-PER.c
@@ -288,7 +288,10 @@ process_XER_data(const char *fname, char *fbuf, int size) {
fwrite(buf, 1, buf_offset, stderr);
fprintf(stderr, "=== end ===\n");
- assert(xer_encoding_equal(fbuf, size, buf, buf_offset));
+ if(fname[strlen(fname) - 4] == 'X')
+ assert(!xer_encoding_equal(fbuf, size, buf, buf_offset));
+ else
+ assert(xer_encoding_equal(fbuf, size, buf, buf_offset));
asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0);
}
diff --git a/asn1c/tests/data-126/data-126-15.out b/asn1c/tests/data-126/data-126-15.out
index 3de83749..e278c6ba 100644
--- a/asn1c/tests/data-126/data-126-15.out
+++ b/asn1c/tests/data-126/data-126-15.out
Binary files differ
diff --git a/asn1c/tests/data-126/data-126-16.out b/asn1c/tests/data-126/data-126-16.out
index 88371928..bebf853c 100644
--- a/asn1c/tests/data-126/data-126-16.out
+++ b/asn1c/tests/data-126/data-126-16.out
Binary files differ
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index d8aa01fb..ef0c8688 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -2057,6 +2057,35 @@ emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
}
static int
+safe_string(const uint8_t *buf, int size) {
+ const uint8_t *end = buf + size;
+ for(; buf < end; buf++) {
+ int ch = *buf;
+ if((ch < 0x20 || ch > 0x7e) || ch == '"')
+ return 0;
+ }
+ return 1;
+}
+
+static void
+emit_default_value(arg_t *arg, asn1p_value_t *v) {
+
+ OUT("static uint8_t defv[] = ");
+ assert(v->type == ATV_STRING);
+
+ if(safe_string(v->value.string.buf, v->value.string.size)) {
+ OUT("\"%s\";\n", v->value.string.buf);
+ } else {
+ uint8_t *b = v->value.string.buf;
+ uint8_t *e = v->value.string.size + b;
+ OUT("{ ");
+ for(;b < e; b++)
+ OUT("0x%02x, ", *b);
+ OUT("0 };\n");
+ }
+}
+
+static int
try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
int save_target = arg->target->target;
asn1p_expr_type_e etype = expr_get_type(arg, expr);
@@ -2074,7 +2103,14 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
if(fits_long && !expr->marker.default_value->value.v_integer)
expr->marker.flags &= ~EM_INDIRECT;
- if(!out) return 1;
+ if(!out) {
+ OUT("asn_DFL_%d_set_%" PRIdASN
+ ",\t/* DEFAULT %" PRIdASN " */\n",
+ expr->_type_unique_index,
+ expr->marker.default_value->value.v_integer,
+ expr->marker.default_value->value.v_integer);
+ return 1;
+ }
REDIR(OT_STAT_DEFS);
OUT("static int asn_DFL_%d_set_%" PRIdASN "(int set_value, void **sptr) {\n",
expr->_type_unique_index,
@@ -2125,7 +2161,52 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
//expr->marker.flags &= ~EM_INDIRECT;
return 0;
default:
- break;
+ if(etype & ASN_STRING_KM_MASK) {
+ if(expr->marker.default_value == NULL
+ || expr->marker.default_value->type != ATV_STRING)
+ break;
+ if(!out) {
+ OUT("asn_DFL_%d_set,\t/* DEFAULT \"%s\" */\n",
+ expr->_type_unique_index,
+ expr->marker.default_value->value.string.buf);
+ return 1;
+ }
+ REDIR(OT_STAT_DEFS);
+ OUT("static int asn_DFL_%d_set(int set_value, void **sptr) {\n", expr->_type_unique_index);
+ INDENT(+1);
+ emit_default_value(arg, expr->marker.default_value);
+ OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
+ OUT("\n");
+ OUT("if(!st) {\n");
+ OUT("\tif(!set_value) return -1;\t/* Not a default value */\n");
+ OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
+ OUT("\tif(!st) return -1;\n");
+ OUT("}\n");
+ OUT("\n");
+ OUT("if(set_value) {\n");
+ INDENT(+1);
+ OUT("uint8_t *ptr = MALLOC(sizeof(defv));\n");
+ OUT("if(!ptr) return -1;\n");
+ OUT("memcpy(ptr, &defv, sizeof(defv));\n");
+ OUT("FREEMEM(st->buf);\n");
+ OUT("st->buf = ptr;\n");
+ OUT("st->size = sizeof(defv) - 1;\n");
+ OUT("return 0;\n");
+ INDENT(-1);
+ OUT("} else {\n");
+ INDENT(+1);
+ OUT("if(st->size != (sizeof(defv) - 1)\n");
+ OUT("|| memcmp(st->buf, &defv, sizeof(defv) - 1))\n");
+ OUT("\treturn 0;\n");
+ OUT("return 1;\n");
+ INDENT(-1);
+ OUT("}\n"); OUT("\n");
+ INDENT(-1);
+ OUT("}\n");
+ REDIR(save_target);
+ return 1;
+ }
+ break;
}
return 0;
}
@@ -2247,11 +2328,6 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
}
if(C99_MODE) OUT(".default_value = ");
if(try_inline_default(arg, expr, 0)) {
- OUT("asn_DFL_%d_set_%" PRIdASN
- ",\t/* DEFAULT %" PRIdASN " */\n",
- expr->_type_unique_index,
- expr->marker.default_value->value.v_integer,
- expr->marker.default_value->value.v_integer);
} else {
OUT("0,\n");
}
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index c824c04a..f82ebc69 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1337,6 +1337,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
FREEMEM(opres);
_ASN_DECODE_FAILED;
}
+ ASN_DEBUG("Filled-in default");
}
/* The member is just not present */
continue;
@@ -1612,8 +1613,11 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
}
/* Eliminate default values */
- if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
+ ASN_DEBUG("Defv %p mptr %p\n", elm->default_value, memb_ptr2);
+ ASN_DEBUG("Do not encode default: %s\n", (*(char **)(*memb_ptr2)));
+ if(elm->default_value && elm->default_value(0, memb_ptr2) == 1) {
continue;
+ }
er = elm->type->uper_encoder(elm->type, elm->per_constraints,
*memb_ptr2, po);
diff --git a/tests/126-per-extensions-OK.asn1.-Pgen-PER b/tests/126-per-extensions-OK.asn1.-Pgen-PER
index 7f7626ac..326a705c 100644
--- a/tests/126-per-extensions-OK.asn1.-Pgen-PER
+++ b/tests/126-per-extensions-OK.asn1.-Pgen-PER
@@ -140,6 +140,32 @@ extern asn_TYPE_descriptor_t asn_DEF_Singleton;
/*** <<< STAT-DEFS [Singleton] >>> ***/
+static int asn_DFL_2_set(int set_value, void **sptr) {
+ static uint8_t defv[] = "z";
+ IA5String_t *st = *sptr;
+
+ if(!st) {
+ if(!set_value) return -1; /* Not a default value */
+ st = (*sptr = CALLOC(1, sizeof(*st)));
+ if(!st) return -1;
+ }
+
+ if(set_value) {
+ uint8_t *ptr = MALLOC(sizeof(defv));
+ if(!ptr) return -1;
+ memcpy(ptr, &defv, sizeof(defv));
+ FREEMEM(st->buf);
+ st->buf = ptr;
+ st->size = sizeof(defv) - 1;
+ return 0;
+ } else {
+ if(st->size != (sizeof(defv) - 1)
+ || memcmp(st->buf, &defv, sizeof(defv) - 1))
+ return 0;
+ return 1;
+ }
+
+}
static asn_TYPE_member_t asn_MBR_Singleton_1[] = {
{ ATF_POINTER, 1, offsetof(struct Singleton, opt_z),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
@@ -147,7 +173,7 @@ static asn_TYPE_member_t asn_MBR_Singleton_1[] = {
.type = &asn_DEF_IA5String,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* No PER visible constraints */
- .default_value = 0,
+ .default_value = asn_DFL_2_set, /* DEFAULT "z" */
.name = "opt-z"
},
};