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 <OCTET_STRING.h>
10 * Biased function for randomizing character values around their limits.
13 OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
15 switch(asn_random_between(0, 16)) {
17 if(lb < ub) return lb + 1;
22 if(lb < ub) return ub - 1;
27 return asn_random_between(lb, ub);
31 asn_random_fill_result_t
32 OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
33 const asn_encoding_constraints_t *constraints,
35 const asn_OCTET_STRING_specifics_t *specs = td->specifics
36 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
37 : &asn_SPC_OCTET_STRING_specs;
38 asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
39 asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
40 asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
41 unsigned int unit_bytes = 1;
42 unsigned long clb = 0; /* Lower bound on char */
43 unsigned long cub = 255; /* Higher bound on char value */
50 if(max_length == 0 && !*sptr) return result_skipped;
52 switch(specs->subvariant) {
57 /* Handled by BIT_STRING itself. */
76 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
77 if(!constraints || !constraints->per_constraints)
78 constraints = &td->encoding_constraints;
79 if(constraints->per_constraints) {
80 const asn_per_constraint_t *pc = &constraints->per_constraints->value;
81 if(pc->flags & APC_SEMI_CONSTRAINED) {
82 clb = pc->lower_bound;
83 } else if(pc->flags & APC_CONSTRAINED) {
84 clb = pc->lower_bound;
85 cub = pc->upper_bound;
89 if(!constraints) constraints = &td->encoding_constraints;
90 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
93 OCTET_STRING_random_length_constrained(td, constraints, max_length);
95 buf = CALLOC(unit_bytes, rnd_len + 1);
96 if(!buf) return result_failed;
98 bend = &buf[unit_bytes * rnd_len];
102 for(b = buf; b < bend; b += unit_bytes) {
103 *(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
108 for(b = buf; b < bend; b += unit_bytes) {
109 uint32_t code = OCTET_STRING__random_char(clb, cub);
116 for(b = buf; b < bend; b += unit_bytes) {
117 uint32_t code = OCTET_STRING__random_char(clb, cub);
131 st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
134 return result_failed;
139 st->size = unit_bytes * rnd_len;
141 result_ok.length = st->size;
146 OCTET_STRING_random_length_constrained(
147 const asn_TYPE_descriptor_t *td,
148 const asn_encoding_constraints_t *constraints, size_t max_length) {
149 const unsigned lengths[] = {0, 1, 2, 3, 4, 8,
150 126, 127, 128, 16383, 16384, 16385,
151 65534, 65535, 65536, 65537};
154 /* Figure out how far we should go */
155 rnd_len = lengths[asn_random_between(
156 0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
158 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
159 if(!constraints || !constraints->per_constraints)
160 constraints = &td->encoding_constraints;
161 if(constraints->per_constraints) {
162 const asn_per_constraint_t *pc = &constraints->per_constraints->size;
163 if(pc->flags & APC_CONSTRAINED) {
164 long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
166 : (ssize_t)max_length;
167 if(max_length <= (size_t)pc->lower_bound) {
168 return pc->lower_bound;
170 if(pc->flags & APC_EXTENSIBLE) {
171 switch(asn_random_between(0, 5)) {
173 if(pc->lower_bound > 0) {
174 rnd_len = pc->lower_bound - 1;
179 rnd_len = pc->upper_bound + 1;
182 /* Keep rnd_len from the table */
183 if(rnd_len <= max_length) {
188 rnd_len = asn_random_between(pc->lower_bound,
189 suggested_upper_bound);
193 asn_random_between(pc->lower_bound, suggested_upper_bound);
196 rnd_len = asn_random_between(0, max_length);
200 if(!constraints) constraints = &td->encoding_constraints;
202 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
203 if(rnd_len > max_length) {
204 rnd_len = asn_random_between(0, max_length);