Coverage Report

Created: 2025-12-27 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/unit/src/nxt_parse.c
Line
Count
Source
1
2
/*
3
 * Copyright (C) Igor Sysoev
4
 * Copyright (C) NGINX, Inc.
5
 */
6
7
#include <nxt_main.h>
8
9
10
/*
11
 * nxt_int_parse() returns size_t value >= 0 on success,
12
 * -1 on failure, and -2 on overflow.
13
 */
14
15
nxt_int_t
16
nxt_int_parse(const u_char *p, size_t length)
17
1.78k
{
18
1.78k
    u_char      c;
19
1.78k
    nxt_uint_t  val;
20
21
1.78k
    static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
22
1.78k
    static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
23
24
1.78k
    if (nxt_fast_path(length != 0)) {
25
26
1.78k
        val = 0;
27
28
8.15k
        do {
29
8.15k
            c = *p++;
30
31
            /* Values below '0' become >= 208. */
32
8.15k
            c = c - '0';
33
34
8.15k
            if (nxt_slow_path(c > 9)) {
35
750
                return -1;
36
750
            }
37
38
7.40k
            if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
39
                /* An overflow. */
40
452
                return -2;
41
452
            }
42
43
6.95k
            val = val * 10 + c;
44
45
6.95k
            length--;
46
47
6.95k
        } while (length != 0);
48
49
578
        return val;
50
1.78k
    }
51
52
0
    return -1;
53
1.78k
}
54
55
56
/*
57
 * nxt_size_t_parse() returns size_t value >= 0 on success,
58
 * -1 on failure, and -2 on overflow.
59
 */
60
61
ssize_t
62
nxt_size_t_parse(const u_char *p, size_t length)
63
2.48k
{
64
2.48k
    u_char  c;
65
2.48k
    size_t  val;
66
67
2.48k
    static const size_t cutoff = NXT_SIZE_T_MAX / 10;
68
2.48k
    static const size_t cutlim = NXT_SIZE_T_MAX % 10;
69
70
2.48k
    if (nxt_fast_path(length != 0)) {
71
72
2.48k
        val = 0;
73
74
20.1k
        do {
75
20.1k
            c = *p++;
76
77
            /* Values below '0' become >= 208. */
78
20.1k
            c = c - '0';
79
80
20.1k
            if (nxt_slow_path(c > 9)) {
81
1.54k
                return -1;
82
1.54k
            }
83
84
18.6k
            if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
85
                /* An overflow. */
86
280
                return -2;
87
280
            }
88
89
18.3k
            val = val * 10 + c;
90
91
18.3k
            length--;
92
93
18.3k
        } while (length != 0);
94
95
653
        return val;
96
2.48k
    }
97
98
0
    return -1;
99
2.48k
}
100
101
102
/*
103
 * nxt_size_parse() parses size string with optional K or M units and
104
 * returns size_t value >= 0 on success, -1 on failure, and -2 on overflow.
105
 */
106
107
ssize_t
108
nxt_size_parse(const u_char *p, size_t length)
109
1.24k
{
110
1.24k
    u_char      unit;
111
1.24k
    ssize_t     val, max;
112
1.24k
    nxt_uint_t  shift;
113
114
1.24k
    if (nxt_fast_path(length != 0)) {
115
116
1.24k
        length--;
117
118
        /* Upper case. */
119
1.24k
        unit = p[length] & ~0x20;
120
121
1.24k
        switch (unit) {
122
123
187
        case 'G':
124
187
            max = NXT_SIZE_T_MAX >> 30;
125
187
            shift = 30;
126
187
            break;
127
128
128
        case 'M':
129
128
            max = NXT_SIZE_T_MAX >> 20;
130
128
            shift = 20;
131
128
            break;
132
133
67
        case 'K':
134
67
            max = NXT_SIZE_T_MAX >> 10;
135
67
            shift = 10;
136
67
            break;
137
138
859
        default:
139
859
            return nxt_size_t_parse(p, length + 1);
140
1.24k
        }
141
142
382
        val = nxt_size_t_parse(p, length);
143
144
382
        if (nxt_fast_path(val >= 0)) {
145
146
273
            if (nxt_slow_path(val > max)) {
147
                /* An overflow. */
148
159
                return -2;
149
159
            }
150
151
114
            val <<= shift;
152
114
        }
153
154
223
        return val;
155
382
    }
156
157
0
    return -1;
158
1.24k
}
159
160
161
/*
162
 * nxt_off_t_parse() returns nxt_off_t value >= 0 on success,
163
 * -1 on failure, and -2 on overflow.
164
 */
