Combined constraints and introduced value randomizer.

This commit is contained in:
Lev Walkin 2017-09-29 23:15:58 -07:00
parent 6d69204622
commit a5972bedae
74 changed files with 1422 additions and 274 deletions

View File

@ -32,16 +32,15 @@ asn_TYPE_operation_t asn_OP_ANY = {
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,
};

View File

@ -39,21 +39,20 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = {
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 @@ BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
}
}
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;
}

View File

@ -30,6 +30,7 @@ asn_constr_check_f BIT_STRING_constraint;
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

View File

@ -15,7 +15,7 @@ BIT_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_
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_encode_oer(asn_TYPE_descriptor_t *td,
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;

View File

@ -45,21 +45,20 @@ asn_TYPE_operation_t asn_OP_BMPString = {
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
};

View File

@ -34,19 +34,18 @@ asn_TYPE_operation_t asn_OP_BOOLEAN = {
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 @@ BOOLEAN_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
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;
}

View File

@ -30,6 +30,7 @@ xer_type_decoder_f BOOLEAN_decode_xer;
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

View File

@ -36,19 +36,18 @@ asn_TYPE_operation_t asn_OP_ENUMERATED = {
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 */
};

View File

@ -27,6 +27,7 @@ per_type_encoder_f ENUMERATED_encode_uper;
#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
}

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_GeneralString = {
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 */
};

View File

@ -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 @@ static const ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
(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 @@ asn_TYPE_operation_t asn_OP_GeneralizedTime = {
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 @@ asn_time2GT_frac(GeneralizedTime_t *opt_gt, const struct tm *tm, int frac_value,
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;
}

View File

@ -20,6 +20,7 @@ asn_struct_print_f GeneralizedTime_print;
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

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_GraphicString = {
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 */
};

View File

@ -39,21 +39,20 @@ asn_TYPE_operation_t asn_OP_IA5String = {
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 */
};

View File

@ -36,19 +36,18 @@ asn_TYPE_operation_t asn_OP_INTEGER = {
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 @@ INTEGER_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
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 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
}
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;
}
}

View File

@ -48,6 +48,7 @@ oer_type_decoder_f INTEGER_decode_oer;
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. *

View File

@ -32,7 +32,7 @@ INTEGER_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
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 @@ INTEGER_encode_oer(asn_TYPE_descriptor_t *td,
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;

View File

@ -39,21 +39,20 @@ asn_TYPE_operation_t asn_OP_ISO646String = {
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 */
};

View File

@ -65,6 +65,7 @@ libasn1cskeletons_la_SOURCES = \
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 \

View File

@ -35,19 +35,18 @@ asn_TYPE_operation_t asn_OP_NULL = {
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 @@ NULL_encode_uper(asn_TYPE_descriptor_t *td,
}
#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;
}

View File

@ -30,6 +30,7 @@ oer_type_decoder_f NULL_decode_oer;
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

View File

@ -40,19 +40,18 @@ asn_TYPE_operation_t asn_OP_NativeEnumerated = {
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 @@ NativeEnumerated_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
(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 @@ NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
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);

View File

@ -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 @@ per_type_encoder_f NativeEnumerated_encode_uper;
#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

View File

@ -41,19 +41,18 @@ asn_TYPE_operation_t asn_OP_NativeInteger = {
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 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v
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;
}

View File

@ -33,6 +33,7 @@ oer_type_decoder_f NativeInteger_decode_oer;
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

View File

@ -61,19 +61,18 @@ asn_TYPE_operation_t asn_OP_NativeReal = {
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 @@ NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr,
}
}
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;
}

View File

@ -29,6 +29,7 @@ xer_type_decoder_f NativeReal_decode_xer;
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

View File

@ -59,21 +59,20 @@ asn_TYPE_operation_t asn_OP_NumericString = {
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 */
};

View File

@ -37,21 +37,20 @@ asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = {
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 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
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;
}

View File

@ -24,6 +24,7 @@ asn_constr_check_f OBJECT_IDENTIFIER_constraint;
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

View File

@ -42,21 +42,20 @@ asn_TYPE_operation_t asn_OP_OCTET_STRING = {
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 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
? (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 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
? (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_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
}
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 @@ OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
}
/*
* 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;
}

View File

@ -36,6 +36,7 @@ oer_type_decoder_f OCTET_STRING_decode_oer;
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 @@ int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size);
* 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. *

View File

@ -20,7 +20,7 @@ OCTET_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
: (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 @@ OCTET_STRING_encode_oer(asn_TYPE_descriptor_t *td,
: (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};

View File

@ -23,6 +23,7 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
OPEN_TYPE_decode_uper,
OPEN_TYPE_encode_uper,
#endif
0, /* Random fill is not supported for open type */
0, /* Use generic outmost tag fetcher */
};

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_ObjectDescriptor = {
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 */
};

View File

@ -69,21 +69,20 @@ asn_TYPE_operation_t asn_OP_PrintableString = {
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 */
};

View File

@ -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 @@ asn_TYPE_operation_t asn_OP_REAL = {
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 @@ REAL_encode_uper(asn_TYPE_descriptor_t *td,
}
#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;
}

View File

