Coverage Report

Created: 2026-07-14 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/asn1c/common/OCTET_STRING_aper.c
Line
Count
Source
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
 */
6
#include <asn_internal.h>
7
#include <OCTET_STRING.h>
8
#include <BIT_STRING.h>  /* for .bits_unused member */
9
10
#undef RETURN
11
10.4k
#define RETURN(_code) do {\
12
10.4k
        asn_dec_rval_t tmprval;\
13
10.4k
        tmprval.code = _code;\
14
10.4k
        tmprval.consumed = consumed_myself;\
15
10.4k
        return tmprval;\
16
10.4k
    } while(0)
17
18
static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
19
    { APC_CONSTRAINED, 8, 8, 0, 255 },
20
    { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
21
    0, 0
22
};
23
24
asn_dec_rval_t
25
OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
26
                         const asn_TYPE_descriptor_t *td,
27
                         const asn_per_constraints_t *constraints,
28
14.0k
                         void **sptr, asn_per_data_t *pd) {
29
30
14.0k
    const asn_OCTET_STRING_specifics_t *specs = td->specifics
31
14.0k
        ? (const asn_OCTET_STRING_specifics_t *)td->specifics
32
14.0k
        : &asn_SPC_OCTET_STRING_specs;
33
14.0k
    const asn_per_constraints_t *pc = constraints
34
14.0k
        ? constraints
35
14.0k
        : td->encoding_constraints.per_constraints;
36
14.0k
    const asn_per_constraint_t *cval;
37
14.0k
    const asn_per_constraint_t *csiz;
38
14.0k
    asn_dec_rval_t rval = { RC_OK, 0 };
39
14.0k
    BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
40
14.0k
    ssize_t consumed_myself = 0;
41
14.0k
    int repeat;
42
14.0k
    enum {
43
14.0k
        OS__BPC_BIT = 0,
44
14.0k
        OS__BPC_CHAR = 1,
45
14.0k
        OS__BPC_U16 = 2,
46
14.0k
        OS__BPC_U32 = 4
47
14.0k
    } bpc;  /* Bytes per character */
48
14.0k
    unsigned int unit_bits;
49
14.0k
    unsigned int canonical_unit_bits;
50
51
14.0k
    (void)opt_codec_ctx;
52
53
14.0k
    if(pc) {
54
12.2k
        cval = &pc->value;
55
12.2k
        csiz = &pc->size;
56
12.2k
    } else {
57
1.76k
        cval = &asn_DEF_OCTET_STRING_constraints.value;
58
1.76k
        csiz = &asn_DEF_OCTET_STRING_constraints.size;
59
1.76k
    }
60
61
14.0k
    switch(specs->subvariant) {
62
0
    case ASN_OSUBV_ANY:
63
9.43k
    case ASN_OSUBV_STR:
64
9.43k
        canonical_unit_bits = unit_bits = 8;
65
9.43k
        if(cval->flags & APC_CONSTRAINED) {
66
            /* follow power of 2 rule */
67
1.83k
            if (cval->range_bits <= 2) {
68
0
            unit_bits = 2;
69
1.83k
            } else {
70
1.83k
          if (cval->range_bits <= 4) {
71
0
              unit_bits = 4;
72
              /* otherwise, unit_bits = 8; */
73
0
          }
74
1.83k
     }
75
           /* unit_bits = cval->range_bits; */
76
1.83k
           ASN_DEBUG("APER decoding ASN_OSUBV_STR range_bits = %d unit_bits = %d\n",
77
1.83k
              cval->range_bits, unit_bits);
78
1.83k
        }
79
9.43k
        bpc = OS__BPC_CHAR;
80
9.43k
        break;
81
0
    case ASN_OSUBV_U16:
82
0
        canonical_unit_bits = unit_bits = 16;
83
0
        if(cval->flags & APC_CONSTRAINED) {
84
0
            unit_bits = cval->range_bits;
85
0
            ASN_DEBUG("APER decoding ASN_OSUBV_U16 range_bits = %d\n", cval->range_bits);
86
0
        }
87
0
        bpc = OS__BPC_U16;
88
0
        break;
89
0
    case ASN_OSUBV_U32:
90
0
        canonical_unit_bits = unit_bits = 32;
91
0
        if(cval->flags & APC_CONSTRAINED) {
92
0
            unit_bits = cval->range_bits;
93
0
            ASN_DEBUG("APER decoding ASN_OSUBV_U32 range_bits = %d\n", cval->range_bits);
94
0
        }
95
0
        bpc = OS__BPC_U32;
96
0
        break;
97
/*
98
    case ASN_OSUBV_ANY:
99
        ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
100
        RETURN(RC_FAIL);
101
*/
102
4.62k
    case ASN_OSUBV_BIT:
103
4.62k
    default:
104
4.62k
        canonical_unit_bits = unit_bits = 1;
105
4.62k
        bpc = OS__BPC_BIT;
106
4.62k
        break;
107
14.0k
    }
108
109
    /*
110
     * Allocate the string.
111
     */
112
14.0k
    if(!st) {
113
4.95k
        st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
114
4.95k
        if(!st) RETURN(RC_FAIL);
115
4.95k
    }
116
117
14.0k
    ASN_DEBUG("PER Decoding %s size %lld .. %lld bits %d",
118
14.0k
              csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
119
14.0k
              (long long int)csiz->lower_bound, (long long int)csiz->upper_bound,
120
14.0k
              csiz->effective_bits);
121
122
14.0k
    if(csiz->flags & APC_EXTENSIBLE) {
123
1.46k
        int inext = per_get_few_bits(pd, 1);
124
1.46k
        if(inext < 0) RETURN(RC_WMORE);
125
1.45k
        if(inext) {
126
360
            csiz = &asn_DEF_OCTET_STRING_constraints.size;
127
360
            cval = &asn_DEF_OCTET_STRING_constraints.value;
128
360
            unit_bits = canonical_unit_bits;
129
360
        }
130
1.45k
    }
131
132
14.0k
    if(csiz->effective_bits >= 0) {
133
11.4k
        FREEMEM(st->buf);
134
11.4k
        if(bpc) {
135
7.23k
            st->size = csiz->upper_bound * bpc;
136
7.23k
        } else {
137
4.23k
            st->size = (csiz->upper_bound + 7) >> 3;
138
4.23k
        }
139
11.4k
        st->buf = (uint8_t *)MALLOC(st->size + 1);
140
11.4k
        if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
141
11.4k
    }
142
143
    /* X.691, #16.5: zero-length encoding */
144
    /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
145
    /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
146
14.0k
    if(csiz->effective_bits == 0) {
147
10.2k
        int ret;
148
        /* X.691 #16 NOTE 1 for fixed length (<= 16 bits) strings */
149
10.2k
        if (st->size > 2 || csiz->range_bits != 0) {
150
5.02k
            if (aper_get_align(pd) < 0)
151
0
                RETURN(RC_FAIL);
152
5.02k
        }
153
10.2k
        if(bpc) {
154
7.14k
            ASN_DEBUG("Decoding OCTET STRING size %lld",
155
7.14k
                      (long long int)csiz->upper_bound);
156
7.14k
            ret = OCTET_STRING_per_get_characters(pd, st->buf,
157
7.14k
                                                  csiz->upper_bound,
158
7.14k
                                                  bpc, unit_bits,
159
7.14k
                                                  cval->lower_bound,
160
7.14k
                                                  cval->upper_bound,
161
7.14k
                                                  pc);
162
7.14k
            if(ret > 0) RETURN(RC_FAIL);
163
7.14k
        } else {
164
3.07k
            ASN_DEBUG("Decoding BIT STRING size %lld",
165
3.07k
                      (long long int)csiz->upper_bound);
166
3.07k
            ret = per_get_many_bits(pd, st->buf, 0,
167
3.07k
                                    unit_bits * csiz->upper_bound);
168
3.07k
        }
169
10.2k
        if(ret < 0) RETURN(RC_WMORE);
170
10.0k
        consumed_myself += unit_bits * csiz->upper_bound;
171
10.0k
        st->buf[st->size] = 0;
172
10.0k
        if(bpc == 0) {
173
3.03k
            int ubs = (csiz->upper_bound & 0x7);
174
3.03k
            st->bits_unused = ubs ? 8 - ubs : 0;
175
3.03k
        }
176
10.0k
        RETURN(RC_OK);
177
10.0k
    }
178
179
3.82k
    st->size = 0;
180
3.82k
    do {
181
3.82k
        ssize_t raw_len;
182
3.82k
        ssize_t len_bytes;
183
3.82k
        ssize_t len_bits;
184
3.82k
        void *p;
185
3.82k
        int ret;
186
187
3.82k
        repeat = 0;
188
        /* Get the PER length */
189
3.82k
        if (csiz->upper_bound - csiz->lower_bound == 0)
190
            /* Indefinite length case */
191
2.55k
            raw_len = aper_get_length(pd, -1, -1, csiz->effective_bits, &repeat);
192
1.26k
        else
193
1.26k
            raw_len = aper_get_length(pd, csiz->lower_bound, csiz->upper_bound,
194
1.26k
                                      csiz->effective_bits, &repeat);
195
3.82k
        if(raw_len < 0) RETURN(RC_WMORE);
196
197
3.71k
        ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
198
3.71k
                  (long)csiz->effective_bits, (long)raw_len,
199
3.71k
                  repeat ? "repeat" : "once", td->name);
200
201
        /* X.691 #16 NOTE 1  for fixed length (<=16 bits) strings */
202
3.71k
        if ((raw_len > 2) || (csiz->upper_bound > 2) || (csiz->range_bits != 0))
203
3.71k
        {
204
3.71k
            if (aper_get_align(pd) < 0)
205
0
                RETURN(RC_FAIL);
206
3.71k
        }
207
208
3.71k
        if(bpc) {
209
2.20k
            len_bytes = raw_len * bpc;
210
2.20k
            len_bits = len_bytes * unit_bits;
211
2.20k
        } else {
212
1.51k
            len_bits = raw_len;
213
1.51k
            len_bytes = (len_bits + 7) >> 3;
214
1.51k
            if(len_bits & 0x7)
215
1.27k
                st->bits_unused = 8 - (len_bits & 0x7);
216
            /* len_bits be multiple of 16K if repeat is set */
217
1.51k
        }
218
3.71k
        p = REALLOC(st->buf, st->size + len_bytes + 1);
219
3.71k
        if(!p) RETURN(RC_FAIL);
220
3.71k
        st->buf = (uint8_t *)p;
221
222
3.71k
        if(bpc) {
223
2.20k
            ret = OCTET_STRING_per_get_characters(pd,
224
2.20k
                                                  &st->buf[st->size],
225
2.20k
                                                  raw_len, bpc,
226
2.20k
                                                  unit_bits,
227
2.20k
                                                  cval->lower_bound,
228
2.20k
                                                  cval->upper_bound,
229
2.20k
                                                  pc);
230
2.20k
            if(ret > 0) RETURN(RC_FAIL);
231
2.20k
        } else {
232
1.51k
            ret = per_get_many_bits(pd, &st->buf[st->size],
233
1.51k
                                    0, len_bits);
234
1.51k
        }
235
3.71k
        if(ret < 0) RETURN(RC_WMORE);
236
3.60k
        st->size += len_bytes;
237
3.60k
    } while(repeat);
