From 0931f5766f0fb39aa5fb34c4add66d9a6e7a0a9d Mon Sep 17 00:00:00 2001 From: vlm Date: Wed, 27 Jun 2007 01:54:57 +0000 Subject: optionality handling git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1348 59561ff5-6e30-0410-9f3c-9617f08c8826 --- ChangeLog | 3 +- asn1c/tests/check-126.-gen-PER.c | 5 +- asn1c/tests/data-126/data-126-15.out | Bin 7 -> 6 bytes asn1c/tests/data-126/data-126-16.out | Bin 8 -> 7 bytes libasn1compiler/asn1c_C.c | 90 ++++++++++++++++++++++++++--- skeletons/constr_SEQUENCE.c | 6 +- tests/126-per-extensions-OK.asn1.-Pgen-PER | 28 ++++++++- 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= 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 Binary files a/asn1c/tests/data-126/data-126-15.out and b/asn1c/tests/data-126/data-126-15.out 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 Binary files a/asn1c/tests/data-126/data-126-16.out and b/asn1c/tests/data-126/data-126-16.out 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 @@ -2056,6 +2056,35 @@ emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) { return 0; } +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; @@ -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" }, }; -- cgit v1.2.3