165
166
nxt_off_t
167
nxt_off_t_parse(const u_char *p, size_t length)
168
1.24k
{
169
1.24k
    u_char      c;
170
1.24k
    nxt_uoff_t  val;
171
172
1.24k
    static const nxt_uoff_t cutoff = NXT_OFF_T_MAX / 10;
173
1.24k
    static const nxt_uoff_t cutlim = NXT_OFF_T_MAX % 10;
174
175
1.24k
    if (nxt_fast_path(length != 0)) {
176
177
1.24k
        val = 0;
178
179
10.2k
        do {
180
10.2k
            c = *p++;
181
182
            /* Values below '0' become >= 208. */
183
10.2k
            c = c - '0';
184
185
10.2k
            if (nxt_slow_path(c > 9)) {
186
911
                return -1;
187
911
            }
188
189
9.31k
            if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
190
                /* An overflow. */
191
140
                return -2;
192
140
            }
193
194
9.17k
            val = val * 10 + c;
195
196
9.17k
            length--;
197
198
9.17k
        } while (length != 0);
199
200
190
        return val;
201
1.24k
    }
202
203
0
    return -1;
204
1.24k
}
205
206
207
/*
208
 * nxt_str_int_parse() returns nxt_int_t value >= 0 on success,
209
 * -1 on failure, and -2 on overflow and also updates the 's' argument.
210
 */
211
212
nxt_int_t
213
nxt_str_int_parse(nxt_str_t *s)
214
1.24k
{
215
1.24k
    u_char      c, *p;
216
1.24k
    size_t      length;
217
1.24k
    nxt_uint_t  val;
218
219
1.24k
    static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
220
1.24k
    static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
221
222
1.24k
    length = s->length;
223
224
1.24k
    if (nxt_slow_path(length == 0)) {
225
0
        return -1;
226
0
    }
227
228
1.24k
    p = s->start;
229
1.24k
    val = 0;
230
231
7.05k
    do {
232
7.05k
        c = *p;
233
234
        /* Values below '0' become >= 208. */
235
7.05k
        c = c - '0';
236
237
7.05k
        if (c > 9) {
238
727
            break;
239
727
        }
240
241
6.32k
        if (nxt_slow_path(val >= cutoff && (val > cutoff || c > cutlim))) {
242
            /* An overflow. */
243
452
            return -2;
244
452
        }
245
246
5.87k
        val = val * 10 + c;
247
248
5.87k
        p++;
249
5.87k
        length--;
250
251
5.87k
    } while (length != 0);
252
253
789
    s->length = length;
254
789
    s->start = p;
255
256
789
    return val;
257
1.24k
}
258
259
260
/*
261
 * nxt_number_parse() returns a double value >= 0 and updates the start
262
 * argument on success, or returns -1 on failure or -2 on overflow.
263
 */
264
265
double
266
nxt_number_parse(const u_char **start, const u_char *end)
267
1.24k
{
268
1.24k
    u_char        c;
269
1.24k
    nxt_bool_t    overflow;
270
1.24k
    nxt_uint_t    integral, frac, power;
271
1.24k
    const u_char  *p;
272
273
1.24k
    static const nxt_uint_t cutoff = NXT_INT_T_MAX / 10;
274
1.24k
    static const nxt_uint_t cutlim = NXT_INT_T_MAX % 10;
275
276
1.24k
    p = *start;
277
1.24k
    integral = 0;
278
279
7.11k
    while (p < end) {
280
7.05k
        c = *p;
281
282
7.05k
        if (c == '.') {
283
105
            goto dot;
284
105
        }
285
286
        /* Values below '0' become >= 208. */
287
6.94k
        c = c - '0';
288
289
6.94k
        if (c > 9) {
290
622
            break;
291
622
        }
292
293
6.32k
        overflow = nxt_expect(0, (integral >= cutoff
294
6.32k
                                  && (integral > cutoff || c > cutlim)));
295
296
6.32k
        if (overflow) {
297
452
            return -2;
298
452
        }
299
300
5.87k
        integral = integral * 10 + c;
301
302
5.87k
        p++;
303
5.87k
    }
304
305
684
    if (nxt_fast_path(p != *start)) {
306
291
        *start = p;
307
291
        return integral;
308
291
    }
309
310
    /* No value. */
311
393
    return -1;
312
313
105
dot:
314
315
105
    if (nxt_slow_path(p == *start)) {
316
        /* No leading digit before dot. */
317
1
        return -1;
318
1
    }
319
320
104
    frac = 0;
321
104
    power = 1;
322
323
877
    for (p++; p < end; p++) {
324
846
        c = *p;
325
326
        /* Values below '0' become >= 208. */
327
846
        c = c - '0';
328
329
846
        if (c > 9) {
330
8
            break;
331
8
        }
332
333
838
        overflow = nxt_expect(0, (frac >= cutoff && (frac > cutoff
334
838
                                                     || c > cutlim))
335
838
                                 || power > cutoff);
336
337
838
        if (overflow) {
338
65
            return -2;
339
65
        }
340
341
773
        frac = frac * 10 + c;
342
773
        power *= 10;
343
773
    }
344
345
39
    *start = p;
346
347
39
    return integral + (double) frac / power;
348
104
}