@ -23,6 +23,7 @@ xer_type_decoder_f REAL_decode_xer;
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

View File

@ -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 @@ asn_TYPE_operation_t asn_OP_RELATIVE_OID = {
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 @@ RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_si
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;
}

View File

@ -20,6 +20,7 @@ extern asn_TYPE_operation_t asn_OP_RELATIVE_OID;
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

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_T61String = {
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 */
};

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_TeletexString = {
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 */
};

View File

@ -50,21 +50,20 @@ asn_TYPE_operation_t asn_OP_UTCTime = {
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 @@ asn_time2UT(UTCTime_t *opt_ut, const struct tm *tm, int force_gmt) {
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;
}

View File

@ -19,6 +19,7 @@ extern asn_TYPE_operation_t asn_OP_UTCTime;
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

View File

@ -35,21 +35,20 @@ asn_TYPE_operation_t asn_OP_UTF8String = {
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 @@ UTF8String_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
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;
}

View File

@ -18,6 +18,7 @@ extern asn_TYPE_operation_t asn_OP_UTF8String;
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

View File

@ -45,21 +45,20 @@ asn_TYPE_operation_t asn_OP_UniversalString = {
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
};

View File

@ -34,21 +34,20 @@ asn_TYPE_operation_t asn_OP_VideotexString = {
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 */
};

View File

@ -39,21 +39,20 @@ asn_TYPE_operation_t asn_OP_VisibleString = {
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 */
};

View File

@ -151,6 +151,35 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
}
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 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
}
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 @@ asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
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 @@ asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
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);

View File

@ -22,8 +22,10 @@ extern "C" {
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.

View File

@ -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));
}

View File

@ -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 */

View File

@ -516,18 +516,12 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
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 @@ CHOICE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
}
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 @@ CHOICE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
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 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td, void *sptr,
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 @@ asn_TYPE_operation_t asn_OP_CHOICE = {
CHOICE_decode_uper,
CHOICE_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
CHOICE_random_fill,
CHOICE_outmost_tag
};

View File

@ -52,6 +52,7 @@ oer_type_encoder_f CHOICE_encode_oer;
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;
/*

View File

@ -244,7 +244,7 @@ CHOICE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *t
}
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 @@ CHOICE_encode_oer(asn_TYPE_descriptor_t *td,
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;

View File

@ -1059,19 +1059,13 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
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 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
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 @@ SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
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 @@ SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr,
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 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ asn_TYPE_operation_t asn_OP_SEQUENCE = {
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;
}

View File

@ -55,6 +55,7 @@ oer_type_decoder_f SEQUENCE_decode_oer;
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

View File

@ -157,7 +157,8 @@ SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
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 @@ asn_TYPE_operation_t asn_OP_SEQUENCE_OF = {
SEQUENCE_OF_decode_uper,
SEQUENCE_OF_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
SEQUENCE_OF_random_fill,
0 /* Use generic outmost tag fetcher */
};

View File

@ -25,6 +25,7 @@ extern "C" {
#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;

View File

@ -204,7 +204,7 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
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 @@ SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
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 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
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 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
/* 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;
}

View File

@ -996,19 +996,12 @@ SET_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
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 @@ asn_TYPE_operation_t asn_OP_SET = {
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;
}

View File

@ -55,6 +55,7 @@ xer_type_decoder_f SET_decode_xer;
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;
/***********************

View File

@ -839,8 +839,8 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
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 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
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 @@ SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
/* 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 @@ SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
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 @@ asn_TYPE_operation_t asn_OP_SET_OF = {
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;
}

View File

@ -37,6 +37,7 @@ oer_type_decoder_f SET_OF_decode_oer;
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

View File

@ -168,7 +168,8 @@ SET_OF_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *t
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 @@ SET_OF_encode_oer(asn_TYPE_descriptor_t *td,
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 {

View File

@ -42,6 +42,7 @@ typedef struct asn_struct_ctx_s {
#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 @@ typedef asn_type_selector_result_t(asn_type_selector_f)(
* 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 @@ typedef struct asn_TYPE_member_s {
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;

View File

@ -74,20 +74,19 @@ _asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const ch
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;
}

View File

@ -58,14 +58,35 @@ static int opt_nopad; /* -per-nopad (PER input is not padded between msgs) */
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 @@ main(int ac, char *av[]) {
/*
* 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 @@ main(int ac, char *av[]) {
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 @@ main(int ac, char *av[]) {
" -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 @@ main(int ac, char *av[]) {
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 @@ main(int ac, char *av[]) {
/*
* 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 @@ main(int ac, char *av[]) {
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,

View File

@ -46,6 +46,7 @@ asn_ioc.h # Information Object Classes, runtime support
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

View File

@ -58,9 +58,8 @@ oer_open_type_skip(const void *bufptr, size_t size) {
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;

View File

@ -56,8 +56,8 @@ ssize_t oer_open_type_skip(const void *bufptr, size_t size);
*/
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

View File

@ -26,7 +26,7 @@ static asn_dec_rval_t uper_sot_suck(const asn_codec_ctx_t *,
* #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;

View File

@ -22,7 +22,7 @@ int uper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx,
* 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