OCTET_STRING_rfill.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
8 
9 /*
10  * Biased function for randomizing character values around their limits.
11  */
12 static uint32_t
13 OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
14  assert(lb <= ub);
15  switch(asn_random_between(0, 16)) {
16  case 0:
17  if(lb < ub) return lb + 1;
18  /* Fall through */
19  case 1:
20  return lb;
21  case 2:
22  if(lb < ub) return ub - 1;
23  /* Fall through */
24  case 3:
25  return ub;
26  default:
27  return asn_random_between(lb, ub);
28  }
29 }
30 
33  const asn_encoding_constraints_t *constraints,
34  size_t max_length) {
35  const asn_OCTET_STRING_specifics_t *specs = td->specifics
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 */
44  uint8_t *buf;
45  uint8_t *bend;
46  uint8_t *b;
47  size_t rnd_len;
48  OCTET_STRING_t *st;
49 
50  if(max_length == 0 && !*sptr) return result_skipped;
51 
52  switch(specs->subvariant) {
53  default:
54  case ASN_OSUBV_ANY:
55  return result_failed;
56  case ASN_OSUBV_BIT:
57  /* Handled by BIT_STRING itself. */
58  return result_failed;
59  case ASN_OSUBV_STR:
60  unit_bytes = 1;
61  clb = 0;
62  cub = 255;
63  break;
64  case ASN_OSUBV_U16:
65  unit_bytes = 2;
66  clb = 0;
67  cub = 65535;
68  break;
69  case ASN_OSUBV_U32:
70  unit_bytes = 4;
71  clb = 0;
72  cub = 0x10FFFF;
73  break;
74  }
75 
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;
86  }
87  }
88 #else
89  if(!constraints) constraints = &td->encoding_constraints;
90 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
91 
92  rnd_len =
93  OCTET_STRING_random_length_constrained(td, constraints, max_length);
94 
95  buf = CALLOC(unit_bytes, rnd_len + 1);
96  if(!buf) return result_failed;
97 
98  bend = &buf[unit_bytes * rnd_len];
99 
100  switch(unit_bytes) {
101  case 1:
102  for(b = buf; b < bend; b += unit_bytes) {
103  *(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
104  }
105  *(uint8_t *)b = 0;
106  break;
107  case 2:
108  for(b = buf; b < bend; b += unit_bytes) {
109  uint32_t code = OCTET_STRING__random_char(clb, cub);
110  b[0] = code >> 8;
111  b[1] = code;
112  }
113  *(uint16_t *)b = 0;
114  break;
115  case 4:
116  for(b = buf; b < bend; b += unit_bytes) {
117  uint32_t code = OCTET_STRING__random_char(clb, cub);
118  b[0] = code >> 24;
119  b[1] = code >> 16;
120  b[2] = code >> 8;
121  b[3] = code;
122  }
123  *(uint32_t *)b = 0;
124  break;
125  }
126 
127  if(*sptr) {
128  st = *sptr;
129  FREEMEM(st->buf);
130  } else {
131  st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
132  if(!st) {
133  FREEMEM(buf);
134  return result_failed;
135  }
136  }
137 
138  st->buf = buf;
139  st->size = unit_bytes * rnd_len;
140 
141  result_ok.length = st->size;
142  return result_ok;
143 }
144 
145 size_t
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};
152  size_t rnd_len;
153 
154  /* Figure out how far we should go */
155  rnd_len = lengths[asn_random_between(
156  0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
157 
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
165  ? pc->upper_bound
166  : (ssize_t)max_length;
167  if(max_length <= (size_t)pc->lower_bound) {
168  return pc->lower_bound;
169  }
170  if(pc->flags & APC_EXTENSIBLE) {
171  switch(asn_random_between(0, 5)) {
172  case 0:
173  if(pc->lower_bound > 0) {
174  rnd_len = pc->lower_bound - 1;
175  break;
176  }
177  /* Fall through */
178  case 1:
179  rnd_len = pc->upper_bound + 1;
180  break;
181  case 2:
182  /* Keep rnd_len from the table */
183  if(rnd_len <= max_length) {
184  break;
185  }
186  /* Fall through */
187  default:
188  rnd_len = asn_random_between(pc->lower_bound,
189  suggested_upper_bound);
190  }
191  } else {
192  rnd_len =
193  asn_random_between(pc->lower_bound, suggested_upper_bound);
194  }
195  } else {
196  rnd_len = asn_random_between(0, max_length);
197  }
198  } else {
199 #else
200  if(!constraints) constraints = &td->encoding_constraints;
201  {
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);
205  }
206  }
207 
208  return rnd_len;
209 }
OCTET_STRING__random_char
static uint32_t OCTET_STRING__random_char(unsigned long lb, unsigned long ub)
Definition: OCTET_STRING_rfill.c:13
asn_per_constraint_s::lower_bound
intmax_t lower_bound
Definition: per_support.h:27
OCTET_STRING_random_length_constrained
size_t OCTET_STRING_random_length_constrained(const asn_TYPE_descriptor_t *td, const asn_encoding_constraints_t *constraints, size_t max_length)
Definition: OCTET_STRING_rfill.c:146
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
asn_per_constraint_s
Definition: per_support.h:18
OCTET_STRING::buf
uint8_t * buf
Definition: OCTET_STRING.h:15
asn_OCTET_STRING_specifics_s
Definition: OCTET_STRING.h:125
asn_SPC_OCTET_STRING_specs
asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs
Definition: OCTET_STRING.c:16
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_random_fill_result_s
Definition: asn_random_fill.h:24
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_random_between
intmax_t asn_random_between(intmax_t min, intmax_t max)
Definition: asn_random_fill.c:38
OCTET_STRING_random_fill
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)
Definition: OCTET_STRING_rfill.c:32
asn_encoding_constraints_s::per_constraints
const struct asn_per_constraints_s * per_constraints
Definition: constr_TYPE.h:213
asn_encoding_constraints_s
Definition: constr_TYPE.h:208
OCTET_STRING
Definition: OCTET_STRING.h:14
asn_per_constraints_s::size
asn_per_constraint_t size
Definition: per_support.h:32
asn_internal.h
asn_TYPE_descriptor_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:247
asn_per_constraint_s::upper_bound
intmax_t upper_bound
Definition: per_support.h:28
asn_per_constraint_s::flags
enum asn_per_constraint_s::asn_per_constraint_flags flags
OCTET_STRING.h
OCTET_STRING::size
size_t size
Definition: OCTET_STRING.h:16


etsi_its_vam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:30:55