238
3.60k
    st->buf[st->size] = 0;  /* nul-terminate */
239
240
3.60k
    return rval;
241
3.82k
}
242
243
asn_enc_rval_t
244
OCTET_STRING_encode_aper(const asn_TYPE_descriptor_t *td,
245
                         const asn_per_constraints_t *constraints,
246
0
                         const void *sptr, asn_per_outp_t *po) {
247
248
0
    const asn_OCTET_STRING_specifics_t *specs = td->specifics
249
0
        ? (const asn_OCTET_STRING_specifics_t *)td->specifics
250
0
        : &asn_SPC_OCTET_STRING_specs;
251
0
    const asn_per_constraints_t *pc = constraints
252
0
        ? constraints
253
0
        : td->encoding_constraints.per_constraints;
254
0
    const asn_per_constraint_t *cval;
255
0
    const asn_per_constraint_t *csiz;
256
0
    const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
257
0
    asn_enc_rval_t er = { 0, 0, 0 };
258
0
    int inext = 0;  /* Lies not within extension root */
259
0
    unsigned int unit_bits;
260
0
    unsigned int canonical_unit_bits;
261
0
    unsigned int sizeinunits;
262
0
    const uint8_t *buf;
263
0
    int ret;
264
0
    enum {
265
0
        OS__BPC_BIT  = 0,
266
0
        OS__BPC_CHAR = 1,
267
0
        OS__BPC_U16  = 2,
268
0
        OS__BPC_U32  = 4
269
0
    } bpc;  /* Bytes per character */
270
0
    int ct_extensible;
271
272
0
    if(!st || (!st->buf && st->size))
273
0
        ASN__ENCODE_FAILED;
274
275
0
    if(pc) {
276
0
        cval = &pc->value;
277
0
        csiz = &pc->size;
278
0
    } else {
279
0
        cval = &asn_DEF_OCTET_STRING_constraints.value;
280
0
        csiz = &asn_DEF_OCTET_STRING_constraints.size;
281
0
    }
282
0
    ct_extensible = csiz->flags & APC_EXTENSIBLE;
283
284
0
    switch(specs->subvariant) {
285
0
    case ASN_OSUBV_ANY:
286
0
    case ASN_OSUBV_STR:
287
0
        canonical_unit_bits = unit_bits = 8;
288
0
        if(cval->flags & APC_CONSTRAINED) {
289
          /* follow power of 2 rule */
290
0
          if (cval->range_bits <= 2) {
291
0
            unit_bits = 2;
292
0
          } else {
293
0
            if (cval->range_bits <= 4)
294
0
              unit_bits = 4;
295
            /* otherwise, unit_bits = 8; */
296
0
          }
297
              /* unit_bits = cval->range_bits; */
298
0
              ASN_DEBUG("APER encoding ASN_OSUBV_STR range_bits = %d unit_bits = %d\n", 
299
0
                cval->range_bits, unit_bits);
300
0
        }
301
0
        bpc = OS__BPC_CHAR;
302
0
        sizeinunits = st->size;
303
0
        break;
304
0
    case ASN_OSUBV_U16:
305
0
        canonical_unit_bits = unit_bits = 16;
306
0
        if(cval->flags & APC_CONSTRAINED) {
307
0
            unit_bits = cval->range_bits;
308
0
            ASN_DEBUG("APER encoding ASN_OSUBV_U16 range_bits = %d\n", cval->range_bits);
309
0
        }
310
0
        bpc = OS__BPC_U16;
311
0
        sizeinunits = st->size / 2;
312
0
        break;
313
0
    case ASN_OSUBV_U32:
314
0
        canonical_unit_bits = unit_bits = 32;
315
0
        if(cval->flags & APC_CONSTRAINED) {
316
0
            unit_bits = cval->range_bits;
317
0
            ASN_DEBUG("APER encoding ASN_OSUBV_U32 range_bits = %d\n", cval->range_bits);
318
0
        }
319
0
        bpc = OS__BPC_U32;
320
0
        sizeinunits = st->size / 4;
321
0
        break;
322
/*
323
    case ASN_OSUBV_ANY:
324
        ASN__ENCODE_FAILED;
325
*/
326
0
    case ASN_OSUBV_BIT:
327
0
    default:
328
0
        canonical_unit_bits = unit_bits = 1;
329
0
        bpc = OS__BPC_BIT;
330
0
        sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
331
0
        ASN_DEBUG("BIT STRING of %d bytes", sizeinunits);
332
0
        break;
333
0
    }
334
335
0
    ASN_DEBUG("Encoding %s into %d units of %d bits"
336
0
              " (%lld..%lld, effective %d)%s",
337
0
              td->name, sizeinunits, unit_bits,
338
0
              (long long int)csiz->lower_bound,
339
0
              (long long int)csiz->upper_bound,
340
0
              csiz->effective_bits, ct_extensible ? " EXT" : "");
341
342
    /* Figure out wheter size lies within PER visible constraint */
343
344
0
    if(csiz->effective_bits >= 0) {
345
0
        if((int)sizeinunits < csiz->lower_bound
346
0
        || (int)sizeinunits > csiz->upper_bound) {
347
0
            if(ct_extensible) {
348
0
                cval = &asn_DEF_OCTET_STRING_constraints.value;
349
0
                csiz = &asn_DEF_OCTET_STRING_constraints.size;
350
0
                unit_bits = canonical_unit_bits;
351
0
                inext = 1;
352
0
            } else
353
0
                ASN__ENCODE_FAILED;
354
0
        }
355
0
    } else {
356
0
        inext = 0;
357
0
    }
358
359
0
    if(ct_extensible) {
360
        /* Declare whether length is [not] within extension root */
361
0
        if(per_put_few_bits(po, inext, 1))
362
0
            ASN__ENCODE_FAILED;
363
0
    }
364
365
    /* X.691, #16.5: zero-length encoding */
366
    /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
367
    /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
368
0
    if(csiz->effective_bits >= 0) {
369
0
        ASN_DEBUG("Encoding %zu bytes (%lld), length in %d bits",
370
0
                  st->size, (long long int)(sizeinunits - csiz->lower_bound),
371
0
                  csiz->effective_bits);
372
0
        if (csiz->effective_bits > 0) {
373
0
                ret = aper_put_length(po, csiz->lower_bound, csiz->upper_bound,
374
0
                                      sizeinunits - csiz->lower_bound, NULL);
375
0
                if(ret < 0) ASN__ENCODE_FAILED;
376
0
        }
377
0
        if (csiz->effective_bits > 0 || (st->size > 2)
378
0
            || (csiz->upper_bound > (2 * 8 / unit_bits))
379
0
            || (csiz->range_bits != 0))
380
0
        { /* X.691 #16 NOTE 1 for fixed length (<=16 bits) strings*/
381
0
            if (aper_put_align(po) < 0)
382
0
                ASN__ENCODE_FAILED;
383
0
        }
384
0
        if(bpc) {
385
0
            ret = OCTET_STRING_per_put_characters(po, st->buf,
386
0
                                                  sizeinunits,
387
0
                                                  bpc, unit_bits,
388
0
                                                  cval->lower_bound,
389
0
                                                  cval->upper_bound,
390
0
                                                  pc);
391
0
        } else {
392
0
            ret = per_put_many_bits(po, st->buf,
393
0
                                    sizeinunits * unit_bits);
394
0
        }
395
0
        if(ret) ASN__ENCODE_FAILED;
396
0
        ASN__ENCODED_OK(er);
397
0
    }
398
399
0
    ASN_DEBUG("Encoding %zu bytes", st->size);
400
401
0
    if(sizeinunits == 0) {
402
0
        if(aper_put_length(po, -1, -1, 0, NULL) < 0)
403
0
            ASN__ENCODE_FAILED;
404
0
        ASN__ENCODED_OK(er);
405
0
    }
406
407
0
    buf = st->buf;
408
0
    while(sizeinunits) {
409
0
        int need_eom = 0;
410
0
        ssize_t maySave = aper_put_length(po, -1, -1, sizeinunits, &need_eom);
411
412
0
        if(maySave < 0) ASN__ENCODE_FAILED;
413
414
0
        ASN_DEBUG("Encoding %ld of %ld",
415
0
                  (long)maySave, (long)sizeinunits);
416
417
0
        if(bpc) {
418
0
            ret = OCTET_STRING_per_put_characters(po, buf, maySave,
419
0
                                                  bpc, unit_bits,
420
0
                                                  cval->lower_bound,
421
0
                                                  cval->upper_bound,
422
0
                                                  pc);
423
0
        } else {
424
0
            ret = per_put_many_bits(po, buf, maySave * unit_bits);
425
0
        }
426
0
        if(ret) ASN__ENCODE_FAILED;
427
428
0
        if(bpc)
429
0
            buf += maySave * bpc;
430
0
        else
431
0
            buf += maySave >> 3;
432
0
        sizeinunits -= maySave;
433
0
        assert(!(maySave & 0x07) || !sizeinunits);
434
0
        if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0))
435
0
            ASN__ENCODE_FAILED; /* End of Message length */
436
0
    }
437
438
0
    ASN__ENCODED_OK(er);
439
0
}