Coverage Report

Created: 2026-08-14 06:04

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
11.0k
#define RETURN(_code) do {\
12
11.0k
        asn_dec_rval_t tmprval;\
13
11.0k
        tmprval.code = _code;\
14
11.0k
        tmprval.consumed = consumed_myself;\
15
11.0k
        return tmprval;\
16
11.0k
    } 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
17.5k
                         void **sptr, asn_per_data_t *pd) {
29
30
17.5k
    const asn_OCTET_STRING_specifics_t *specs = td->specifics
31
17.5k
        ? (const asn_OCTET_STRING_specifics_t *)td->specifics
32
17.5k
        : &asn_SPC_OCTET_STRING_specs;
33
17.5k
    const asn_per_constraints_t *pc = constraints
34
17.5k
        ? constraints
35
17.5k
        : td->encoding_constraints.per_constraints;
36
17.5k
    const asn_per_constraint_t *cval;
37
17.5k
    const asn_per_constraint_t *csiz;
38
17.5k
    asn_dec_rval_t rval = { RC_OK, 0 };
39
17.5k
    BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
40
17.5k
    ssize_t consumed_myself = 0;
41
17.5k
    int repeat;
42
17.5k
    enum {
43
17.5k
        OS__BPC_BIT = 0,
44
17.5k
        OS__BPC_CHAR = 1,
45
17.5k
        OS__BPC_U16 = 2,
46
17.5k
        OS__BPC_U32 = 4
47
17.5k
    } bpc;  /* Bytes per character */
48
17.5k
    unsigned int unit_bits;
49
17.5k
    unsigned int canonical_unit_bits;
50
51
17.5k
    (void)opt_codec_ctx;
52
53
17.5k
    if(pc) {
54
13.4k
        cval = &pc->value;
55
13.4k
        csiz = &pc->size;
56
13.4k
    } else {
57
4.07k
        cval = &asn_DEF_OCTET_STRING_constraints.value;
58
4.07k
        csiz = &asn_DEF_OCTET_STRING_constraints.size;
59
4.07k
    }
60
61
17.5k
    switch(specs->subvariant) {
62
0
    case ASN_OSUBV_ANY:
63
12.3k
    case ASN_OSUBV_STR:
64
12.3k
        canonical_unit_bits = unit_bits = 8;
65
12.3k
        if(cval->flags & APC_CONSTRAINED) {
66
            /* follow power of 2 rule */
67
4.16k
            if (cval->range_bits <= 2) {
68
0
            unit_bits = 2;
69
4.16k
            } else {
70
4.16k
          if (cval->range_bits <= 4) {
71
0
              unit_bits = 4;
72
              /* otherwise, unit_bits = 8; */
73
0
          }
74
4.16k
     }
75
           /* unit_bits = cval->range_bits; */
76
4.16k
           ASN_DEBUG("APER decoding ASN_OSUBV_STR range_bits = %d unit_bits = %d\n",
77
4.16k
              cval->range_bits, unit_bits);
78
4.16k
        }
79
12.3k
        bpc = OS__BPC_CHAR;
80
12.3k
        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
5.26k
    case ASN_OSUBV_BIT:
103
5.26k
    default:
104
5.26k
        canonical_unit_bits = unit_bits = 1;
105
5.26k
        bpc = OS__BPC_BIT;
106
5.26k
        break;
107
17.5k
    }
108
109
    /*
110
     * Allocate the string.
111
     */
112
17.5k
    if(!st) {
113
7.15k
        st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
114
7.15k
        if(!st) RETURN(RC_FAIL);
115
7.15k
    }
116
117
17.5k
    ASN_DEBUG("PER Decoding %s size %lld .. %lld bits %d",
118
17.5k
              csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
119
17.5k
              (long long int)csiz->lower_bound, (long long int)csiz->upper_bound,
120
17.5k
              csiz->effective_bits);
121
122
17.5k
    if(csiz->flags & APC_EXTENSIBLE) {
123
2.05k
        int inext = per_get_few_bits(pd, 1);
124
2.05k
        if(inext < 0) RETURN(RC_WMORE);
125
2.05k
        if(inext) {
126
625
            csiz = &asn_DEF_OCTET_STRING_constraints.size;
127
625
            cval = &asn_DEF_OCTET_STRING_constraints.value;
128
625
            unit_bits = canonical_unit_bits;
129
625
        }
130
2.05k
    }
131
132
17.5k
    if(csiz->effective_bits >= 0) {
133
12.3k
        FREEMEM(st->buf);
134
12.3k
        if(bpc) {
135
7.69k
            st->size = csiz->upper_bound * bpc;
136
7.69k
        } else {
137
4.61k
            st->size = (csiz->upper_bound + 7) >> 3;
138
4.61k
        }
139
12.3k
        st->buf = (uint8_t *)MALLOC(st->size + 1);
140
12.3k
        if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
141
12.3k
    }
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
17.5k
    if(csiz->effective_bits == 0) {
147
10.8k
        int ret;
148
        /* X.691 #16 NOTE 1 for fixed length (<= 16 bits) strings */
149
10.8k
        if (st->size > 2 || csiz->range_bits != 0) {
150
5.28k
            if (aper_get_align(pd) < 0)
151
0
                RETURN(RC_FAIL);
152
5.28k
        }
153
10.8k
        if(bpc) {
154
7.61k
            ASN_DEBUG("Decoding OCTET STRING size %lld",
155
7.61k
                      (long long int)csiz->upper_bound);
156
7.61k
            ret = OCTET_STRING_per_get_characters(pd, st->buf,
157
7.61k
                                                  csiz->upper_bound,
158
7.61k
                                                  bpc, unit_bits,
159
7.61k
                                                  cval->lower_bound,
160
7.61k
                                                  cval->upper_bound,
161
7.61k
                                                  pc);
162
7.61k
            if(ret > 0) RETURN(RC_FAIL);
163
7.61k
        } else {
164
3.23k
            ASN_DEBUG("Decoding BIT STRING size %lld",
165
3.23k
                      (long long int)csiz->upper_bound);
166
3.23k
            ret = per_get_many_bits(pd, st->buf, 0,
167
3.23k
                                    unit_bits * csiz->upper_bound);
168
3.23k
        }
169
10.8k
        if(ret < 0) RETURN(RC_WMORE);
170
10.6k
        consumed_myself += unit_bits * csiz->upper_bound;
171
10.6k
        st->buf[st->size] = 0;
172
10.6k
        if(bpc == 0) {
173
3.17k
            int ubs = (csiz->upper_bound & 0x7);
174
3.17k
            st->bits_unused = ubs ? 8 - ubs : 0;
175
3.17k
        }
176
10.6k
        RETURN(RC_OK);
177
10.6k
    }
178
179
6.71k
    st->size = 0;
180
6.71k
    do {
181
6.71k
        ssize_t raw_len;
182
6.71k
        ssize_t len_bytes;
183
6.71k
        ssize_t len_bits;
184
6.71k
        void *p;
185
6.71k
        int ret;
186
187
6.71k
        repeat = 0;
188
        /* Get the PER length */
189
6.71k
        if (csiz->upper_bound - csiz->lower_bound == 0)
190
            /* Indefinite length case */
191
5.22k
            raw_len = aper_get_length(pd, -1, -1, csiz->effective_bits, &repeat);
192
1.49k
        else
193
1.49k
            raw_len = aper_get_length(pd, csiz->lower_bound, csiz->upper_bound,
194
1.49k
                                      csiz->effective_bits, &repeat);
195
6.71k
        if(raw_len < 0) RETURN(RC_WMORE);
196
197
6.60k
        ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
198
6.60k
                  (long)csiz->effective_bits, (long)raw_len,
199
6.60k
                  repeat ? "repeat" : "once", td->name);
200
201
        /* X.691 #16 NOTE 1  for fixed length (<=16 bits) strings */
202
6.60k
        if ((raw_len > 2) || (csiz->upper_bound > 2) || (csiz->range_bits != 0))
203
6.60k
        {
204
6.60k
            if (aper_get_align(pd) < 0)
205
0
                RETURN(RC_FAIL);
206
6.60k
        }
207
208
6.60k
        if(bpc) {
209
4.60k
            len_bytes = raw_len * bpc;
210
4.60k
            len_bits = len_bytes * unit_bits;
211
4.60k
        } else {
212
1.99k
            len_bits = raw_len;
213
1.99k
            len_bytes = (len_bits + 7) >> 3;
214
1.99k
            if(len_bits & 0x7)
215
1.68k
                st->bits_unused = 8 - (len_bits & 0x7);
216
            /* len_bits be multiple of 16K if repeat is set */
217
1.99k
        }
218
6.60k
        p = REALLOC(st->buf, st->size + len_bytes + 1);
219
6.60k
        if(!p) RETURN(RC_FAIL);
220
6.60k
        st->buf = (uint8_t *)p;
221
222
6.60k
        if(bpc) {
223
4.60k
            ret = OCTET_STRING_per_get_characters(pd,
224
4.60k
                                                  &st->buf[st->size],
225
4.60k
                                                  raw_len, bpc,
226
4.60k
                                                  unit_bits,
227
4.60k
                                                  cval->lower_bound,
228
4.60k
                                                  cval->upper_bound,
229
4.60k
                                                  pc);
230
4.60k
            if(ret > 0) RETURN(RC_FAIL);
231
4.60k
        } else {
232
1.99k
            ret = per_get_many_bits(pd, &st->buf[st->size],
233
1.99k
                                    0, len_bits);
234
1.99k
        }
235
6.60k
        if(ret < 0) RETURN(RC_WMORE);
236
6.47k
        st->size += len_bytes;
237
6.47k
    } while(repeat);
238
6.47k
    st->buf[st->size] = 0;  /* nul-terminate */
239
240
6.47k
    return rval;
241
6.71k
}
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
}