Commit 8032f7ab authored by Lev Walkin's avatar Lev Walkin
Browse files

optionality handling

parent 9774fd15
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
......
......@@ -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);
}
......
......@@ -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");
}
......
......@@ -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);
......
......@@ -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"
},
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment