Combined constraints and introduced value randomizer.
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 1e670ba..6b2c08e 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -32,16 +32,15 @@
ANY_decode_uper,
ANY_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ 0, /* Random fill is not defined for ANY type */
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_ANY = {
"ANY",
"ANY",
&asn_OP_ANY,
- asn_generic_no_constraint,
0, 0, 0, 0,
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint }, /* No constraints */
0, 0, /* No members */
&asn_SPC_ANY_specs,
};
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index a68621a..b5ab945 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -39,21 +39,20 @@
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ BIT_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
"BIT STRING",
"BIT_STRING",
&asn_OP_BIT_STRING,
- BIT_STRING_constraint,
asn_DEF_BIT_STRING_tags,
sizeof(asn_DEF_BIT_STRING_tags)
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
asn_DEF_BIT_STRING_tags, /* Same as above */
sizeof(asn_DEF_BIT_STRING_tags)
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, BIT_STRING_constraint },
0, 0, /* No members */
&asn_SPC_BIT_STRING_specs
};
@@ -244,3 +243,84 @@
}
}
+
+asn_random_fill_result_t
+BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_OCTET_STRING_specifics_t *specs =
+ td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_SPC_BIT_STRING_specs;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
+ 126, 127, 128, 16383, 16384, 16385,
+ 65534, 65535, 65536, 65537};
+ uint8_t *buf;
+ uint8_t *bend;
+ uint8_t *b;
+ size_t rnd_bits, rnd_len;
+ BIT_STRING_t *st;
+
+ if(max_length == 0) return result_skipped;
+
+ switch(specs->subvariant) {
+ case ASN_OSUBV_ANY:
+ return result_failed;
+ case ASN_OSUBV_BIT:
+ break;
+ default:
+ break;
+ }
+
+ /* Figure out how far we should go */
+ rnd_bits = lengths[asn_random_between(
+ 0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
+ if(constraints->per_constraints) {
+ const asn_per_constraint_t *pc =
+ &td->encoding_constraints.per_constraints->size;
+ if(pc->flags & APC_CONSTRAINED) {
+ if(max_length < (size_t)pc->lower_bound) {
+ return result_skipped;
+ }
+ rnd_bits = asn_random_between(pc->lower_bound, pc->upper_bound);
+ } else {
+ rnd_bits = asn_random_between(0, max_length - 1);
+ }
+ } else if(rnd_bits >= max_length) {
+ rnd_bits = asn_random_between(0, max_length - 1);
+ }
+
+ rnd_len = (rnd_bits + 7) / 8;
+ buf = CALLOC(1, rnd_len + 1);
+ if(!buf) return result_failed;
+
+ bend = &buf[rnd_len];
+
+ for(b = buf; b < bend; b++) {
+ *(uint8_t *)b = asn_random_between(0, 255);
+ }
+
+ if(*sptr) {
+ st = *sptr;
+ FREEMEM(st->buf);
+ } else {
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(!st) {
+ FREEMEM(buf);
+ return result_failed;
+ }
+ }
+
+ st->buf = buf;
+ st->size = rnd_len;
+ st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
+ if(st->bits_unused) {
+ assert(st->size > 0);
+ st->buf[st->size-1] &= 0xff << st->bits_unused;
+ }
+
+ result_ok.length = st->size;
+ return result_ok;
+}
diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h
index 2b19584..dd7a611 100644
--- a/skeletons/BIT_STRING.h
+++ b/skeletons/BIT_STRING.h
@@ -30,6 +30,7 @@
xer_type_encoder_f BIT_STRING_encode_xer;
oer_type_decoder_f BIT_STRING_decode_oer;
oer_type_encoder_f BIT_STRING_encode_oer;
+asn_random_fill_f BIT_STRING_random_fill;
#define BIT_STRING_free OCTET_STRING_free
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
diff --git a/skeletons/BIT_STRING_oer.c b/skeletons/BIT_STRING_oer.c
index a470e09..e887228 100644
--- a/skeletons/BIT_STRING_oer.c
+++ b/skeletons/BIT_STRING_oer.c
@@ -15,7 +15,7 @@
const void *ptr, size_t size) {
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
const asn_oer_constraints_t *cts =
- constraints ? constraints : td->oer_constraints;
+ constraints ? constraints : td->encoding_constraints.oer_constraints;
ssize_t ct_size = cts ? cts->size : -1;
asn_dec_rval_t rval = {RC_OK, 0};
size_t expected_length = 0;
@@ -93,7 +93,7 @@
BIT_STRING_t *st = (BIT_STRING_t *)sptr;
asn_enc_rval_t erval = {0, 0, 0};
const asn_oer_constraints_t *cts =
- constraints ? constraints : td->oer_constraints;
+ constraints ? constraints : td->encoding_constraints.oer_constraints;
ssize_t ct_size = cts ? cts->size : -1;
size_t trailing_zeros = 0;
int fix_last_byte = 0;
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index 80a3f8b..8fa583b 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -45,21 +45,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_BMPString = {
"BMPString",
"BMPString",
&asn_OP_BMPString,
- BMPString_constraint,
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]) - 1,
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_BMPString_per_constraints,
+ { 0, &asn_DEF_BMPString_per_constraints, BMPString_constraint },
0, 0, /* No members */
&asn_SPC_BMPString_specs
};
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 21a858c..3534003 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -34,19 +34,18 @@
BOOLEAN_decode_uper, /* Unaligned PER decoder */
BOOLEAN_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ BOOLEAN_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
"BOOLEAN",
"BOOLEAN",
&asn_OP_BOOLEAN,
- asn_generic_no_constraint,
asn_DEF_BOOLEAN_tags,
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
asn_DEF_BOOLEAN_tags, /* Same as above */
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -332,3 +331,29 @@
return 1;
}
}
+
+asn_random_fill_result_t
+BOOLEAN_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ BOOLEAN_t *st = *sptr;
+
+ (void)td;
+ (void)constr;
+
+ if(max_length == 0) return result_skipped;
+
+ if(st == NULL) {
+ st = (BOOLEAN_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ *st = asn_random_between(0, 1);
+
+ return result_ok;
+}
diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h
index b399b3e..b58fdd7 100644
--- a/skeletons/BOOLEAN.h
+++ b/skeletons/BOOLEAN.h
@@ -30,6 +30,7 @@
xer_type_encoder_f BOOLEAN_encode_xer;
per_type_decoder_f BOOLEAN_decode_uper;
per_type_encoder_f BOOLEAN_encode_uper;
+asn_random_fill_f BOOLEAN_random_fill;
#define BOOLEAN_constraint asn_generic_no_constraint
diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c
index ffc61e3..dc6ecff 100644
--- a/skeletons/ENUMERATED.c
+++ b/skeletons/ENUMERATED.c
@@ -36,19 +36,18 @@
ENUMERATED_decode_uper, /* Unaligned PER decoder */
ENUMERATED_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ ENUMERATED_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
"ENUMERATED",
"ENUMERATED",
&asn_OP_ENUMERATED,
- asn_generic_no_constraint,
asn_DEF_ENUMERATED_tags,
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
asn_DEF_ENUMERATED_tags, /* Same as above */
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/ENUMERATED.h b/skeletons/ENUMERATED.h
index e4df29b..6c878c4 100644
--- a/skeletons/ENUMERATED.h
+++ b/skeletons/ENUMERATED.h
@@ -27,6 +27,7 @@
#define ENUMERATED_encode_der INTEGER_encode_der
#define ENUMERATED_decode_xer INTEGER_decode_xer
#define ENUMERATED_encode_xer INTEGER_encode_xer
+#define ENUMERATED_random_fill INTEGER_random_fill
#ifdef __cplusplus
}
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index c833dd5..16b6f2f 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_GeneralString = {
"GeneralString",
"GeneralString",
&asn_OP_GeneralString,
- asn_generic_unknown_constraint,
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
/ sizeof(asn_DEF_GeneralString_tags[0]) - 1,
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
/ sizeof(asn_DEF_GeneralString_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index aeebafd..97a381d 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#define _POSIX_PTHREAD_SEMANTICS /* for Sun */
@@ -166,7 +166,7 @@
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
-static asn_per_constraints_t asn_DEF_GeneralizedTime_constraints = {
+static asn_per_constraints_t asn_DEF_GeneralizedTime_per_constraints = {
{ APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
0, 0
@@ -193,21 +193,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ GeneralizedTime_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
"GeneralizedTime",
"GeneralizedTime",
&asn_OP_GeneralizedTime,
- GeneralizedTime_constraint, /* Check validity of time */
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
/ sizeof(asn_DEF_GeneralizedTime_tags[0]) - 2,
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
/ sizeof(asn_DEF_GeneralizedTime_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_GeneralizedTime_constraints,
+ { 0, &asn_DEF_GeneralizedTime_per_constraints, GeneralizedTime_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -722,4 +721,34 @@
return opt_gt;
}
+asn_random_fill_result_t
+GeneralizedTime_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static const char *values[] = {
+ "19700101000000", "19700101000000-0000", "19700101000000+0000",
+ "19700101000000Z", "19700101000000.3Z", "19821106210623.3",
+ "19821106210629.3Z", "19691106210827.3-0500", "19821106210629.456",
+ };
+ size_t rnd = asn_random_between(0, sizeof(values)/sizeof(values[0])-1);
+ (void)constraints;
+
+ if(max_length < sizeof("yyyymmddhhmmss")) {
+ return result_skipped;
+ }
+
+ if(*sptr) {
+ if(OCTET_STRING_fromBuf(*sptr, values[rnd], -1) != 0) {
+ if(!sptr) return result_failed;
+ }
+ } else {
+ *sptr = OCTET_STRING_new_fromBuf(td, values[rnd], -1);
+ if(!sptr) return result_failed;
+ }
+
+ return result_ok;
+}
diff --git a/skeletons/GeneralizedTime.h b/skeletons/GeneralizedTime.h
index ace9c02..84ee481 100644
--- a/skeletons/GeneralizedTime.h
+++ b/skeletons/GeneralizedTime.h
@@ -20,6 +20,7 @@
asn_constr_check_f GeneralizedTime_constraint;
der_type_encoder_f GeneralizedTime_encode_der;
xer_type_encoder_f GeneralizedTime_encode_xer;
+asn_random_fill_f GeneralizedTime_random_fill;
#define GeneralizedTime_free OCTET_STRING_free
#define GeneralizedTime_compare OCTET_STRING_compare
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index ecf4e52..7ec7945 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_GraphicString = {
"GraphicString",
"GraphicString",
&asn_OP_GraphicString,
- asn_generic_unknown_constraint,
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
/ sizeof(asn_DEF_GraphicString_tags[0]) - 1,
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
/ sizeof(asn_DEF_GraphicString_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index b0e06c3..6530ba3 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -39,21 +39,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_IA5String = {
"IA5String",
"IA5String",
&asn_OP_IA5String,
- IA5String_constraint, /* Constraint on the alphabet */
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
/ sizeof(asn_DEF_IA5String_tags[0]) - 1,
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
/ sizeof(asn_DEF_IA5String_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_IA5String_per_constraints,
+ { 0, &asn_DEF_IA5String_per_constraints, IA5String_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 9d5baff..38806db 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -36,19 +36,18 @@
INTEGER_decode_uper, /* Unaligned PER decoder */
INTEGER_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ INTEGER_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_INTEGER = {
"INTEGER",
"INTEGER",
&asn_OP_INTEGER,
- asn_generic_no_constraint,
asn_DEF_INTEGER_tags,
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
asn_DEF_INTEGER_tags, /* Same as above */
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -589,7 +588,7 @@
if(!st) ASN__DECODE_FAILED;
}
- if(!constraints) constraints = td->per_constraints;
+ if(!constraints) constraints = td->encoding_constraints.per_constraints;
ct = constraints ? &constraints->value : 0;
if(ct && ct->flags & APC_EXTENSIBLE) {
@@ -701,7 +700,7 @@
if(!st || st->size == 0) ASN__ENCODE_FAILED;
- if(!constraints) constraints = td->per_constraints;
+ if(!constraints) constraints = td->encoding_constraints.per_constraints;
ct = constraints ? &constraints->value : 0;
er.encoded = 0;
@@ -1152,3 +1151,80 @@
}
+asn_random_fill_result_t
+INTEGER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ const asn_INTEGER_specifics_t *specs =
+ (const asn_INTEGER_specifics_t *)td->specifics;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ INTEGER_t *st = *sptr;
+ const asn_INTEGER_enum_map_t *emap;
+ size_t emap_len;
+ intmax_t value;
+ int find_inside_map;
+
+ if(max_length == 0) return result_skipped;
+
+ if(st == NULL) {
+ st = (INTEGER_t *)CALLOC(1, sizeof(*st));
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ if(specs) {
+ emap = specs->value2enum;
+ emap_len = specs->map_count;
+ if(specs->strict_enumeration) {
+ find_inside_map = emap_len > 0;
+ } else {
+ find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
+ }
+ } else {
+ emap = 0;
+ emap_len = 0;
+ find_inside_map = 0;
+ }
+
+ if(find_inside_map) {
+ assert(emap_len > 0);
+ value = emap[asn_random_between(0, emap_len - 1)].nat_value;
+ } else {
+ const asn_per_constraint_t *ct;
+
+ static const long variants[] = {
+ -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
+ -16383, -257, -256, -255, -254, -129, -128, -127,
+ -126, -1, 0, 1, 126, 127, 128, 129,
+ 254, 255, 256, 257, 16383, 16384, 16385, 32767,
+ 32768, 32769, 65534, 65535, 65536, 65537};
+ if(specs && specs->field_unsigned) {
+ assert(variants[18] == 0);
+ value = variants[asn_random_between(
+ 18, sizeof(variants) / sizeof(variants[0]) - 1)];
+ } else {
+ value = variants[asn_random_between(
+ 0, sizeof(variants) / sizeof(variants[0]) - 1)];
+ }
+
+ if(!constraints) constraints = &td->encoding_constraints;
+ ct = constraints ? &constraints->per_constraints->value : 0;
+ (void)ct;
+ }
+
+
+ if(asn_imax2INTEGER(st, value)) {
+ if(st == *sptr) {
+ ASN_STRUCT_RESET(*td, st);
+ } else {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return result_failed;
+ } else {
+ result_ok.length = st->size;
+ return result_ok;
+ }
+}
diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h
index 2754b4b..70d6a3c 100644
--- a/skeletons/INTEGER.h
+++ b/skeletons/INTEGER.h
@@ -48,6 +48,7 @@
oer_type_encoder_f INTEGER_encode_oer;
per_type_decoder_f INTEGER_decode_uper;
per_type_encoder_f INTEGER_encode_uper;
+asn_random_fill_f INTEGER_random_fill;
/***********************************
* Some handy conversion routines. *
diff --git a/skeletons/INTEGER_oer.c b/skeletons/INTEGER_oer.c
index 240da87..bea2e07 100644
--- a/skeletons/INTEGER_oer.c
+++ b/skeletons/INTEGER_oer.c
@@ -32,7 +32,7 @@
st->buf = 0;
st->size = 0;
- if(!constraints) constraints = td->oer_constraints;
+ if(!constraints) constraints = td->encoding_constraints.oer_constraints;
if(constraints) ct = constraints->value;
if(ct.width) {
@@ -113,7 +113,7 @@
if(!st || st->size == 0) ASN__ENCODE_FAILED;
- if(!constraints) constraints = td->oer_constraints;
+ if(!constraints) constraints = td->encoding_constraints.oer_constraints;
if(constraints) ct = constraints->value;
er.encoded = 0;
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index 6445564..86b128b 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -39,21 +39,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_ISO646String = {
"ISO646String",
"ISO646String",
&asn_OP_ISO646String,
- VisibleString_constraint,
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
/ sizeof(asn_DEF_ISO646String_tags[0]) - 1,
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
/ sizeof(asn_DEF_ISO646String_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_ISO646String_per_constraints,
+ { 0, &asn_DEF_ISO646String_per_constraints, ISO646String_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am
index 3d8ae04..6c66333 100644
--- a/skeletons/Makefile.am
+++ b/skeletons/Makefile.am
@@ -65,6 +65,7 @@
asn_codecs_prim.c asn_codecs_prim.h \
asn_internal.h asn_system.h \
asn_bit_data.c asn_bit_data.h \
+ asn_random_fill.c asn_random_fill.h \
ber_decoder.c ber_decoder.h \
ber_tlv_length.c ber_tlv_length.h \
ber_tlv_tag.c ber_tlv_tag.h \
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index 1354ea4..ed7f853 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -35,19 +35,18 @@
NULL_decode_uper, /* Unaligned PER decoder */
NULL_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ NULL_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NULL = {
"NULL",
"NULL",
&asn_OP_NULL,
- asn_generic_no_constraint,
asn_DEF_NULL_tags,
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
asn_DEF_NULL_tags, /* Same as above */
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -215,3 +214,28 @@
}
#endif /* ASN_DISABLE_PER_SUPPORT */
+
+asn_random_fill_result_t
+NULL_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ NULL_t *st = *sptr;
+
+ (void)td;
+ (void)constr;
+
+ if(max_length == 0) return result_skipped;
+
+ if(st == NULL) {
+ st = (NULL_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ return result_ok;
+}
+
diff --git a/skeletons/NULL.h b/skeletons/NULL.h
index a9bdb9f..050840a 100644
--- a/skeletons/NULL.h
+++ b/skeletons/NULL.h
@@ -30,6 +30,7 @@
oer_type_encoder_f NULL_encode_oer;
per_type_decoder_f NULL_decode_uper;
per_type_encoder_f NULL_encode_uper;
+asn_random_fill_f NULL_random_fill;
#define NULL_free BOOLEAN_free
#define NULL_decode_ber BOOLEAN_decode_ber
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index 137b951..fd24b32 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -40,19 +40,18 @@
NativeEnumerated_decode_uper,
NativeEnumerated_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ NativeEnumerated_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
"ENUMERATED", /* The ASN.1 type is still ENUMERATED */
"ENUMERATED",
&asn_OP_NativeEnumerated,
- asn_generic_no_constraint,
asn_DEF_NativeEnumerated_tags,
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
asn_DEF_NativeEnumerated_tags, /* Same as above */
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -103,7 +102,8 @@
(void)opt_codec_ctx;
if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
+ else if(td->encoding_constraints.per_constraints)
+ ct = &td->encoding_constraints.per_constraints->value;
else ASN__DECODE_FAILED; /* Mandatory! */
if(!specs) ASN__DECODE_FAILED;
@@ -173,7 +173,8 @@
if(!specs) ASN__ENCODE_FAILED;
if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
+ else if(td->encoding_constraints.per_constraints)
+ ct = &td->encoding_constraints.per_constraints->value;
else ASN__ENCODE_FAILED; /* Mandatory! */
ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
diff --git a/skeletons/NativeEnumerated.h b/skeletons/NativeEnumerated.h
index fb4b588..dc4e323 100644
--- a/skeletons/NativeEnumerated.h
+++ b/skeletons/NativeEnumerated.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
@@ -31,6 +31,7 @@
#define NativeEnumerated_free NativeInteger_free
#define NativeEnumerated_print NativeInteger_print
#define NativeEnumerated_compare NativeInteger_compare
+#define NativeEnumerated_random_fill NativeInteger_random_fill
#define NativeEnumerated_constraint asn_generic_no_constraint
#define NativeEnumerated_decode_ber NativeInteger_decode_ber
#define NativeEnumerated_encode_der NativeInteger_encode_der
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index 5ba65e1..dd40fef 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -41,19 +41,18 @@
NativeInteger_decode_uper, /* Unaligned PER decoder */
NativeInteger_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ NativeInteger_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
"INTEGER", /* The ASN.1 type is still INTEGER */
"INTEGER",
&asn_OP_NativeInteger,
- asn_generic_no_constraint,
asn_DEF_NativeInteger_tags,
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
asn_DEF_NativeInteger_tags, /* Same as above */
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -409,3 +408,71 @@
return 1;
}
}
+
+asn_random_fill_result_t
+NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ const asn_INTEGER_specifics_t *specs =
+ (const asn_INTEGER_specifics_t *)td->specifics;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ long *st = *sptr;
+ const asn_INTEGER_enum_map_t *emap;
+ size_t emap_len;
+ intmax_t value;
+ int find_inside_map;
+
+ if(max_length == 0) return result_skipped;
+
+ if(st == NULL) {
+ st = (long *)CALLOC(1, sizeof(*st));
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ if(specs) {
+ emap = specs->value2enum;
+ emap_len = specs->map_count;
+ if(specs->strict_enumeration) {
+ find_inside_map = emap_len > 0;
+ } else {
+ find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
+ }
+ } else {
+ emap = 0;
+ emap_len = 0;
+ find_inside_map = 0;
+ }
+
+ if(find_inside_map) {
+ assert(emap_len > 0);
+ value = emap[asn_random_between(0, emap_len - 1)].nat_value;
+ } else {
+ const asn_per_constraint_t *ct;
+
+ static const long variants[] = {
+ -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
+ -16383, -257, -256, -255, -254, -129, -128, -127,
+ -126, -1, 0, 1, 126, 127, 128, 129,
+ 254, 255, 256, 257, 16383, 16384, 16385, 32767,
+ 32768, 32769, 65534, 65535, 65536, 65537};
+ if(specs && specs->field_unsigned) {
+ assert(variants[18] == 0);
+ value = variants[asn_random_between(
+ 18, sizeof(variants) / sizeof(variants[0]) - 1)];
+ } else {
+ value = variants[asn_random_between(
+ 0, sizeof(variants) / sizeof(variants[0]) - 1)];
+ }
+
+ if(!constraints) constraints = &td->encoding_constraints;
+ ct = constraints ? &constraints->per_constraints->value : 0;
+ (void)ct;
+ }
+
+ *st = value;
+ return result_ok;
+}
diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h
index 19ff2c8..17a6486 100644
--- a/skeletons/NativeInteger.h
+++ b/skeletons/NativeInteger.h
@@ -33,6 +33,7 @@
oer_type_encoder_f NativeInteger_encode_oer;
per_type_decoder_f NativeInteger_decode_uper;
per_type_encoder_f NativeInteger_encode_uper;
+asn_random_fill_f NativeInteger_random_fill;
#define NativeInteger_constraint asn_generic_no_constraint
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index 1983a3b..aba278c 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -61,19 +61,18 @@
NativeReal_decode_uper,
NativeReal_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ NativeReal_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NativeReal = {
"REAL", /* The ASN.1 type is still REAL */
"REAL",
&asn_OP_NativeReal,
- asn_generic_no_constraint,
asn_DEF_NativeReal_tags,
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
asn_DEF_NativeReal_tags, /* Same as above */
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -422,3 +421,36 @@
}
}
+
+asn_random_fill_result_t
+NativeReal_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static const double values[] = {0, -0.0, -1, 1, INFINITY, -INFINITY, NAN};
+ double *st;
+ double d;
+
+ (void)td;
+ (void)constraints;
+
+ if(max_length == 0) return result_skipped;
+
+ d = values[asn_random_between(0, sizeof(values) / sizeof(values[0]) - 1)];
+
+ if(*sptr) {
+ st = *sptr;
+ } else {
+ st = (double *)(*sptr = CALLOC(1, sizeof(double)));
+ if(!st) {
+ return result_failed;
+ }
+ }
+
+ *st = d;
+
+ result_ok.length = sizeof(double);
+ return result_ok;
+}
diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h
index cfdd1bd..b373923 100644
--- a/skeletons/NativeReal.h
+++ b/skeletons/NativeReal.h
@@ -29,6 +29,7 @@
xer_type_encoder_f NativeReal_encode_xer;
per_type_decoder_f NativeReal_decode_uper;
per_type_encoder_f NativeReal_encode_uper;
+asn_random_fill_f NativeReal_random_fill;
#define NativeReal_constraint asn_generic_no_constraint
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index 4dd4c2f..891e4f5 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -59,21 +59,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NumericString = {
"NumericString",
"NumericString",
&asn_OP_NumericString,
- NumericString_constraint,
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
/ sizeof(asn_DEF_NumericString_tags[0]) - 1,
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
/ sizeof(asn_DEF_NumericString_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_NumericString_per_constraints,
+ { 0, &asn_DEF_NumericString_per_constraints, NumericString_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index c0142ee..e7478a0 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -37,21 +37,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OBJECT_IDENTIFIER_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
"OBJECT IDENTIFIER",
"OBJECT_IDENTIFIER",
&asn_OP_OBJECT_IDENTIFIER,
- OBJECT_IDENTIFIER_constraint,
asn_DEF_OBJECT_IDENTIFIER_tags,
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, OBJECT_IDENTIFIER_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -781,4 +780,61 @@
return -1;
}
+/*
+ * Generate values from the list of interesting values, or just a random
+ * value up to the upper limit.
+ */
+static uint32_t
+OBJECT_IDENTIFIER__biased_random_arc(int32_t upper_bound) {
+ static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
+ size_t idx = asn_random_between(0, 2 * sizeof(values)/sizeof(values[0]));
+ if(idx < sizeof(values) / sizeof(values[0])) {
+ if(values[idx] < upper_bound) {
+ return values[idx];
+ }
+ }
+
+ return asn_random_between(0, upper_bound);
+}
+
+asn_random_fill_result_t
+OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ OBJECT_IDENTIFIER_t *st;
+ uint32_t arcs[5];
+ size_t arcs_len = asn_random_between(2, 5);
+ size_t i;
+
+ (void)constraints;
+
+ if(max_length < arcs_len) return result_skipped;
+
+ if(*sptr) {
+ st = *sptr;
+ } else {
+ st = CALLOC(1, sizeof(*st));
+ }
+
+ arcs[0] = asn_random_between(0, 2);
+ arcs[1] =
+ OBJECT_IDENTIFIER__biased_random_arc(arcs[0] <= 1 ? 39 : INT32_MAX);
+ for(i = 2; i < arcs_len; i++) {
+ arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(INT32_MAX);
+ }
+
+ if(OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
+ if(st != *sptr) {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return result_failed;
+ }
+
+ *sptr = st;
+
+ return result_ok;
+}
diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h
index 2501a54..02dde9c 100644
--- a/skeletons/OBJECT_IDENTIFIER.h
+++ b/skeletons/OBJECT_IDENTIFIER.h
@@ -24,6 +24,7 @@
der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer;
xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
+asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
#define OBJECT_IDENTIFIER_free ASN__PRIMITIVE_TYPE_free
#define OBJECT_IDENTIFIER_compare OCTET_STRING_compare
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 2f2efc4..05ef112 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -42,21 +42,20 @@
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
"OCTET STRING", /* Canonical name */
"OCTET_STRING", /* XML tag name */
&asn_OP_OCTET_STRING,
- asn_generic_no_constraint,
asn_DEF_OCTET_STRING_tags,
sizeof(asn_DEF_OCTET_STRING_tags)
/ sizeof(asn_DEF_OCTET_STRING_tags[0]),
asn_DEF_OCTET_STRING_tags, /* Same as above */
sizeof(asn_DEF_OCTET_STRING_tags)
/ sizeof(asn_DEF_OCTET_STRING_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
&asn_SPC_OCTET_STRING_specs
};
@@ -1353,7 +1352,7 @@
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_SPC_OCTET_STRING_specs;
const asn_per_constraints_t *pc =
- constraints ? constraints : td->per_constraints;
+ constraints ? constraints : td->encoding_constraints.per_constraints;
const asn_per_constraint_t *cval;
const asn_per_constraint_t *csiz;
asn_dec_rval_t rval = { RC_OK, 0 };
@@ -1524,7 +1523,7 @@
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_SPC_OCTET_STRING_specs;
const asn_per_constraints_t *pc = constraints ? constraints
- : td->per_constraints;
+ : td->encoding_constraints.per_constraints;
const asn_per_constraint_t *cval;
const asn_per_constraint_t *csiz;
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
@@ -1834,11 +1833,12 @@
}
OCTET_STRING_t *
-OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_SPC_OCTET_STRING_specs;
- OCTET_STRING_t *st;
+OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str,
+ int len) {
+ const asn_OCTET_STRING_specifics_t *specs =
+ td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_SPC_OCTET_STRING_specs;
+ OCTET_STRING_t *st;
st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
@@ -1898,3 +1898,146 @@
}
+/*
+ * Biased function for randomizing character values around their limits.
+ */
+static uint32_t
+OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
+ assert(lb <= ub);
+ switch(asn_random_between(0, 16)) {
+ case 0:
+ if(lb < ub) return lb + 1;
+ /* Fall through */
+ case 1:
+ return lb;
+ case 2:
+ if(lb < ub) return ub - 1;
+ /* Fall through */
+ case 3:
+ return ub;
+ default:
+ return asn_random_between(lb, ub);
+ }
+}
+
+asn_random_fill_result_t
+OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_SPC_OCTET_STRING_specs;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
+ 126, 127, 128, 16383, 16384, 16385,
+ 65534, 65535, 65536, 65537};
+ unsigned int unit_bytes = 1;
+ unsigned long clb = 0; /* Lower bound on char */
+ unsigned long cub = 255; /* Higher bound on char value */
+ uint8_t *buf;
+ uint8_t *bend;
+ uint8_t *b;
+ size_t rnd_len;
+ OCTET_STRING_t *st;
+
+ if(max_length == 0) return result_skipped;
+
+ switch(specs->subvariant) {
+ default:
+ case ASN_OSUBV_ANY:
+ return result_failed;
+ case ASN_OSUBV_BIT:
+ /* Handled by BIT_STRING itself. */
+ return result_failed;
+ case ASN_OSUBV_STR:
+ unit_bytes = 1;
+ clb = 0;
+ cub = 255;
+ break;
+ case ASN_OSUBV_U16:
+ unit_bytes = 2;
+ clb = 0;
+ cub = 65535;
+ break;
+ case ASN_OSUBV_U32:
+ unit_bytes = 4;
+ clb = 0;
+ cub = 0x10FFFF;
+ break;
+ }
+
+ if(!constraints) constraints = &td->encoding_constraints;
+ if(constraints->per_constraints) {
+ const asn_per_constraint_t *pc =
+ &td->encoding_constraints.per_constraints->value;
+ if(pc->flags & APC_SEMI_CONSTRAINED) {
+ clb = pc->lower_bound;
+ } else if(pc->flags & APC_CONSTRAINED) {
+ clb = pc->lower_bound;
+ cub = pc->upper_bound;
+ }
+ }
+
+ /* Figure out how far we should go */
+ rnd_len = lengths[asn_random_between(
+ 0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
+ if(constraints->per_constraints) {
+ const asn_per_constraint_t *pc =
+ &td->encoding_constraints.per_constraints->size;
+ if(pc->flags & APC_CONSTRAINED) {
+ if(max_length < (size_t)pc->lower_bound) {
+ return result_skipped;
+ }
+ rnd_len = asn_random_between(pc->lower_bound, pc->upper_bound);
+ } else {
+ rnd_len = asn_random_between(0, max_length - 1);
+ }
+ } else if(rnd_len >= max_length) {
+ rnd_len = asn_random_between(0, max_length - 1);
+ }
+
+ buf = CALLOC(unit_bytes, rnd_len + 1);
+ if(!buf) return result_failed;
+
+ bend = &buf[unit_bytes * rnd_len];
+
+ switch(unit_bytes) {
+ case 1:
+ for(b = buf; b < bend; b += unit_bytes) {
+ *(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
+ }
+ *(uint8_t *)b = 0;
+ break;
+ case 2:
+ for(b = buf; b < bend; b += unit_bytes) {
+ *(uint16_t *)b = OCTET_STRING__random_char(clb, cub);
+ }
+ *(uint16_t *)b = 0;
+ break;
+ case 4:
+ for(b = buf; b < bend; b += unit_bytes) {
+ *(uint32_t *)b = OCTET_STRING__random_char(clb, cub);
+ }
+ *(uint32_t *)b = 0;
+ break;
+ }
+
+ if(*sptr) {
+ st = *sptr;
+ FREEMEM(st->buf);
+ } else {
+ st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(!st) {
+ FREEMEM(buf);
+ return result_failed;
+ }
+ }
+
+ st->buf = buf;
+ st->size = unit_bytes * rnd_len;
+
+ result_ok.length = st->size;
+ return result_ok;
+}
diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h
index 211bc14..ade23bf 100644
--- a/skeletons/OCTET_STRING.h
+++ b/skeletons/OCTET_STRING.h
@@ -36,6 +36,7 @@
oer_type_encoder_f OCTET_STRING_encode_oer;
per_type_decoder_f OCTET_STRING_decode_uper;
per_type_encoder_f OCTET_STRING_encode_uper;
+asn_random_fill_f OCTET_STRING_random_fill;
#define OCTET_STRING_constraint asn_generic_no_constraint
#define OCTET_STRING_decode_xer OCTET_STRING_decode_xer_hex
@@ -63,8 +64,8 @@
* allocated object. NULL is permitted in str: the function will just allocate
* empty OCTET STRING.
*/
-OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
- const char *str, int size);
+OCTET_STRING_t *OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td,
+ const char *str, int size);
/****************************
* Internally useful stuff. *
diff --git a/skeletons/OCTET_STRING_oer.c b/skeletons/OCTET_STRING_oer.c
index 4ea705a..646ce68 100644
--- a/skeletons/OCTET_STRING_oer.c
+++ b/skeletons/OCTET_STRING_oer.c
@@ -20,7 +20,7 @@
: (asn_OCTET_STRING_specifics_t *)&asn_SPC_OCTET_STRING_specs;
OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
const asn_oer_constraints_t *cts =
- constraints ? constraints : td->oer_constraints;
+ constraints ? constraints : td->encoding_constraints.oer_constraints;
ssize_t ct_size = cts ? cts->size : -1;
asn_dec_rval_t rval = {RC_OK, 0};
size_t expected_length = 0;
@@ -110,7 +110,7 @@
: (asn_OCTET_STRING_specifics_t *)&asn_SPC_OCTET_STRING_specs;
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
const asn_oer_constraints_t *cts =
- constraints ? constraints : td->oer_constraints;
+ constraints ? constraints : td->encoding_constraints.oer_constraints;
ssize_t ct_size = cts ? cts->size : -1;
asn_enc_rval_t er = {0, 0, 0};
diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c
index 9417d9a..e490504 100644
--- a/skeletons/OPEN_TYPE.c
+++ b/skeletons/OPEN_TYPE.c
@@ -23,6 +23,7 @@
OPEN_TYPE_decode_uper,
OPEN_TYPE_encode_uper,
#endif
+ 0, /* Random fill is not supported for open type */
0, /* Use generic outmost tag fetcher */
};
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 145e24a..79042c0 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ 0, /* Not supported for ObjectDescriptor */
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
"ObjectDescriptor",
"ObjectDescriptor",
&asn_OP_ObjectDescriptor,
- asn_generic_unknown_constraint,
asn_DEF_ObjectDescriptor_tags,
sizeof(asn_DEF_ObjectDescriptor_tags)
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]) - 1,
asn_DEF_ObjectDescriptor_tags,
sizeof(asn_DEF_ObjectDescriptor_tags)
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index 7c634f1..0cf1741 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -69,21 +69,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_PrintableString = {
"PrintableString",
"PrintableString",
&asn_OP_PrintableString,
- PrintableString_constraint,
asn_DEF_PrintableString_tags,
sizeof(asn_DEF_PrintableString_tags)
/ sizeof(asn_DEF_PrintableString_tags[0]) - 1,
asn_DEF_PrintableString_tags,
sizeof(asn_DEF_PrintableString_tags)
/ sizeof(asn_DEF_PrintableString_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_PrintableString_per_constraints,
+ { 0, &asn_DEF_PrintableString_per_constraints, PrintableString_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index cc7d641..53961a4 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004-2013 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#define _ISOC99_SOURCE /* For ilogb() and quiet NAN */
@@ -88,19 +88,18 @@
REAL_decode_uper,
REAL_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ REAL_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_REAL = {
"REAL",
"REAL",
&asn_OP_REAL,
- asn_generic_no_constraint,
asn_DEF_REAL_tags,
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
asn_DEF_REAL_tags, /* Same as above */
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0,
0, /* No members */
0 /* No specifics */
@@ -848,3 +847,43 @@
}
#endif /* ASN_DISABLE_PER_SUPPORT */
+
+
+asn_random_fill_result_t
+REAL_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static const double values[] = {0, -0.0, -1, 1, INFINITY, -INFINITY, NAN};
+ REAL_t *st;
+ double d;
+
+ (void)constraints;
+
+ if(max_length == 0) return result_skipped;
+
+ d = values[asn_random_between(0, sizeof(values) / sizeof(values[0]) - 1)];
+
+ if(*sptr) {
+ st = *sptr;
+ } else {
+ st = (REAL_t*)(*sptr = CALLOC(1, sizeof(REAL_t)));
+ if(!st) {
+ return result_failed;
+ }
+ }
+
+ if(asn_double2REAL(st, d)) {
+ if(st == *sptr) {
+ ASN_STRUCT_RESET(*td, st);
+ } else {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return result_failed;
+ }
+
+ result_ok.length = st->size;
+ return result_ok;
+}
diff --git a/skeletons/REAL.h b/skeletons/REAL.h
index 8bc0623..6c26ef1 100644
--- a/skeletons/REAL.h
+++ b/skeletons/REAL.h
@@ -23,6 +23,7 @@
xer_type_encoder_f REAL_encode_xer;
per_type_decoder_f REAL_decode_uper;
per_type_encoder_f REAL_encode_uper;
+asn_random_fill_f REAL_random_fill;
#define REAL_free ASN__PRIMITIVE_TYPE_free,
#define REAL_constraint asn_generic_no_constraint
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 82850f1..6edecfa 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
@@ -38,21 +38,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ RELATIVE_OID_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
"RELATIVE-OID",
"RELATIVE_OID",
&asn_OP_RELATIVE_OID,
- asn_generic_no_constraint,
asn_DEF_RELATIVE_OID_tags,
sizeof(asn_DEF_RELATIVE_OID_tags)
/ sizeof(asn_DEF_RELATIVE_OID_tags[0]),
asn_DEF_RELATIVE_OID_tags, /* Same as above */
sizeof(asn_DEF_RELATIVE_OID_tags)
/ sizeof(asn_DEF_RELATIVE_OID_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_no_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -255,3 +254,56 @@
return 0;
}
+
+/*
+ * Generate values from the list of interesting values, or just a random value.
+ */
+static uint32_t
+RELATIVE_OID__biased_random_arc() {
+ static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
+
+ size_t idx = asn_random_between(0, 2 * sizeof(values)/sizeof(values[0]));
+ if(idx < sizeof(values) / sizeof(values[0])) {
+ return values[idx];
+ }
+
+ return asn_random_between(0, INT32_MAX);
+}
+
+asn_random_fill_result_t
+RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ RELATIVE_OID_t *st;
+ uint32_t arcs[3];
+ size_t arcs_len = asn_random_between(0, 3);
+ size_t i;
+
+ (void)constraints;
+
+ if(max_length < arcs_len) return result_skipped;
+
+ if(*sptr) {
+ st = *sptr;
+ } else {
+ st = CALLOC(1, sizeof(*st));
+ }
+
+ for(i = 0; i < arcs_len; i++) {
+ arcs[i] = RELATIVE_OID__biased_random_arc();
+ }
+
+ if(RELATIVE_OID_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
+ if(st != *sptr) {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return result_failed;
+ }
+
+ *sptr = st;
+
+ return result_ok;
+}
diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h
index 4a73d27..f24c392 100644
--- a/skeletons/RELATIVE-OID.h
+++ b/skeletons/RELATIVE-OID.h
@@ -20,6 +20,7 @@
asn_struct_print_f RELATIVE_OID_print;
xer_type_decoder_f RELATIVE_OID_decode_xer;
xer_type_encoder_f RELATIVE_OID_encode_xer;
+asn_random_fill_f RELATIVE_OID_random_fill;
#define RELATIVE_OID_free ASN__PRIMITIVE_TYPE_free
#define RELATIVE_OID_compare OCTET_STRING_compare
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index efb7df8..c7e5f00 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_T61String = {
"T61String",
"T61String",
&asn_OP_T61String,
- asn_generic_unknown_constraint,
asn_DEF_T61String_tags,
sizeof(asn_DEF_T61String_tags)
/ sizeof(asn_DEF_T61String_tags[0]) - 1,
asn_DEF_T61String_tags,
sizeof(asn_DEF_T61String_tags)
/ sizeof(asn_DEF_T61String_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index 31f8433..6c13f73 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_TeletexString = {
"TeletexString",
"TeletexString",
&asn_OP_TeletexString,
- asn_generic_unknown_constraint,
asn_DEF_TeletexString_tags,
sizeof(asn_DEF_TeletexString_tags)
/ sizeof(asn_DEF_TeletexString_tags[0]) - 1,
asn_DEF_TeletexString_tags,
sizeof(asn_DEF_TeletexString_tags)
/ sizeof(asn_DEF_TeletexString_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index 32c5817..55c7506 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -50,21 +50,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ UTCTime_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_UTCTime = {
"UTCTime",
"UTCTime",
&asn_OP_UTCTime,
- UTCTime_constraint,
asn_DEF_UTCTime_tags,
sizeof(asn_DEF_UTCTime_tags)
/ sizeof(asn_DEF_UTCTime_tags[0]) - 2,
asn_DEF_UTCTime_tags,
sizeof(asn_DEF_UTCTime_tags)
/ sizeof(asn_DEF_UTCTime_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_UTCTime_constraints,
+ { 0, &asn_DEF_UTCTime_constraints, UTCTime_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -194,3 +193,35 @@
return (UTCTime_t *)gt;
}
+
+asn_random_fill_result_t
+UTCTime_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static const char *values[] = {
+ "700101000000", "700101000000-0000", "700101000000+0000",
+ "700101000000Z", "821106210623", "691106210827-0500",
+ "821106210629Z",
+ };
+ size_t rnd = asn_random_between(0, sizeof(values)/sizeof(values[0])-1);
+
+ (void)constraints;
+
+ if(max_length < sizeof("yymmddhhmmss")) {
+ return result_skipped;
+ }
+
+ if(*sptr) {
+ if(OCTET_STRING_fromBuf(*sptr, values[rnd], -1) != 0) {
+ if(!sptr) return result_failed;
+ }
+ } else {
+ *sptr = OCTET_STRING_new_fromBuf(td, values[rnd], -1);
+ if(!sptr) return result_failed;
+ }
+
+ return result_ok;
+}
diff --git a/skeletons/UTCTime.h b/skeletons/UTCTime.h
index 5537020..629bf06 100644
--- a/skeletons/UTCTime.h
+++ b/skeletons/UTCTime.h
@@ -19,6 +19,7 @@
asn_struct_print_f UTCTime_print;
asn_constr_check_f UTCTime_constraint;
xer_type_encoder_f UTCTime_encode_xer;
+asn_random_fill_f UTCTime_random_fill;
#define UTCTime_free OCTET_STRING_free
#define UTCTime_compare OCTET_STRING_compare
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index 7a6de6d..7d7cd8b 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -35,21 +35,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ UTF8String_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_UTF8String = {
"UTF8String",
"UTF8String",
&asn_OP_UTF8String,
- UTF8String_constraint, /* Check for invalid codes, etc. */
asn_DEF_UTF8String_tags,
sizeof(asn_DEF_UTF8String_tags)
/ sizeof(asn_DEF_UTF8String_tags[0]) - 1,
asn_DEF_UTF8String_tags,
sizeof(asn_DEF_UTF8String_tags)
/ sizeof(asn_DEF_UTF8String_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, UTF8String_constraint },
0, 0, /* No members */
0 /* No specifics */
};
@@ -199,3 +198,100 @@
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
}
}
+
+
+/*
+ * Biased function for randomizing UTF-8 sequences.
+ */
+static uint32_t
+UTF8String__random_char(uint8_t *b, size_t size) {
+ struct rnd_value {
+ const char *value;
+ size_t size;
+ };
+ static const struct rnd_value values[] = {{"\0", 1},
+ {"\x01", 1},
+ {"\x7f", 1},
+ {"\xc2\xa2", 2},
+ {"\xe2\x82\xac", 3},
+ {"\xf0\x90\x8d\x88", 4},
+ {"\xf4\x8f\xbf\xbf", 4}};
+
+ const struct rnd_value *v;
+ size_t max_idx;
+
+ switch(size) {
+ case 0:
+ assert(size != 0);
+ return 0;
+ case 1:
+ max_idx = 2;
+ break;
+ case 2:
+ max_idx = 3;
+ break;
+ case 4:
+ return sizeof(values) / sizeof(values[0]) - 1;
+ }
+
+ v = &values[asn_random_between(0, max_idx)];
+ memcpy(b, v->value, v->size);
+ return v->size;
+}
+
+asn_random_fill_result_t
+UTF8String_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
+ 126, 127, 128, 16383, 16384, 16385,
+ 65534, 65535, 65536, 65537};
+ uint8_t *buf;
+ uint8_t *bend;
+ uint8_t *b;
+ size_t rnd_len;
+ size_t idx;
+ UTF8String_t *st;
+
+ (void)td;
+ (void)constraints;
+
+ if(max_length == 0) return result_skipped;
+
+ /* Figure out how far we should go */
+ rnd_len = lengths[asn_random_between(
+ 0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
+ if(4 * rnd_len >= max_length) {
+ rnd_len = asn_random_between(0, (max_length - 1) / 4);
+ }
+
+ buf = CALLOC(4, rnd_len + 1);
+ if(!buf) return result_failed;
+
+ bend = &buf[4 * rnd_len];
+
+ for(b = buf, idx = 0; idx < rnd_len; idx++) {
+ b += UTF8String__random_char(b, (bend - b));
+ }
+ *(uint8_t *)b = 0;
+
+ if(*sptr) {
+ st = *sptr;
+ FREEMEM(st->buf);
+ } else {
+ st = (OCTET_STRING_t *)(*sptr = CALLOC(1, sizeof(UTF8String_t)));
+ if(!st) {
+ FREEMEM(buf);
+ return result_failed;
+ }
+ }
+ assert(UTF8String_length(st) == (ssize_t)rnd_len);
+
+ st->buf = buf;
+ st->size = b - buf;
+
+ return result_ok;
+}
diff --git a/skeletons/UTF8String.h b/skeletons/UTF8String.h
index 1853573..4deec26 100644
--- a/skeletons/UTF8String.h
+++ b/skeletons/UTF8String.h
@@ -18,6 +18,7 @@
asn_struct_print_f UTF8String_print;
asn_constr_check_f UTF8String_constraint;
+asn_random_fill_f UTF8String_random_fill;
#define UTF8String_free OCTET_STRING_free
#define UTF8String_compare OCTET_STRING_compare
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 453c6a8..8d99cad 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -45,21 +45,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_UniversalString = {
"UniversalString",
"UniversalString",
&asn_OP_UniversalString,
- UniversalString_constraint,
asn_DEF_UniversalString_tags,
sizeof(asn_DEF_UniversalString_tags)
/ sizeof(asn_DEF_UniversalString_tags[0]) - 1,
asn_DEF_UniversalString_tags,
sizeof(asn_DEF_UniversalString_tags)
/ sizeof(asn_DEF_UniversalString_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_UniversalString_per_constraints,
+ { 0, &asn_DEF_UniversalString_per_constraints, UniversalString_constraint },
0, 0, /* No members */
&asn_SPC_UniversalString_specs
};
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index 6e4fc36..06fe4a7 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -34,21 +34,20 @@
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_VideotexString = {
"VideotexString",
"VideotexString",
&asn_OP_VideotexString,
- asn_generic_unknown_constraint,
asn_DEF_VideotexString_tags,
sizeof(asn_DEF_VideotexString_tags)
/ sizeof(asn_DEF_VideotexString_tags[0]) - 1,
asn_DEF_VideotexString_tags,
sizeof(asn_DEF_VideotexString_tags)
/ sizeof(asn_DEF_VideotexString_tags[0]),
- 0, /* No OER visible constraints */
- 0, /* No PER visible constraints */
+ { 0, 0, asn_generic_unknown_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index f8d651b..fe2762f 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -39,21 +39,20 @@
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ OCTET_STRING_random_fill,
0 /* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_VisibleString = {
"VisibleString",
"VisibleString",
&asn_OP_VisibleString,
- VisibleString_constraint,
asn_DEF_VisibleString_tags,
sizeof(asn_DEF_VisibleString_tags)
/ sizeof(asn_DEF_VisibleString_tags[0]) - 1,
asn_DEF_VisibleString_tags,
sizeof(asn_DEF_VisibleString_tags)
/ sizeof(asn_DEF_VisibleString_tags[0]),
- 0, /* No OER visible constraints */
- &asn_DEF_VisibleString_constraints,
+ { 0, &asn_DEF_VisibleString_constraints, VisibleString_constraint },
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/asn_application.c b/skeletons/asn_application.c
index 46f1aa8..b558d46 100644
--- a/skeletons/asn_application.c
+++ b/skeletons/asn_application.c
@@ -151,6 +151,35 @@
}
switch(syntax) {
+ case ATS_NONSTANDARD_PLAINTEXT:
+ if(td->op->print_struct) {
+ struct callback_count_bytes_key cb_key;
+ cb_key.callback = callback;
+ cb_key.callback_key = callback_key;
+ cb_key.computed_size = 0;
+ if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb,
+ &cb_key)
+ < 0
+ || callback_count_bytes_cb("\n", 1, &cb_key) < 0) {
+ errno = EBADF; /* Structure has incorrect form. */
+ er.encoded = -1;
+ er.failed_type = td;
+ er.structure_ptr = sptr;
+ } else {
+ er.encoded = cb_key.computed_size;
+ er.failed_type = 0;
+ er.structure_ptr = 0;
+ }
+ } else {
+ errno = ENOENT; /* Transfer syntax is not defined for this type. */
+ ASN__ENCODE_FAILED;
+ }
+ break;
+
+ case ATS_RANDOM:
+ errno = ENOENT; /* Randomization doesn't make sense on output. */
+ ASN__ENCODE_FAILED;
+
case ATS_BER:
/* BER is a superset of DER. */
/* Fall through. */
@@ -260,31 +289,6 @@
}
break;
- case ATS_NONSTANDARD_PLAINTEXT:
- if(td->op->print_struct) {
- struct callback_count_bytes_key cb_key;
- cb_key.callback = callback;
- cb_key.callback_key = callback_key;
- cb_key.computed_size = 0;
- if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb,
- &cb_key)
- < 0
- || callback_count_bytes_cb("\n", 1, &cb_key) < 0) {
- errno = EBADF; /* Structure has incorrect form. */
- er.encoded = -1;
- er.failed_type = td;
- er.structure_ptr = sptr;
- } else {
- er.encoded = cb_key.computed_size;
- er.failed_type = 0;
- er.structure_ptr = 0;
- }
- } else {
- errno = ENOENT; /* Transfer syntax is not defined for this type. */
- ASN__ENCODE_FAILED;
- }
- break;
-
default:
errno = ENOENT;
ASN__ENCODE_FAILED;
@@ -298,7 +302,7 @@
enum asn_transfer_syntax syntax, struct asn_TYPE_descriptor_s *td,
void **sptr, const void *buffer, size_t size) {
- if(!td || !sptr || (size && !buffer)) {
+ if(!td || !td->op || !sptr || (size && !buffer)) {
ASN__DECODE_FAILED;
}
@@ -309,6 +313,19 @@
errno = ENOENT;
ASN__DECODE_FAILED;
+ case ATS_RANDOM:
+ if(!td->op->random_fill) {
+ ASN__DECODE_FAILED;
+ } else {
+ if(asn_random_fill(td, sptr, 16000) == 0) {
+ asn_dec_rval_t ret = {RC_OK, 0};
+ return ret;
+ } else {
+ ASN__DECODE_FAILED;
+ }
+ }
+ break;
+
case ATS_DER:
case ATS_BER:
return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
diff --git a/skeletons/asn_application.h b/skeletons/asn_application.h
index b8b0b9e..d75a2ce 100644
--- a/skeletons/asn_application.h
+++ b/skeletons/asn_application.h
@@ -22,8 +22,10 @@
enum asn_transfer_syntax {
/* Avoid appearance of a default transfer syntax. */
ATS_INVALID = 0,
- /* Plaintext output, useful for debugging. */
+ /* Plaintext output (not conforming to any standard), for debugging. */
ATS_NONSTANDARD_PLAINTEXT,
+ /* Returns a randomly generatede structure. */
+ ATS_RANDOM,
/*
* X.690:
* BER: Basic Encoding Rules.
diff --git a/skeletons/asn_random_fill.c b/skeletons/asn_random_fill.c
new file mode 100644
index 0000000..39e7eaa
--- /dev/null
+++ b/skeletons/asn_random_fill.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+
+#include <asn_internal.h>
+#include <asn_random_fill.h>
+#include <constr_TYPE.h>
+
+int
+asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
+ size_t length) {
+
+ if(td && td->op->random_fill) {
+ asn_random_fill_result_t res =
+ td->op->random_fill(td, struct_ptr, 0, length);
+ return (res.code == ARFILL_OK) ? 0 : -1;
+ } else {
+ return -1;
+ }
+}
+
+intmax_t
+asn_random_between(intmax_t a, intmax_t b) {
+ assert(a <= b);
+ assert((b-a) < RAND_MAX);
+ if(a == b) return a;
+ return a + (random() % (b - a));
+}
diff --git a/skeletons/asn_random_fill.h b/skeletons/asn_random_fill.h
new file mode 100644
index 0000000..bfaa13e
--- /dev/null
+++ b/skeletons/asn_random_fill.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_RANDOM_FILL
+#define ASN_RANDOM_FILL
+
+/* Forward declarations */
+struct asn_TYPE_descriptor_s;
+struct asn_encoding_constraints_s;
+
+/*
+ * Initialize a structure with random data according to the type specification
+ * and optional member constraints.
+ * ARGUMENTS:
+ * (max_length) - See (approx_max_length_limit).
+ * (memb_constraints) - Member constraints, if exist.
+ * The type can be constrained differently according
+ * to PER and OER specifications, so we find a value
+ * at the intersection of these constraints.
+ * In case the return differs from ARFILL_OK, the (struct_ptr) contents
+ * and (current_length) value remain in their original state.
+ */
+typedef struct asn_random_fill_result_s {
+ enum {
+ ARFILL_FAILED = -1, /* System error (memory?) */
+ ARFILL_OK = 0, /* Initialization succeeded */
+ ARFILL_SKIPPED = 1 /* Not done due to (length?) constraint */
+ } code;
+ size_t length; /* Approximate number of bytes created. */
+} asn_random_fill_result_t;
+typedef asn_random_fill_result_t(asn_random_fill_f)(
+ const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
+ const struct asn_encoding_constraints_s *memb_constraints,
+ size_t max_length);
+
+/*
+ * Returns 0 if the structure was properly initialized, -1 otherwise.
+ * The (approx_max_length_limit) specifies the approximate limit of the
+ * resulting structure in units closely resembling bytes. The actual result
+ * might be several times larger or smaller than the length limit.
+ */
+int asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
+ size_t approx_max_length_limit);
+
+/*
+ * Returns a random number between min and max.
+ */
+intmax_t asn_random_between(intmax_t min, intmax_t max);
+
+#endif /* ASN_RANDOM_FILL */
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index d99e1bd..b4b5c88 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -516,18 +516,12 @@
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
}
- if(elm->memb_constraints) {
- return elm->memb_constraints(elm->type, memb_ptr,
+ if(elm->encoding_constraints.general_constraints) {
+ return elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
ctfailcb, app_key);
} else {
- int ret = elm->type->check_constraints(elm->type,
+ return elm->type->encoding_constraints.general_constraints(elm->type,
memb_ptr, ctfailcb, app_key);
- /*
- * Cannot inherit it eralier:
- * need to make sure we get the updated version.
- */
- elm->memb_constraints = elm->type->check_constraints;
- return ret;
}
} else {
ASN__CTFAIL(app_key, td, sptr,
@@ -855,7 +849,7 @@
}
if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
+ else if(td->encoding_constraints.per_constraints) ct = &td->encoding_constraints.per_constraints->value;
else ct = 0;
if(ct && ct->flags & APC_EXTENSIBLE) {
@@ -900,10 +894,10 @@
if(ct && ct->range_bits >= 0) {
rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
+ elm->encoding_constraints.per_constraints, memb_ptr2, pd);
} else {
rv = uper_open_type_get(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
+ elm->encoding_constraints.per_constraints, memb_ptr2, pd);
}
if(rv.code != RC_OK)
@@ -928,7 +922,8 @@
ASN_DEBUG("Encoding %s as CHOICE", td->name);
if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
+ else if(td->encoding_constraints.per_constraints)
+ ct = &td->encoding_constraints.per_constraints->value;
else ct = 0;
present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
@@ -979,7 +974,7 @@
if(per_put_few_bits(po, present_enc, ct->range_bits))
ASN__ENCODE_FAILED;
- return elm->type->op->uper_encoder(elm->type, elm->per_constraints,
+ return elm->type->op->uper_encoder(elm->type, elm->encoding_constraints.per_constraints,
memb_ptr, po);
} else {
asn_enc_rval_t rval;
@@ -987,7 +982,7 @@
ASN__ENCODE_FAILED;
if(uper_put_nsnnwn(po, present_enc - specs->ext_start))
ASN__ENCODE_FAILED;
- if(uper_open_type_put(elm->type, elm->per_constraints,
+ if(uper_open_type_put(elm->type, elm->encoding_constraints.per_constraints,
memb_ptr, po))
ASN__ENCODE_FAILED;
rval.encoded = 0;
@@ -1239,6 +1234,61 @@
return 0;
}
+
+asn_random_fill_result_t
+CHOICE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ const asn_CHOICE_specifics_t *specs =
+ (const asn_CHOICE_specifics_t *)td->specifics;
+ asn_random_fill_result_t res;
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ const asn_TYPE_member_t *elm;
+ unsigned present;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ void *st = *sptr;
+
+ if(max_length == 0) return result_skipped;
+
+ (void)constr;
+
+ if(st == NULL) {
+ st = CALLOC(1, specs->struct_size);
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ present = asn_random_between(1, td->elements_count);
+ elm = &td->elements[present - 1];
+
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ res = elm->type->op->random_fill(elm->type, memb_ptr2,
+ &elm->encoding_constraints, max_length);
+ _set_present_idx(st, specs->pres_offset, specs->pres_size, present);
+ if(res.code == ARFILL_OK) {
+ *sptr = st;
+ } else {
+ if(st == *sptr) {
+ ASN_STRUCT_RESET(*td, st);
+ } else {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ }
+
+ return res;
+}
+
+
asn_TYPE_operation_t asn_OP_CHOICE = {
CHOICE_free,
CHOICE_print,
@@ -1261,5 +1311,6 @@
CHOICE_decode_uper,
CHOICE_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ CHOICE_random_fill,
CHOICE_outmost_tag
};
diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h
index c7e0b90..c23d8e1 100644
--- a/skeletons/constr_CHOICE.h
+++ b/skeletons/constr_CHOICE.h
@@ -52,6 +52,7 @@
per_type_decoder_f CHOICE_decode_uper;
per_type_encoder_f CHOICE_encode_uper;
asn_outmost_tag_f CHOICE_outmost_tag;
+asn_random_fill_f CHOICE_random_fill;
extern asn_TYPE_operation_t asn_OP_CHOICE;
/*
diff --git a/skeletons/constr_CHOICE_oer.c b/skeletons/constr_CHOICE_oer.c
index b975fd1..ed8c761 100644
--- a/skeletons/constr_CHOICE_oer.c
+++ b/skeletons/constr_CHOICE_oer.c
@@ -244,7 +244,7 @@
}
rval = elm->type->op->oer_decoder(opt_codec_ctx, elm->type,
- elm->oer_constraints, memb_ptr2, ptr,
+ elm->encoding_constraints.oer_constraints, memb_ptr2, ptr,
size);
rval.consumed += consumed_myself;
switch(rval.code) {
@@ -353,7 +353,7 @@
ASN__ENCODE_FAILED;
}
- er = elm->type->op->oer_encoder(elm->type, elm->oer_constraints, memb_ptr,
+ er = elm->type->op->oer_encoder(elm->type, elm->encoding_constraints.oer_constraints, memb_ptr,
cb, app_key);
if(er.encoded > 0)
er.encoded += tag_len;
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 4ba4b08..0b9693e 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1059,19 +1059,13 @@
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
}
- if(elm->memb_constraints) {
- int ret = elm->memb_constraints(elm->type, memb_ptr,
+ if(elm->encoding_constraints.general_constraints) {
+ int ret = elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
ctfailcb, app_key);
if(ret) return ret;
} else {
- int ret = elm->type->check_constraints(elm->type,
+ return elm->type->encoding_constraints.general_constraints(elm->type,
memb_ptr, ctfailcb, app_key);
- if(ret) return ret;
- /*
- * Cannot inherit it earlier:
- * need to make sure we get the updated version.
- */
- elm->memb_constraints = elm->type->check_constraints;
}
}
@@ -1178,7 +1172,7 @@
rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
} else {
rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
+ elm->encoding_constraints.per_constraints, memb_ptr2, pd);
}
if(rv.code != RC_OK) {
ASN_DEBUG("Failed decode %s in %s",
@@ -1247,7 +1241,7 @@
ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
rv = uper_open_type_get(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
+ elm->encoding_constraints.per_constraints, memb_ptr2, pd);
if(rv.code != RC_OK) {
FREEMEM(epres);
return rv;
@@ -1345,7 +1339,7 @@
return -1;
/* Encode as open type field */
if(po2 && present && uper_open_type_put(elm->type,
- elm->per_constraints, *memb_ptr2, po2))
+ elm->encoding_constraints.per_constraints, *memb_ptr2, po2))
return -1;
}
@@ -1458,7 +1452,7 @@
continue;
ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
- er = elm->type->op->uper_encoder(elm->type, elm->per_constraints,
+ er = elm->type->op->uper_encoder(elm->type, elm->encoding_constraints.per_constraints,
*memb_ptr2, po);
if(er.encoded == -1)
return er;
@@ -1544,6 +1538,75 @@
SEQUENCE_decode_uper,
SEQUENCE_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ SEQUENCE_random_fill,
0 /* Use generic outmost tag fetcher */
};
+
+asn_random_fill_result_t
+SEQUENCE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ const asn_SEQUENCE_specifics_t *specs =
+ (const asn_SEQUENCE_specifics_t *)td->specifics;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ void *st = *sptr;
+ size_t edx;
+
+ if(max_length == 0) return result_skipped;
+
+ (void)constr;
+
+ if(st == NULL) {
+ st = CALLOC(1, specs->struct_size);
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ const asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ asn_random_fill_result_t tmpres;
+
+ if(elm->optional && asn_random_between(0, 4) == 2) {
+ /* Sometimes decide not to fill the optional value */
+ continue;
+ }
+
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ tmpres = elm->type->op->random_fill(
+ elm->type, memb_ptr2, &elm->encoding_constraints,
+ max_length > result_ok.length ? max_length - result_ok.length : 0);
+ switch(tmpres.code) {
+ case ARFILL_OK:
+ result_ok.length += tmpres.length;
+ continue;
+ case ARFILL_SKIPPED:
+ assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
+ continue;
+ case ARFILL_FAILED:
+ if(st == *sptr) {
+ ASN_STRUCT_RESET(*td, st);
+ } else {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return tmpres;
+ }
+ }
+
+ *sptr = st;
+
+ return result_ok;
+}
+
diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h
index e4d3801..e2df003 100644
--- a/skeletons/constr_SEQUENCE.h
+++ b/skeletons/constr_SEQUENCE.h
@@ -55,6 +55,7 @@
oer_type_encoder_f SEQUENCE_encode_oer;
per_type_decoder_f SEQUENCE_decode_uper;
per_type_encoder_f SEQUENCE_encode_uper;
+asn_random_fill_f SEQUENCE_random_fill;
extern asn_TYPE_operation_t asn_OP_SEQUENCE;
#ifdef __cplusplus
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index a8e20ec..2d278c2 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -157,7 +157,8 @@
ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
if(constraints) ct = &constraints->size;
- else if(td->per_constraints) ct = &td->per_constraints->size;
+ else if(td->encoding_constraints.per_constraints)
+ ct = &td->encoding_constraints.per_constraints->size;
else ct = 0;
/* If extensible constraint, check if size is in root */
@@ -197,7 +198,7 @@
void *memb_ptr = list->array[seq++];
if(!memb_ptr) ASN__ENCODE_FAILED;
er = elm->type->op->uper_encoder(elm->type,
- elm->per_constraints, memb_ptr, po);
+ elm->encoding_constraints.per_constraints, memb_ptr, po);
if(er.encoded == -1)
ASN__ENCODE_FAILED;
}
@@ -228,6 +229,7 @@
SEQUENCE_OF_decode_uper,
SEQUENCE_OF_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
+ SEQUENCE_OF_random_fill,
0 /* Use generic outmost tag fetcher */
};
diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h
index 22d816b..c2acc6a 100644
--- a/skeletons/constr_SEQUENCE_OF.h
+++ b/skeletons/constr_SEQUENCE_OF.h
@@ -25,6 +25,7 @@
#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
#define SEQUENCE_OF_decode_oer SET_OF_decode_oer
#define SEQUENCE_OF_encode_oer SET_OF_encode_oer
+#define SEQUENCE_OF_random_fill SET_OF_random_fill
der_type_encoder_f SEQUENCE_OF_encode_der;
xer_type_encoder_f SEQUENCE_OF_encode_xer;
per_type_encoder_f SEQUENCE_OF_encode_uper;
diff --git a/skeletons/constr_SEQUENCE_oer.c b/skeletons/constr_SEQUENCE_oer.c
index eb5d6d4..ef2cda2 100644
--- a/skeletons/constr_SEQUENCE_oer.c
+++ b/skeletons/constr_SEQUENCE_oer.c
@@ -204,7 +204,7 @@
memb_ptr2 = element_ptrptr(st, elm, &save_memb_ptr);
rval = elm->type->op->oer_decoder(opt_codec_ctx, elm->type,
- elm->oer_constraints,
+ elm->encoding_constraints.oer_constraints,
memb_ptr2, ptr, size);
}
switch(rval.code) {
@@ -328,7 +328,7 @@
case 1: {
/* Read OER open type */
ssize_t ot_size = oer_open_type_get(opt_codec_ctx, elm->type,
- elm->oer_constraints,
+ elm->encoding_constraints.oer_constraints,
memb_ptr2, ptr, size);
if(ot_size > 0) {
ADVANCE(ot_size);
@@ -482,8 +482,9 @@
ASN_DEBUG("OER encoder is not defined for type %s", elm->type->name);
ASN__ENCODE_FAILED;
}
- er = elm->type->op->oer_encoder(elm->type, elm->oer_constraints, memb_ptr,
- cb, app_key);
+ er = elm->type->op->oer_encoder(
+ elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
+ app_key);
if(er.encoded == -1) {
ASN_DEBUG("... while encoding %s member \"%s\"\n", td->name,
elm->name);
@@ -546,7 +547,8 @@
/* Do not encode default value. */
} else {
asn_enc_rval_t er = elm->type->op->oer_encoder(
- elm->type, elm->oer_constraints, memb_ptr, cb, app_key);
+ elm->type, elm->encoding_constraints.oer_constraints,
+ memb_ptr, cb, app_key);
if(er.encoded == -1) {
return er;
}
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 8e614ec..e9a25ae 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -996,19 +996,12 @@
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
}
- if(elm->memb_constraints) {
- int ret = elm->memb_constraints(elm->type, memb_ptr,
- ctfailcb, app_key);
- if(ret) return ret;
+ if(elm->encoding_constraints.general_constraints) {
+ return elm->encoding_constraints.general_constraints(
+ elm->type, memb_ptr, ctfailcb, app_key);
} else {
- int ret = elm->type->check_constraints(elm->type,
- memb_ptr, ctfailcb, app_key);
- if(ret) return ret;
- /*
- * Cannot inherit it earlier:
- * need to make sure we get the updated version.
- */
- elm->memb_constraints = elm->type->check_constraints;
+ return elm->type->encoding_constraints.general_constraints(
+ elm->type, memb_ptr, ctfailcb, app_key);
}
}
@@ -1062,6 +1055,75 @@
0, /* SET_encode_oer */
0, /* SET_decode_uper */
0, /* SET_encode_uper */
+ SET_random_fill,
0 /* Use generic outmost tag fetcher */
};
+
+asn_random_fill_result_t
+SET_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ const asn_SET_specifics_t *specs =
+ (const asn_SET_specifics_t *)td->specifics;
+ asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ void *st = *sptr;
+ size_t edx;
+
+ if(max_length == 0) return result_skipped;
+
+ (void)constr;
+
+ if(st == NULL) {
+ st = CALLOC(1, specs->struct_size);
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ const asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ asn_random_fill_result_t tmpres;
+
+ if(elm->optional && asn_random_between(0, 4) == 2) {
+ /* Sometimes decide not to fill the optional value */
+ continue;
+ }
+
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ tmpres = elm->type->op->random_fill(
+ elm->type, memb_ptr2, &elm->encoding_constraints,
+ max_length > result_ok.length ? max_length - result_ok.length : 0);
+ switch(tmpres.code) {
+ case ARFILL_OK:
+ result_ok.length += tmpres.length;
+ continue;
+ case ARFILL_SKIPPED:
+ assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
+ continue;
+ case ARFILL_FAILED:
+ if(st == *sptr) {
+ ASN_STRUCT_RESET(*td, st);
+ } else {
+ ASN_STRUCT_FREE(*td, st);
+ }
+ return tmpres;
+ }
+ }
+
+ *sptr = st;
+
+ return result_ok;
+}
+
diff --git a/skeletons/constr_SET.h b/skeletons/constr_SET.h
index 6a8d077..a83ca1e 100644
--- a/skeletons/constr_SET.h
+++ b/skeletons/constr_SET.h
@@ -55,6 +55,7 @@
xer_type_encoder_f SET_encode_xer;
per_type_decoder_f SET_decode_uper;
per_type_encoder_f SET_encode_uper;
+asn_random_fill_f SET_random_fill;
extern asn_TYPE_operation_t asn_OP_SET;
/***********************
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index ba61496..2deb8bd 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -839,8 +839,8 @@
return -1;
}
- constr = elm->memb_constraints;
- if(!constr) constr = elm->type->check_constraints;
+ constr = elm->encoding_constraints.general_constraints;
+ if(!constr) constr = elm->type->encoding_constraints.general_constraints;
/*
* Iterate over the members of an array.
@@ -856,13 +856,6 @@
if(ret) return ret;
}
- /*
- * Cannot inherit it eralier:
- * need to make sure we get the updated version.
- */
- if(!elm->memb_constraints)
- elm->memb_constraints = elm->type->check_constraints;
-
return 0;
}
@@ -893,7 +886,8 @@
/* Figure out which constraints to use */
if(constraints) ct = &constraints->size;
- else if(td->per_constraints) ct = &td->per_constraints->size;
+ else if(td->encoding_constraints.per_constraints)
+ ct = &td->encoding_constraints.per_constraints->size;
else ct = 0;
if(ct && ct->flags & APC_EXTENSIBLE) {
@@ -927,7 +921,7 @@
void *ptr = 0;
ASN_DEBUG("SET OF %s decoding", elm->type->name);
rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, &ptr, pd);
+ elm->encoding_constraints.per_constraints, &ptr, pd);
ASN_DEBUG("%s SET OF %s decoded %d, %p",
td->name, elm->type->name, rv.code, ptr);
if(rv.code == RC_OK) {
@@ -988,5 +982,55 @@
SET_OF_decode_uper,
0, /* SET_OF_encode_uper */
#endif /* ASN_DISABLE_PER_SUPPORT */
+ SET_OF_random_fill,
0 /* Use generic outmost tag fetcher */
};
+
+
+asn_random_fill_result_t
+SET_OF_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
+ const asn_encoding_constraints_t *constr,
+ size_t max_length) {
+ const asn_SET_OF_specifics_t *specs =
+ (const asn_SET_OF_specifics_t *)td->specifics;
+ asn_random_fill_result_t res_ok = {ARFILL_OK, 0};
+ asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
+ asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
+ const asn_TYPE_member_t *elm = td->elements;
+ void *st = *sptr;
+ size_t rnd_len;
+
+ if(max_length == 0) return result_skipped;
+
+ (void)constr;
+
+ if(st == NULL) {
+ st = (*sptr = CALLOC(1, specs->struct_size));
+ if(st == NULL) {
+ return result_failed;
+ }
+ }
+
+ rnd_len = asn_random_between(0, 5);
+ for(; rnd_len > 0; rnd_len--) {
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
+ void *ptr = 0;
+ asn_random_fill_result_t tmpres = elm->type->op->random_fill(
+ elm->type, &ptr, &elm->encoding_constraints,
+ max_length > res_ok.length ? max_length - res_ok.length : 0);
+ switch(tmpres.code) {
+ case ARFILL_OK:
+ ASN_SET_ADD(list, ptr);
+ res_ok.length += tmpres.code;
+ break;
+ case ARFILL_SKIPPED:
+ break;
+ case ARFILL_FAILED:
+ assert(ptr == 0);
+ return tmpres;
+ }
+ }
+
+ return res_ok;
+}
+
diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h
index 8b51611..86609e8 100644
--- a/skeletons/constr_SET_OF.h
+++ b/skeletons/constr_SET_OF.h
@@ -37,6 +37,7 @@
oer_type_encoder_f SET_OF_encode_oer;
per_type_decoder_f SET_OF_decode_uper;
per_type_encoder_f SET_OF_encode_uper;
+asn_random_fill_f SET_OF_random_fill;
extern asn_TYPE_operation_t asn_OP_SET_OF;
#ifdef __cplusplus
diff --git a/skeletons/constr_SET_OF_oer.c b/skeletons/constr_SET_OF_oer.c
index 49f56c5..332c11b 100644
--- a/skeletons/constr_SET_OF_oer.c
+++ b/skeletons/constr_SET_OF_oer.c
@@ -168,7 +168,8 @@
for(; ctx->left > 0; ctx->left--) {
asn_dec_rval_t rv = elm->type->op->oer_decoder(
- opt_codec_ctx, elm->type, elm->oer_constraints, &ctx->ptr, ptr,
+ opt_codec_ctx, elm->type,
+ elm->encoding_constraints.oer_constraints, &ctx->ptr, ptr,
size);
ADVANCE(rv.consumed);
switch(rv.code) {
@@ -251,8 +252,9 @@
for(n = 0; n < list->count; n++) {
void *memb_ptr = list->array[n];
asn_enc_rval_t er;
- er = elm->type->op->oer_encoder(elm->type, elm->oer_constraints,
- memb_ptr, cb, app_key);
+ er = elm->type->op->oer_encoder(
+ elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
+ app_key);
if(er.encoded < 0) {
return er;
} else {
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index b8247f4..7810349 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -42,6 +42,7 @@
#include <per_decoder.h> /* Packet Encoding Rules decoder */
#include <per_encoder.h> /* Packet Encoding Rules encoder */
#include <constraints.h> /* Subtype constraints support */
+#include <asn_random_fill.h> /* Random structures support */
#ifdef ASN_DISABLE_OER_SUPPORT
typedef void (oer_type_decoder_f)();
@@ -142,60 +143,69 @@
* May be directly invoked by applications.
*/
typedef struct asn_TYPE_operation_s {
- asn_struct_free_f *free_struct; /* Free the structure */
- asn_struct_print_f *print_struct; /* Human readable output */
- asn_struct_compare_f *compare_struct; /* Compare two structures */
- ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
- der_type_encoder_f *der_encoder; /* Canonical DER encoder */
- xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
- xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
- oer_type_decoder_f *oer_decoder; /* Generic OER decoder */
- oer_type_encoder_f *oer_encoder; /* Canonical OER encoder */
- per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
- per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
- asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
+ asn_struct_free_f *free_struct; /* Free the structure */
+ asn_struct_print_f *print_struct; /* Human readable output */
+ asn_struct_compare_f *compare_struct; /* Compare two structures */
+ ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
+ der_type_encoder_f *der_encoder; /* Canonical DER encoder */
+ xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
+ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
+ oer_type_decoder_f *oer_decoder; /* Generic OER decoder */
+ oer_type_encoder_f *oer_encoder; /* Canonical OER encoder */
+ per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
+ per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
+ asn_random_fill_f *random_fill; /* Initialize with a random value */
+ asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
} asn_TYPE_operation_t;
/*
+ * A constraints tuple specifying both the OER and PER constraints.
+ */
+typedef struct asn_encoding_constraints_s {
+ const struct asn_oer_constraints_s *oer_constraints;
+ const struct asn_per_constraints_s *per_constraints;
+ asn_constr_check_f *general_constraints;
+} asn_encoding_constraints_t;
+
+/*
* The definitive description of the destination language's structure.
*/
typedef struct asn_TYPE_descriptor_s {
- const char *name; /* A name of the ASN.1 type. "" in some cases. */
- const char *xml_tag; /* Name used in XML tag */
+ const char *name; /* A name of the ASN.1 type. "" in some cases. */
+ const char *xml_tag; /* Name used in XML tag */
- /*
- * Generalized functions for dealing with the specific type.
- * May be directly invoked by applications.
- */
- asn_TYPE_operation_t *op;
- asn_constr_check_f *check_constraints; /* Constraints validator */
+ /*
+ * Generalized functions for dealing with the specific type.
+ * May be directly invoked by applications.
+ */
+ asn_TYPE_operation_t *op;
- /***********************************************************************
- * Internally useful members. Not to be used by applications directly. *
- **********************************************************************/
+ /***********************************************************************
+ * Internally useful members. Not to be used by applications directly. *
+ **********************************************************************/
- /*
- * Tags that are expected to occur.
- */
- const ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
- unsigned tags_count; /* Number of tags which are expected */
- const ber_tlv_tag_t *all_tags; /* Every tag for BER/containment */
- unsigned all_tags_count; /* Number of tags */
+ /*
+ * Tags that are expected to occur.
+ */
+ const ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
+ unsigned tags_count; /* Number of tags which are expected */
+ const ber_tlv_tag_t *all_tags; /* Every tag for BER/containment */
+ unsigned all_tags_count; /* Number of tags */
- asn_oer_constraints_t *oer_constraints; /* OER constraints */
- asn_per_constraints_t *per_constraints; /* PER constraints */
+ /* OER, PER, and general constraints */
+ asn_encoding_constraints_t encoding_constraints;
- /*
- * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
- */
- struct asn_TYPE_member_s *elements;
- unsigned elements_count;
+ /*
+ * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
+ */
+ struct asn_TYPE_member_s *elements;
+ unsigned elements_count;
- /*
- * Additional information describing the type, used by appropriate
- * functions above.
- */
- const void *specifics;
+ /*
+ * Additional information describing the type, used by appropriate
+ * functions above.
+ */
+ const void *specifics;
} asn_TYPE_descriptor_t;
/*
@@ -216,9 +226,7 @@
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
asn_TYPE_descriptor_t *type; /* Member type descriptor */
asn_type_selector_f *type_selector; /* IoS runtime type selector */
- asn_constr_check_f *memb_constraints; /* Constraints validator */
- asn_oer_constraints_t *oer_constraints; /* OER compiled constraints */
- asn_per_constraints_t *per_constraints; /* PER compiled constraints */
+ asn_encoding_constraints_t encoding_constraints;
int (*default_value)(int setval, void **sptr); /* DEFAULT <value> */
const char *name; /* ASN.1 identifier of the element */
} asn_TYPE_member_t;
diff --git a/skeletons/constraints.c b/skeletons/constraints.c
index 6c8287a..c260997 100644
--- a/skeletons/constraints.c
+++ b/skeletons/constraints.c
@@ -74,20 +74,19 @@
int
asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor,
- const void *struct_ptr, char *errbuf, size_t *errlen) {
- struct errbufDesc arg;
- int ret;
+ const void *struct_ptr, char *errbuf, size_t *errlen) {
+ struct errbufDesc arg;
+ int ret;
- arg.failed_type = 0;
- arg.failed_struct_ptr = 0;
- arg.errbuf = errbuf;
- arg.errlen = errlen ? *errlen : 0;
+ arg.failed_type = 0;
+ arg.failed_struct_ptr = 0;
+ arg.errbuf = errbuf;
+ arg.errlen = errlen ? *errlen : 0;
- ret = type_descriptor->check_constraints(type_descriptor,
- struct_ptr, _asn_i_ctfailcb, &arg);
- if(ret == -1 && errlen)
- *errlen = arg.errlen;
+ ret = type_descriptor->encoding_constraints.general_constraints(
+ type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg);
+ if(ret == -1 && errlen) *errlen = arg.errlen;
- return ret;
+ return ret;
}
diff --git a/skeletons/converter-example.c b/skeletons/converter-example.c
index a1dc8f4..ec1cc10 100644
--- a/skeletons/converter-example.c
+++ b/skeletons/converter-example.c
@@ -58,14 +58,35 @@
static int opt_onepdu; /* -1 (decode single PDU) */
#ifdef JUNKTEST /* Enable -J <probability> */
-#define JUNKOPT "J:"
+#define JUNKOPT "J:"
static double opt_jprob; /* Junk bit probability */
static int junk_failures;
static void junk_bytes_with_probability(uint8_t *, size_t, double prob);
-#else
-#define JUNKOPT
+
+#define RANDOPT "R:"
+static ssize_t random_max_size = 0; /* Size of the random data */
+
+#if !defined(__FreeBSD__) && !(defined(__APPLE__) && defined(__MACH__))
+static void
+srandomdev(void) {
+ FILE *f = fopen("/dev/urandom", "rb");
+ unsigned seed;
+ if(f) {
+ if(fread(&seed, 1, sizeof(seed), f) != sizeof(seed)) {
+ seed = time(NULL);
+ }
+ fclose(f);
+ } else {
+ seed = time(NULL);
+ }
+ srandom(seed);
+}
#endif
+#else /* !JUNKTEST */
+#define JUNKOPT
+#endif /* JUNKTEST */
+
/* Debug output function */
static void
DEBUG(const char *fmt, ...) {
@@ -195,7 +216,7 @@
/*
* Pocess the command-line argments.
*/
- while((ch = getopt(ac, av, "i:o:1b:cdn:p:hs:" JUNKOPT)) != -1)
+ while((ch = getopt(ac, av, "i:o:1b:cdn:p:hs:" JUNKOPT RANDOPT)) != -1)
switch(ch) {
case 'i':
sel = ats_by_name(optarg, pduType, input_encodings);
@@ -296,6 +317,17 @@
exit(EX_UNAVAILABLE);
}
break;
+ case 'R':
+ isyntax = ATS_RANDOM;
+ random_max_size = atoi(optarg);
+ if(random_max_size < 0) {
+ fprintf(stderr,
+ "-R %s: Non-negative value expected\n",
+ optarg);
+ exit(EX_UNAVAILABLE);
+ }
+ srandomdev();
+ break;
#endif /* JUNKTEST */
case 'h':
default:
@@ -339,6 +371,8 @@
" -s <size> Set the stack usage limit (default is %d)\n"
#ifdef JUNKTEST
" -J <prob> Set random junk test bit garbaging probability\n"
+ " -R <size> Generate a random value of roughly the given size,\n"
+ " instead of parsing the value from file.\n"
#endif
, (long)suggested_bufsize, ASN__DEFAULT_STACK_MAX);
exit(EX_USAGE);
@@ -347,7 +381,7 @@
ac -= optind;
av += optind;
- if(ac < 1) {
+ if(ac < 1 && isyntax != ATS_RANDOM) {
fprintf(stderr, "%s: No input files specified. "
"Try '-h' for more information\n",
av[-optind]);
@@ -378,19 +412,39 @@
/*
* Process all files in turn.
*/
- for(ac_i = 0; ac_i < ac; ac_i++) {
+ for(ac_i = (isyntax == ATS_RANDOM) ? -1 : 0; ac_i < ac; ac_i++) {
asn_enc_rval_t erv;
void *structure; /* Decoded structure */
- FILE *file = argument_to_file(av, ac_i);
- char *name = argument_to_name(av, ac_i);
+ FILE *file;
+ char *name;
int first_pdu;
+ if(ac_i == -1) {
+ file = NULL;
+ name = "<random value generator>";
+ opt_onepdu = 1;
+ } else {
+ file = argument_to_file(av, ac_i);
+ name = argument_to_name(av, ac_i);
+ }
+
for(first_pdu = 1; (first_pdu || !opt_onepdu); first_pdu = 0) {
/*
* Decode the encoded structure from file.
*/
- structure = data_decode_from_file(isyntax, pduType, file, name,
- suggested_bufsize, first_pdu);
+ if(isyntax == ATS_RANDOM) {
+ structure = NULL;
+ if(asn_random_fill(pduType, &structure, random_max_size) != 0) {
+ fprintf(stderr,
+ "Cannot generate a random value.\n",
+ random_max_size);
+ assert(structure == NULL);
+ errno = EINVAL;
+ }
+ } else {
+ structure = data_decode_from_file(isyntax, pduType, file, name,
+ suggested_bufsize, first_pdu);
+ }
if(!structure) {
if(errno) {
/* Error message is already printed */
@@ -429,6 +483,8 @@
if(erv.encoded == -1) {
fprintf(stderr, "%s: Cannot convert %s into %s\n", name,
pduType->name, ats_simple_name(osyntax));
+ DEBUG("Conversion failed for %s:\n", pduType->name);
+ asn_fprint(stderr, pduType, structure);
exit(EX_UNAVAILABLE);
}
DEBUG("Encoded in %zd bytes of %s", erv.encoded,
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 76c97ea..170dee4 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -46,6 +46,7 @@
asn_system.h # Platform-dependent types
asn_codecs.h # Return types of encoders and decoders
asn_internal.h # Internal stuff
+asn_random_fill.h asn_random_fill.c # Initialize with a random value
asn_bit_data.h asn_bit_data.c # Bit streaming support
OCTET_STRING.h OCTET_STRING.c # This one is used too widely
BIT_STRING.h BIT_STRING.c # This one is necessary for the above one
diff --git a/skeletons/oer_decoder.c b/skeletons/oer_decoder.c
index 52f56de..e803ad2 100644
--- a/skeletons/oer_decoder.c
+++ b/skeletons/oer_decoder.c
@@ -58,9 +58,8 @@
ssize_t
oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
struct asn_TYPE_descriptor_s *td,
- asn_oer_constraints_t *constraints, void **struct_ptr,
+ const asn_oer_constraints_t *constraints, void **struct_ptr,
const void *bufptr, size_t size) {
-
asn_dec_rval_t dr;
size_t container_len = 0;
ssize_t len_len;
diff --git a/skeletons/oer_decoder.h b/skeletons/oer_decoder.h
index db6005f..bf4bc08 100644
--- a/skeletons/oer_decoder.h
+++ b/skeletons/oer_decoder.h
@@ -56,8 +56,8 @@
*/
ssize_t oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
struct asn_TYPE_descriptor_s *td,
- asn_oer_constraints_t *constraints, void **struct_ptr,
- const void *bufptr, size_t size);
+ const asn_oer_constraints_t *constraints,
+ void **struct_ptr, const void *bufptr, size_t size);
#ifdef __cplusplus
diff --git a/skeletons/per_opentype.c b/skeletons/per_opentype.c
index c0286ff..9b213d8 100644
--- a/skeletons/per_opentype.c
+++ b/skeletons/per_opentype.c
@@ -26,7 +26,7 @@
* #10.1, #10.2
*/
int
-uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+uper_open_type_put(asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
void *buf;
void *bptr;
ssize_t size;
diff --git a/skeletons/per_opentype.h b/skeletons/per_opentype.h
index 4e3f5fe..31c1832 100644
--- a/skeletons/per_opentype.h
+++ b/skeletons/per_opentype.h
@@ -22,7 +22,7 @@
* Returns -1 if error is encountered. 0 if all OK.
*/
int uper_open_type_put(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr,
+ const asn_per_constraints_t *constraints, void *sptr,
asn_per_outp_t *po);
#ifdef __cplusplus