Coverage Report

Created: 2026-11-06 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/asn1c/common/OCTET_STRING_rfill.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
9
/*
10
 * Biased function for randomizing character values around their limits.
11
 */
12
static uint32_t
13
0
OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
14
0
    assert(lb <= ub);
15
0
    switch(asn_random_between(0, 16)) {
16
0
    case 0:
17
0
        if(lb < ub) return lb + 1;
18
        /* Fall through */
19
0
    case 1:
20
0
        return lb;
21
0
    case 2:
22
0
        if(lb < ub) return ub - 1;
23
        /* Fall through */
24
0
    case 3:
25
0
        return ub;
26
0
    default:
27
0
        return asn_random_between(lb, ub);
28
0
    }
29
0
}
30
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,
34
0
                         size_t max_length) {
35
0
    const asn_OCTET_STRING_specifics_t *specs = td->specifics
36
0
        ? (const asn_OCTET_STRING_specifics_t *)td->specifics
37
0
        : &asn_SPC_OCTET_STRING_specs;
38
0
    asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
39
0
    asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
40
0
    asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
41
0
    unsigned int unit_bytes = 1;
42
0
    unsigned long clb = 0;  /* Lower bound on char */
43
0
    unsigned long cub = 255;  /* Higher bound on char value */
44
0
    uint8_t *buf;
45
0
    uint8_t *bend;
46
0
    uint8_t *b;
47
0
    size_t rnd_len;
48
0
    OCTET_STRING_t *st;
49
50
0
    if(max_length == 0 && !*sptr) return result_skipped;
51
52
0
    switch(specs->subvariant) {
53
0
    default:
54
0
    case ASN_OSUBV_ANY:
55
0
        return result_failed;
56
0
    case ASN_OSUBV_BIT:
57
        /* Handled by BIT_STRING itself. */
58
0
        return result_failed;
59
0
    case ASN_OSUBV_STR:
60
0
        unit_bytes = 1;
61
0
        clb = 0;
62
0
        cub = 255;
63
0
        break;
64
0
    case ASN_OSUBV_U16:
65
0
        unit_bytes = 2;
66
0
        clb = 0;
67
0
        cub = 65535;
68
0
        break;
69
0
    case ASN_OSUBV_U32:
70
0
        unit_bytes = 4;
71
0
        clb = 0;
72
0
        cub = 0x10FFFF;
73
0
        break;
74
0
    }
75
76
0
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
77
0
    if(!constraints || !constraints->per_constraints)
78
0
        constraints = &td->encoding_constraints;
79
0
    if(constraints->per_constraints) {
80
0
        const asn_per_constraint_t *pc = &constraints->per_constraints->value;
81
0
        if(pc->flags & APC_SEMI_CONSTRAINED) {
82
0
            clb = pc->lower_bound;
83
0
        } else if(pc->flags & APC_CONSTRAINED) {
84
0
            clb = pc->lower_bound;
85
0
            cub = pc->upper_bound;
86
0
        }
87
0
    }
88
#else
89
    if(!constraints) constraints = &td->encoding_constraints;
90
#endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
91
92
0
    rnd_len =
93
0
        OCTET_STRING_random_length_constrained(td, constraints, max_length);
94
95
0
    buf = CALLOC(unit_bytes, rnd_len + 1);
96
0
    if(!buf) return result_failed;
97
98
0
    bend = &buf[unit_bytes * rnd_len];
99
100
0
    switch(unit_bytes) {
101
0
    case 1:
102
0
        for(b = buf; b < bend; b += unit_bytes) {
103
0
            *(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
104
0
        }
105
0
        *(uint8_t *)b = 0;
106
0
        break;
107
0
    case 2:
108
0
        for(b = buf; b < bend; b += unit_bytes) {
109
0
            uint32_t code = OCTET_STRING__random_char(clb, cub);
110
0
            b[0] = code >> 8;
111
0
            b[1] = code;
112
0
        }
113
0
        *(uint16_t *)b = 0;
114
0
        break;
115
0
    case 4:
116
0
        for(b = buf; b < bend; b += unit_bytes) {
117
0
            uint32_t code = OCTET_STRING__random_char(clb, cub);
118
0
            b[0] = code >> 24;
119
0
            b[1] = code >> 16;
120
0
            b[2] = code >> 8;
121
0
            b[3] = code;
122
0
        }
123
0
        *(uint32_t *)b = 0;
124
0
        break;
125
0
    }
126
127
0
    if(*sptr) {
128
0
        st = *sptr;
129
0
        FREEMEM(st->buf);
130
0
    } else {
131
0
        st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
132
0
        if(!st) {
133
0
            FREEMEM(buf);
134
0
            return result_failed;
135
0
        }
136
0
    }
137
138
0
    st->buf = buf;
139
0
    st->size = unit_bytes * rnd_len;
140
141
0
    result_ok.length = st->size;
142
0
    return result_ok;
143
0
}
144
145
size_t
146
OCTET_STRING_random_length_constrained(
147
    const asn_TYPE_descriptor_t *td,
148
0
    const asn_encoding_constraints_t *constraints, size_t max_length) {
149
0
    const unsigned lengths[] = {0,     1,     2,     3,     4,     8,
150
0
                                126,   127,   128,   16383, 16384, 16385,
151
0
                                65534, 65535, 65536, 65537};
152
0
    size_t rnd_len;
153
154
    /* Figure out how far we should go */
155
0
    rnd_len = lengths[asn_random_between(
156
0
        0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
157
158
0
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
159
0
    if(!constraints || !constraints->per_constraints)
160
0
        constraints = &td->encoding_constraints;
161
0
    if(constraints->per_constraints) {
162
0
        const asn_per_constraint_t *pc = &constraints->per_constraints->size;
163
0
        if(pc->flags & APC_CONSTRAINED) {
164
0
            long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
165
0
                                             ? pc->upper_bound
166
0
                                             : (ssize_t)max_length;
167
0
            if(max_length <= (size_t)pc->lower_bound) {
168
0
                return pc->lower_bound;
169
0
            }
170
0
            if(pc->flags & APC_EXTENSIBLE) {
171
0
                switch(asn_random_between(0, 5)) {
172
0
                case 0:
173
0
                    if(pc->lower_bound > 0) {
174
0
                        rnd_len = pc->lower_bound - 1;
175
0
                        break;
176
0
                    }
177
                    /* Fall through */
178
0
                case 1:
179
0
                    rnd_len = pc->upper_bound + 1;
180
0
                    break;
181
0
                case 2:
182
                    /* Keep rnd_len from the table */
183
0
                    if(rnd_len <= max_length) {
184
0
                        break;
185
0
                    }
186
                    /* Fall through */
187
0
                default:
188
0
                    rnd_len = asn_random_between(pc->lower_bound,
189
0
                                                 suggested_upper_bound);
190
0
                }
191
0
            } else {
192
0
                rnd_len =
193
0
                    asn_random_between(pc->lower_bound, suggested_upper_bound);
194
0
            }
195
0
        } else {
196
0
            rnd_len = asn_random_between(0, max_length);
197
0
        }
198
0
    } else {
199
#else
200
    if(!constraints) constraints = &td->encoding_constraints;
201
    {
202
#endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
203
0
        if(rnd_len > max_length) {
204
0
            rnd_len = asn_random_between(0, max_length);
205
0
        }
206
0
    }
207
208
0
    return rnd_len;
209
0
}