2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <BIT_STRING.h>
9 asn_random_fill_result_t
10 BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
11 const asn_encoding_constraints_t *constraints,
13 const asn_OCTET_STRING_specifics_t *specs =
14 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
15 : &asn_SPC_BIT_STRING_specs;
16 asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
17 asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
18 asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
19 static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
20 126, 127, 128, 16383, 16384, 16385,
21 65534, 65535, 65536, 65537};
25 size_t rnd_bits, rnd_len;
28 if(max_length == 0) return result_skipped;
30 switch(specs->subvariant) {
39 /* Figure out how far we should go */
40 rnd_bits = lengths[asn_random_between(
41 0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
42 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
43 if(!constraints || !constraints->per_constraints)
44 constraints = &td->encoding_constraints;
45 if(constraints->per_constraints) {
46 const asn_per_constraint_t *pc = &constraints->per_constraints->size;
47 if(pc->flags & APC_CONSTRAINED) {
48 long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
50 : (ssize_t)max_length;
51 if(max_length < (size_t)pc->lower_bound) {
52 return result_skipped;
54 if(pc->flags & APC_EXTENSIBLE) {
55 switch(asn_random_between(0, 5)) {
57 if(pc->lower_bound > 0) {
58 rnd_bits = pc->lower_bound - 1;
63 rnd_bits = pc->upper_bound + 1;
66 /* Keep rnd_bits from the table */
67 if(rnd_bits < max_length) {
72 rnd_bits = asn_random_between(pc->lower_bound,
73 suggested_upper_bound);
77 asn_random_between(pc->lower_bound, suggested_upper_bound);
80 rnd_bits = asn_random_between(0, max_length - 1);
84 if(!constraints) constraints = &td->encoding_constraints;
86 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
87 if(rnd_bits >= max_length) {
88 rnd_bits = asn_random_between(0, max_length - 1);
92 rnd_len = (rnd_bits + 7) / 8;
93 buf = CALLOC(1, rnd_len + 1);
94 if(!buf) return result_failed;
98 for(b = buf; b < bend; b++) {
99 *(uint8_t *)b = asn_random_between(0, 255);
101 *b = 0; /* Zero-terminate just in case. */
107 st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
110 return result_failed;
116 st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
117 if(st->bits_unused) {
118 assert(st->size > 0);
119 st->buf[st->size-1] &= 0xff << st->bits_unused;
122 result_ok.length = st->size;