• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.65
/src/util-byte.c
1
/* Copyright (C) 2007-2010 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Brian Rectanus <brectanu@gmail.com>
22
 *
23
 * Byte utility functions
24
 */
25

26
#include "suricata-common.h"
27
#include "util-byte.h"
28
#include "util-unittest.h"
29
#include "util-debug.h"
30
#include "util-validate.h"
31

32
/** \brief Turn byte array into string.
33
 *
34
 *  All non-printables are copied over, except for '\0', which is
35
 *  turned into literal \0 in the string.
36
 *
37
 *  \param bytes byte array
38
 *  \param nbytes number of bytes
39
 *  \return string nul-terminated string or NULL on error
40
 */
41
char *BytesToString(const uint8_t *bytes, size_t nbytes)
42
{
×
43
    size_t n = nbytes + 1;
×
44
    size_t nulls = 0;
×
45

46
    size_t u;
×
47
    for (u = 0; u < nbytes; u++) {
×
48
        if (bytes[u] == '\0')
×
49
            nulls++;
×
50
    }
×
51
    n += nulls;
×
52

53
    char *string = SCCalloc(1, n);
×
54
    if (string == NULL)
×
55
        return NULL;
×
56

57
    if (nulls == 0) {
×
58
        /* no nulls */
59
        memcpy(string, bytes, nbytes);
×
60
    } else {
×
61
        /* nulls present */
62
        char *dst = string;
×
63
        for (u = 0; u < nbytes; u++) {
×
64
            if (bytes[u] == '\0') {
×
65
                *dst++ = '\\';
×
66
                *dst++ = '0';
×
67
            } else {
×
68
                *dst++ = bytes[u];
×
69
            }
×
70
        }
×
71
    }
×
72
    return string;
×
73
}
×
74

75
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
76
{
21,582✔
77
    uint64_t i64;
21,582✔
78
    int ret;
21,582✔
79

80
    /* Uint64 is limited to 8 bytes */
81
    if (len > 8) {
21,582✔
82
        /** \todo Need standard return values */
83
        return -1;
×
84
    }
×
85

86
    ret = ByteExtract(&i64, e, len, bytes);
21,582✔
87
    if (ret <= 0) {
21,582✔
88
        return ret;
2,547✔
89
    }
2,547✔
90

91
    *res = (uint64_t)i64;
19,035✔
92

93
    return ret;
19,035✔
94
}
21,582✔
95

96
/**
97
 * \retval Greater than 0 if successful, 0 or negative on failure.
98
 */
99
int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
UNCOV
100
{
×
UNCOV
101
    uint64_t i64;
×
UNCOV
102
    int ret;
×
103

104
    /* Uint32 is limited to 4 bytes */
UNCOV
105
    if (len > 4) {
×
106
        /** \todo Need standard return values */
107
        return -1;
×
108
    }
×
109

UNCOV
110
    ret = ByteExtract(&i64, e, len, bytes);
×
UNCOV
111
    if (ret <= 0) {
×
112
        return ret;
×
113
    }
×
114

UNCOV
115
    *res = (uint32_t)i64;
×
116

UNCOV
117
    return ret;
×
UNCOV
118
}
×
119

120
int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
UNCOV
121
{
×
UNCOV
122
    uint64_t i64;
×
UNCOV
123
    int ret;
×
124

125
    /* Uint16 is limited to 2 bytes */
UNCOV
126
    if (len > 2) {
×
127
        /** \todo Need standard return values */
128
        return -1;
×
129
    }
×
130

UNCOV
131
    ret = ByteExtract(&i64, e, len, bytes);
×
UNCOV
132
    if (ret <= 0) {
×
133
        return ret;
×
134
    }
×
135

UNCOV
136
    *res = (uint16_t)i64;
×
137

UNCOV
138
    return ret;
×
UNCOV
139
}
×
140

141
int ByteExtractString(uint64_t *res, int base, size_t len, const char *str, bool strict)
142
{
4,709,690✔
143
    const char *ptr = str;
4,709,690✔
144
    char *endptr = NULL;
4,709,690✔
145

146
    /* 23 - This is the largest string (octal, with a zero prefix) that
147
     *      will not overflow uint64_t.  The only way this length
148
     *      could be over 23 and still not overflow is if it were zero
149
     *      prefixed and we only support 1 byte of zero prefix for octal.
150
     *
151
     * "01777777777777777777777" = 0xffffffffffffffff
152
     */
153
    char strbuf[24];
4,709,690✔
154

155
    if (len > 23) {
4,709,690✔
156
        SCLogDebug("len too large (23 max)");
31,299✔
157
        return -1;
31,299✔
158
    }
31,299✔
159

160
    if (len) {
4,678,391✔
161
        /* Extract out the string so it can be null terminated */
162
        memcpy(strbuf, str, len);
2,700,536✔
163
        strbuf[len] = '\0';
2,700,536✔
164
        ptr = strbuf;
2,700,536✔
165
    }
2,700,536✔
166

167
    errno = 0;
4,678,391✔
168
    *res = strtoull(ptr, &endptr, base);
4,678,391✔
169

170
    if (errno == ERANGE) {
4,678,391✔
171
        SCLogDebug("numeric value out of range");
4,959✔
172
        return -1;
4,959✔
173
        /* If there is no numeric value in the given string then strtoull(), makes
174
        endptr equals to ptr and return 0 as result */
175
    } else if (endptr == ptr && *res == 0) {
4,673,432✔
176
        SCLogDebug("no numeric value");
83,967✔
177
        return -1;
83,967✔
178
    } else if (endptr == ptr) {
4,589,465✔
179
        SCLogDebug("invalid numeric value");
×
180
        return -1;
×
181
    }
×
182
    else if (strict && *endptr != '\0') {
4,589,465✔
183
        SCLogError("Extra characters following numeric value");
14,735✔
184
        return -1;
14,735✔
185
    }
14,735✔
186

187
    return (int)(endptr - ptr);
4,574,730✔
188
}
4,678,391✔
189

190
int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
191
{
36,132✔
192
    return ByteExtractString(res, base, len, str, false);
36,132✔
193
}
36,132✔
194

195
int ByteExtractStringUint32(uint32_t *res, int base, size_t len, const char *str)
196
{
2,688,841✔
197
    uint64_t i64;
2,688,841✔
198

199
    int ret = ByteExtractString(&i64, base, len, str, false);
2,688,841✔
200
    if (ret <= 0) {
2,688,841✔
201
        return ret;
42,021✔
202
    }
42,021✔
203
    if (i64 > UINT32_MAX) {
2,646,820✔
204
        return -1;
20,072✔
205
    }
20,072✔
206

207
    *res = (uint32_t)i64;
2,626,748✔
208

209
    if ((uint64_t)(*res) != i64) {
2,626,748✔
210
        SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
×
211
                i64, (uintmax_t)UINT_MAX);
×
212
        return -1;
×
213
    }
×
214

215
    return ret;
2,626,748✔
216
}
2,626,748✔
217

218
int ByteExtractStringUint16(uint16_t *res, int base, size_t len, const char *str)
UNCOV
219
{
×
UNCOV
220
    uint64_t i64;
×
221

UNCOV
222
    int ret = ByteExtractString(&i64, base, len, str, false);
×
UNCOV
223
    if (ret <= 0) {
×
224
        return ret;
×
225
    }
×
UNCOV
226
    if (i64 > UINT16_MAX) {
×
227
        return -1;
×
228
    }
×
229

UNCOV
230
    *res = (uint16_t)i64;
×
231

UNCOV
232
    if ((uint64_t)(*res) != i64) {
×
233
        SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
×
234
                i64, (uintmax_t)USHRT_MAX);
×
235
        return -1;
×
236
    }
×
237

UNCOV
238
    return ret;
×
UNCOV
239
}
×
240

241
int ByteExtractStringUint8(uint8_t *res, int base, size_t len, const char *str)
242
{
407✔
243
    uint64_t i64;
407✔
244

245
    int ret = ByteExtractString(&i64, base, len, str, false);
407✔
246
    if (ret <= 0) {
407✔
247
        return ret;
×
248
    }
×
249
    if (i64 > UINT8_MAX) {
407✔
250
        return -1;
86✔
251
    }
86✔
252

253
    *res = (uint8_t)i64;
321✔
254

255
    if ((uint64_t)(*res) != i64) {
321✔
256
        SCLogDebug("Numeric value out of range (%" PRIu64 " > %" PRIuMAX ")",
×
257
                i64, (uintmax_t)UCHAR_MAX);
×
258
        return -1;
×
259
    }
×
260

261
    return ret;
321✔
262
}
321✔
263

264
int StringParseUint64(uint64_t *res, int base, size_t len, const char *str)
265
{
×
266
    return ByteExtractString(res, base, len, str, true);
×
267
}
×
268

269
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
270
{
78,001✔
271
    uint64_t i64;
78,001✔
272

273
    int ret = ByteExtractString(&i64, base, len, str, true);
78,001✔
274
    if (ret <= 0) {
78,001✔
275
        return ret;
3,203✔
276
    }
3,203✔
277
    if (i64 > UINT32_MAX) {
74,798✔
278
        return -1;
135✔
279
    }
135✔
280

281
    *res = (uint32_t)i64;
74,663✔
282

283
    if ((uint64_t)(*res) != i64) {
74,663✔
284
        SCLogError("Numeric value out of range "
×
285
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
286
                i64, (uintmax_t)UINT_MAX);
×
287
        return -1;
×
288
    }
×
289

290
    return ret;
74,663✔
291
}
74,663✔
292

293
/**
294
 * \retval Greater than 0 if successful, 0 or negative on failure.
295
 */
296
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
297
{
1,571,132✔
298
    uint64_t i64;
1,571,132✔
299

300
    int ret = ByteExtractString(&i64, base, len, str, true);
1,571,132✔
301
    if (ret <= 0) {
1,571,132✔
302
        return ret;
73,155✔
303
    }
73,155✔
304
    if (i64 > UINT16_MAX) {
1,497,977✔
305
        return -1;
3,582✔
306
    }
3,582✔
307

308
    *res = (uint16_t)i64;
1,494,395✔
309

310
    if ((uint64_t)(*res) != i64) {
1,494,395✔
311
        SCLogError("Numeric value out of range "
×
312
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
313
                i64, (uintmax_t)USHRT_MAX);
×
314
        return -1;
×
315
    }
×
316

317
    return ret;
1,494,395✔
318
}
1,494,395✔
319

320
/**
321
 * \retval Greater than 0 if successful, 0 or negative on failure.
322
 */
323
int StringParseUint8(uint8_t *res, int base, size_t len, const char *str)
324
{
18,144✔
325
    uint64_t i64;
18,144✔
326

327
    int ret = ByteExtractString(&i64, base, len, str, true);
18,144✔
328
    if (ret <= 0) {
18,144✔
329
        return ret;
2,037✔
330
    }
2,037✔
331
    if (i64 > UINT8_MAX) {
16,107✔
332
        return -1;
514✔
333
    }
514✔
334

335
    *res = (uint8_t)i64;
15,593✔
336

337
    if ((uint64_t)(*res) != i64) {
15,593✔
338
        SCLogError("Numeric value out of range "
×
339
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
340
                i64, (uintmax_t)UCHAR_MAX);
×
341
        return -1;
×
342
    }
×
343

344
    return ret;
15,593✔
345
}
15,593✔
346

347
int StringParseU64RangeCheck(
348
        uint64_t *res, int base, size_t len, const char *str, uint64_t min, uint64_t max)
349
{
×
350
    uint64_t u64;
×
351

352
    int ret = ByteExtractString(&u64, base, len, str, true);
×
353
    if (ret <= 0) {
×
354
        return ret;
×
355
    }
×
356

357
    *res = u64;
×
358

359
    if (*res < min || *res > max) {
×
360
        return -1;
×
361
    }
×
362

363
    return ret;
×
364
}
×
365

366
int StringParseU32RangeCheck(
367
        uint32_t *res, int base, size_t len, const char *str, uint32_t min, uint32_t max)
UNCOV
368
{
×
UNCOV
369
    uint64_t u64;
×
370

UNCOV
371
    int ret = ByteExtractString(&u64, base, len, str, true);
×
UNCOV
372
    if (ret <= 0) {
×
373
        return ret;
×
374
    }
×
UNCOV
375
    if (u64 > UINT32_MAX) {
×
376
        return -1;
×
377
    }
×
378

UNCOV
379
    *res = (uint32_t)u64;
×
380

UNCOV
381
    if (*res < min || *res > max) {
×
382
        return -1;
×
383
    }
×
384

UNCOV
385
    if ((uint64_t)(*res) != u64) {
×
386
        SCLogError("Numeric value out of range "
×
387
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
388
                u64, (uintmax_t)UINT_MAX);
×
389
        return -1;
×
390
    }
×
391

UNCOV
392
    return ret;
×
UNCOV
393
}
×
394

395
int StringParseU16RangeCheck(
396
        uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
397
{
337✔
398
    uint64_t u64;
337✔
399

400
    int ret = ByteExtractString(&u64, base, len, str, true);
337✔
401
    if (ret <= 0) {
337✔
402
        return ret;
50✔
403
    }
50✔
404
    if (u64 > UINT16_MAX) {
287✔
405
        return -1;
24✔
406
    }
24✔
407

408
    *res = (uint16_t)u64;
263✔
409

410
    if (*res < min || *res > max) {
263✔
411
        return -1;
1✔
412
    }
1✔
413

414
    if ((uint64_t)(*res) != u64) {
262✔
415
        SCLogError("Numeric value out of range "
×
416
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
417
                u64, (uintmax_t)USHRT_MAX);
×
418
        return -1;
×
419
    }
×
420

421
    return ret;
262✔
422
}
262✔
423

424
/**
425
 * \retval Greater than 0 if successful, 0 or negative on failure.
426
 */
427
int StringParseU8RangeCheck(
428
        uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
429
{
316,696✔
430
    uint64_t u64;
316,696✔
431

432
    int ret = ByteExtractString(&u64, base, len, str, true);
316,696✔
433
    if (ret <= 0) {
316,696✔
434
        return ret;
4,153✔
435
    }
4,153✔
436
    if (u64 > UINT8_MAX) {
312,543✔
437
        return -1;
×
438
    }
×
439

440
    *res = (uint8_t)u64;
312,543✔
441

442
    if (*res < min || *res > max) {
312,543✔
UNCOV
443
        return -1;
×
UNCOV
444
    }
×
445

446
    if ((uint64_t)(*res) != u64) {
312,543✔
447
        SCLogError("Numeric value out of range "
×
448
                   "(%" PRIu64 " > %" PRIuMAX ")",
×
449
                u64, (uintmax_t)UCHAR_MAX);
×
450
        return -1;
×
451
    }
×
452

453
    return ret;
312,543✔
454
}
312,543✔
455

456
int ByteExtractStringSigned(int64_t *res, int base, size_t len, const char *str, bool strict)
457
{
295,676✔
458
    const char *ptr = str;
295,676✔
459
    char *endptr;
295,676✔
460

461
    /* 23 - This is the largest string (octal, with a zero prefix) that
462
     *      will not overflow int64_t.  The only way this length
463
     *      could be over 23 and still not overflow is if it were zero
464
     *      prefixed and we only support 1 byte of zero prefix for octal.
465
     *
466
     * "-0777777777777777777777" = 0xffffffffffffffff
467
     */
468
    char strbuf[24];
295,676✔
469

470
    if (len > 23) {
295,676✔
471
        SCLogError("len too large (23 max)");
878✔
472
        return -1;
878✔
473
    }
878✔
474

475
    if (len) {
294,798✔
476
        /* Extract out the string so it can be null terminated */
477
        memcpy(strbuf, str, len);
29,970✔
478
        strbuf[len] = '\0';
29,970✔
479
        ptr = strbuf;
29,970✔
480
    }
29,970✔
481

482
    errno = 0;
294,798✔
483
    *res = strtoll(ptr, &endptr, base);
294,798✔
484

485
    if (errno == ERANGE) {
294,798✔
486
        SCLogError("Numeric value out of range");
962✔
487
        return -1;
962✔
488
    } else if (endptr == str) {
293,836✔
489
        SCLogError("Invalid numeric value");
5,773✔
490
        return -1;
5,773✔
491
    }
5,773✔
492
    else if (strict && len && *endptr != '\0') {
288,063✔
493
        SCLogError("Extra characters following numeric value");
1,687✔
494
        return -1;
1,687✔
495
    }
1,687✔
496

497
    //fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res);
498

499
    return (int)(endptr - ptr);
286,376✔
500
}
294,798✔
501

502
int ByteExtractStringInt64(int64_t *res, int base, size_t len, const char *str)
UNCOV
503
{
×
UNCOV
504
    return ByteExtractStringSigned(res, base, len, str, false);
×
UNCOV
505
}
×
506

507
int ByteExtractStringInt32(int32_t *res, int base, size_t len, const char *str)
UNCOV
508
{
×
UNCOV
509
    int64_t i64;
×
UNCOV
510
    int ret;
×
511

UNCOV
512
    ret = ByteExtractStringSigned(&i64, base, len, str, false);
×
UNCOV
513
    if (ret <= 0) {
×
514
        return ret;
×
515
    }
×
UNCOV
516
    if (i64 < INT32_MIN || i64 > INT32_MAX) {
×
517
        return -1;
×
518
    }
×
519

UNCOV
520
    *res = (int32_t)i64;
×
521

UNCOV
522
    if ((int64_t)(*res) != i64) {
×
523
        SCLogError("Numeric value out of range "
×
524
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
525
                i64, (intmax_t)INT_MAX);
×
526
        return -1;
×
527
    }
×
528

UNCOV
529
    return ret;
×
UNCOV
530
}
×
531

532
int ByteExtractStringInt16(int16_t *res, int base, size_t len, const char *str)
UNCOV
533
{
×
UNCOV
534
    int64_t i64;
×
UNCOV
535
    int ret;
×
536

UNCOV
537
    ret = ByteExtractStringSigned(&i64, base, len, str, false);
×
UNCOV
538
    if (ret <= 0) {
×
539
        return ret;
×
540
    }
×
UNCOV
541
    if (i64 < INT16_MIN || i64 > INT16_MAX) {
×
542
        return -1;
×
543
    }
×
544

UNCOV
545
    *res = (int16_t)i64;
×
546

UNCOV
547
    if ((int64_t)(*res) != i64) {
×
548
        SCLogError("Numeric value out of range "
×
549
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
550
                i64, (intmax_t)SHRT_MAX);
×
551
        return -1;
×
552
    }
×
553

UNCOV
554
    return ret;
×
UNCOV
555
}
×
556

557
int ByteExtractStringInt8(int8_t *res, int base, size_t len, const char *str)
UNCOV
558
{
×
UNCOV
559
    int64_t i64;
×
UNCOV
560
    int ret;
×
561

UNCOV
562
    ret = ByteExtractStringSigned(&i64, base, len, str, false);
×
UNCOV
563
    if (ret <= 0) {
×
564
        return ret;
×
565
    }
×
UNCOV
566
    if (i64 < INT8_MIN || i64 > INT8_MAX) {
×
567
        return -1;
×
568
    }
×
569

UNCOV
570
    *res = (int8_t)i64;
×
571

UNCOV
572
    if ((int64_t)(*res) != i64) {
×
573
        SCLogError("Numeric value out of range "
×
574
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
575
                i64, (intmax_t)CHAR_MAX);
×
576
        return -1;
×
577
    }
×
578

UNCOV
579
    return ret;
×
UNCOV
580
}
×
581

582
int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
583
{
43✔
584
    return ByteExtractStringSigned(res, base, len, str, true);
43✔
585
}
43✔
586

587
int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
588
{
27,378✔
589
    int64_t i64;
27,378✔
590
    int ret;
27,378✔
591

592
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
27,378✔
593
    if (ret <= 0) {
27,378✔
594
        return ret;
685✔
595
    }
685✔
596
    if (i64 < INT32_MIN || i64 > INT32_MAX) {
26,693✔
597
        return -1;
703✔
598
    }
703✔
599

600
    *res = (int32_t)i64;
25,990✔
601

602
    if ((int64_t)(*res) != i64) {
25,990✔
603
        SCLogError("Numeric value out of range "
×
604
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
605
                i64, (intmax_t)INT_MAX);
×
606
        return -1;
×
607
    }
×
608

609
    return ret;
25,990✔
610
}
25,990✔
611

612
int StringParseInt16(int16_t *res, int base, size_t len, const char *str)
613
{
×
614
    int64_t i64;
×
615
    int ret;
×
616

617
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
×
618
    if (ret <= 0) {
×
619
        return ret;
×
620
    }
×
621
    if (i64 < INT16_MIN || i64 > INT16_MAX) {
×
622
        return -1;
×
623
    }
×
624

625
    *res = (int16_t)i64;
×
626

627
    if ((int64_t)(*res) != i64) {
×
628
        SCLogError("Numeric value out of range "
×
629
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
630
                i64, (intmax_t)SHRT_MAX);
×
631
        return -1;
×
632
    }
×
633

634
    return ret;
×
635
}
×
636

637
int StringParseInt8(int8_t *res, int base, size_t len, const char *str)
638
{
×
639
    int64_t i64;
×
640
    int ret;
×
641

642
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
×
643
    if (ret <= 0) {
×
644
        return ret;
×
645
    }
×
646
    if (i64 < INT8_MIN || i64 > INT8_MAX) {
×
647
        return -1;
×
648
    }
×
649

650
    *res = (int8_t)i64;
×
651

652
    if ((int64_t)(*res) != i64) {
×
653
        SCLogError("Numeric value out of range "
×
654
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
655
                i64, (intmax_t)CHAR_MAX);
×
656
        return -1;
×
657
    }
×
658

659
    return ret;
×
660
}
×
661

662
int StringParseI64RangeCheck(
663
        int64_t *res, int base, size_t len, const char *str, int64_t min, int64_t max)
664
{
×
665
    int64_t i64;
×
666
    int ret;
×
667

668
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
×
669
    if (ret <= 0) {
×
670
        return ret;
×
671
    }
×
672

673
    *res = i64;
×
674
    if (*res < min || *res > max) {
×
675
        return -1;
×
676
    }
×
677

678
    return ret;
×
679
}
×
680

681
int StringParseI32RangeCheck(
682
        int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
683
{
268,255✔
684
    int64_t i64;
268,255✔
685
    int ret;
268,255✔
686

687
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
268,255✔
688
    if (ret <= 0) {
268,255✔
689
        return ret;
8,613✔
690
    }
8,613✔
691
    if (i64 < INT32_MIN || i64 > INT32_MAX) {
259,642✔
692
        return -1;
450✔
693
    }
450✔
694

695
    *res = (int32_t)i64;
259,192✔
696

697
    if (*res < min || *res > max) {
259,192✔
698
        return -1;
2,014✔
699
    }
2,014✔
700

701
    if ((int64_t)(*res) != i64) {
257,178✔
702
        SCLogError("Numeric value out of range "
×
703
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
704
                i64, (intmax_t)INT_MAX);
×
705
        return -1;
×
706
    }
×
707

708
    return ret;
257,178✔
709
}
257,178✔
710

711
int StringParseI16RangeCheck(
712
        int16_t *res, int base, size_t len, const char *str, int16_t min, int16_t max)
713
{
×
714
    int64_t i64;
×
715
    int ret;
×
716

717
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
×
718
    if (ret <= 0) {
×
719
        return ret;
×
720
    }
×
721
    if (i64 < INT16_MIN || i64 > INT16_MAX) {
×
722
        return -1;
×
723
    }
×
724

725
    *res = (int16_t)i64;
×
726

727
    if (*res < min || *res > max) {
×
728
        return -1;
×
729
    }
×
730

731
    if ((int64_t)(*res) != i64) {
×
732
        SCLogError("Numeric value out of range "
×
733
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
734
                i64, (intmax_t)SHRT_MAX);
×
735
        return -1;
×
736
    }
×
737

738
    return ret;
×
739
}
×
740

741
int StringParseI8RangeCheck(
742
        int8_t *res, int base, size_t len, const char *str, int8_t min, int8_t max)
743
{
×
744
    int64_t i64;
×
745
    int ret;
×
746

747
    ret = ByteExtractStringSigned(&i64, base, len, str, true);
×
748
    if (ret <= 0) {
×
749
        return ret;
×
750
    }
×
751
    if (i64 < INT8_MIN || i64 > INT8_MAX) {
×
752
        return -1;
×
753
    }
×
754

755
    *res = (int8_t)i64;
×
756

757
    if (*res < min || *res > max) {
×
758
        return -1;
×
759
    }
×
760

761
    if ((int64_t)(*res) != i64) {
×
762
        SCLogError("Numeric value out of range "
×
763
                   "(%" PRIi64 " > %" PRIiMAX ")\n",
×
764
                i64, (intmax_t)CHAR_MAX);
×
765
        return -1;
×
766
    }
×
767

768
    return ret;
×
769
}
×
770

771
int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
UNCOV
772
{
×
UNCOV
773
    if (ins < 2)
×
774
        return -1;
×
UNCOV
775
    if (ins % 2 != 0)
×
776
        return -1;
×
UNCOV
777
    if (outs != ins / 2)
×
778
        return -1;
×
779

UNCOV
780
    size_t i, x;
×
UNCOV
781
    for (x = 0, i = 0; i < ins; i += 2, x++) {
×
UNCOV
782
        char buf[3] = { 0, 0, 0 };
×
UNCOV
783
        buf[0] = in[i];
×
UNCOV
784
        buf[1] = in[i + 1];
×
785

UNCOV
786
        long value = strtol(buf, NULL, 16);
×
UNCOV
787
        if (value >= 0 && value <= 255)
×
UNCOV
788
            out[x] = (uint8_t)value;
×
789
        else {
×
790
            SCLogError("hash byte out of range %ld", value);
×
791
            return -1;
×
792
        }
×
UNCOV
793
    }
×
794

UNCOV
795
    return 0;
×
UNCOV
796
}
×
797

798
/* UNITTESTS */
799
#ifdef UNITTESTS
800

801
static int ByteTest01 (void)
802
{
803
    uint16_t val = 0x0102;
804
    uint16_t i16 = 0xbfbf;
805
    uint8_t bytes[2] = { 0x02, 0x01 };
806
    int ret = ByteExtractUint16(&i16, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
807

808
    if ((ret == 2) && (i16 == val)) {
809
        return 1;
810
    }
811

812
    return 0;
813
}
814

815
static int ByteTest02 (void)
816
{
817
    uint16_t val = 0x0102;
818
    uint16_t i16 = 0xbfbf;
819
    uint8_t bytes[2] = { 0x01, 0x02 };
820
    int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
821

822
    if ((ret == 2) && (i16 == val)) {
823
        return 1;
824
    }
825

826
    return 0;
827
}
828

829
static int ByteTest03 (void)
830
{
831
    uint32_t val = 0x01020304;
832
    uint32_t i32 = 0xbfbfbfbf;
833
    uint8_t bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
834
    int ret = ByteExtractUint32(&i32, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
835

836
    if ((ret == 4) && (i32 == val)) {
837
        return 1;
838
    }
839

840
    return 0;
841
}
842

843
static int ByteTest04 (void)
844
{
845
    uint32_t val = 0x01020304;
846
    uint32_t i32 = 0xbfbfbfbf;
847
    uint8_t bytes[4] = { 0x01, 0x02, 0x03, 0x04 };
848
    int ret = ByteExtractUint32(&i32, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
849

850
    if ((ret == 4) && (i32 == val)) {
851
        return 1;
852
    }
853

854
    return 0;
855
}
856

857
static int ByteTest05 (void)
858
{
859
    uint64_t val = 0x0102030405060708ULL;
860
    uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
861
    uint8_t bytes[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
862
    int ret = ByteExtractUint64(&i64, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes);
863

864
    if ((ret == 8) && (i64 == val)) {
865
        return 1;
866
    }
867

868
    return 0;
869
}
870

871
static int ByteTest06 (void)
872
{
873
    uint64_t val = 0x0102030405060708ULL;
874
    uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
875
    uint8_t bytes[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
876
    int ret = ByteExtractUint64(&i64, BYTE_BIG_ENDIAN, sizeof(bytes), bytes);
877

878
    if ((ret == 8) && (i64 == val)) {
879
        return 1;
880
    }
881

882
    return 0;
883
}
884

885
static int ByteTest07 (void)
886
{
887
    const char str[] = "1234567890";
888
    uint64_t val = 1234567890;
889
    uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
890
    int ret = ByteExtractStringUint64(&i64, 10, sizeof(str) - 1, str);
891

892
    if ((ret == 10) && (i64 == val)) {
893
        return 1;
894
    }
895

896
    return 0;
897
}
898

899
static int ByteTest08 (void)
900
{
901
    const char str[] = "1234567890";
902
    uint32_t val = 1234567890;
903
    uint32_t i32 = 0xbfbfbfbf;
904
    int ret = ByteExtractStringUint32(&i32, 10, sizeof(str) - 1, str);
905

906
    if ((ret == 10) && (i32 == val)) {
907
        return 1;
908
    }
909

910
    return 0;
911
}
912

913
static int ByteTest09 (void)
914
{
915
    const char str[] = "12345";
916
    uint16_t val = 12345;
917
    uint16_t i16 = 0xbfbf;
918
    int ret = ByteExtractStringUint16(&i16, 10, sizeof(str) - 1, str);
919

920
    if ((ret == 5) && (i16 == val)) {
921
        return 1;
922
    }
923

924
    return 0;
925
}
926

927
static int ByteTest10 (void)
928
{
929
    const char str[] = "123";
930
    uint8_t val = 123;
931
    uint8_t i8 = 0xbf;
932
    int ret = ByteExtractStringUint8(&i8, 10, sizeof(str) - 1, str);
933

934
    if ((ret == 3) && (i8 == val)) {
935
        return 1;
936
    }
937

938
    return 0;
939
}
940

941
static int ByteTest11 (void)
942
{
943
    const char str[] = "-1234567890";
944
    int64_t val = -1234567890;
945
    int64_t i64 = 0xbfbfbfbfbfbfbfbfULL;
946
    int ret = ByteExtractStringInt64(&i64, 10, sizeof(str) - 1, str);
947

948
    if ((ret == 11) && (i64 == val)) {
949
        return 1;
950
    }
951

952
    return 0;
953
}
954

955
static int ByteTest12 (void)
956
{
957
    const char str[] = "-1234567890";
958
    int32_t val = -1234567890;
959
    int32_t i32 = 0xbfbfbfbf;
960
    int ret = ByteExtractStringInt32(&i32, 10, sizeof(str) - 1, str);
961

962
    if ((ret == 11) && (i32 == val)) {
963
        return 1;
964
    }
965

966
    return 0;
967
}
968

969
static int ByteTest13 (void)
970
{
971
    const char str[] = "-12345";
972
    int16_t val = -12345;
973
    int16_t i16 = 0xbfbf;
974
    int ret = ByteExtractStringInt16(&i16, 10, sizeof(str) - 1, str);
975

976
    if ((ret == 6) && (i16 == val)) {
977
        return 1;
978
    }
979

980
    return 0;
981
}
982

983
static int ByteTest14 (void)
984
{
985
    const char str[] = "-123";
986
    int8_t val = -123;
987
    int8_t i8 = 0xbf;
988
    int ret = ByteExtractStringInt8(&i8, 10, sizeof(str) - 1, str);
989

990
    if ((ret == 4) && (i8 == val)) {
991
        return 1;
992
    }
993

994
    return 0;
995
}
996

997
/** \test max u32 value */
998
static int ByteTest15 (void)
999
{
1000
    const char str[] = "4294967295";
1001
    uint32_t val = 4294967295UL;
1002
    uint32_t u32 = 0xffffffff;
1003

1004
    int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1005
    if ((ret == 10) && (u32 == val)) {
1006
        return 1;
1007
    }
1008

1009
    return 0;
1010
}
1011

1012
/** \test max u32 value + 1 */
1013
static int ByteTest16 (void)
1014
{
1015
    const char str[] = "4294967296";
1016
    uint32_t u32 = 0;
1017

1018
    int ret = ByteExtractStringUint32(&u32, 10, sizeof(str) - 1, str);
1019
    if (ret != 0) {
1020
        return 1;
1021
    }
1022

1023
    return 0;
1024
}
1025

1026
void ByteRegisterTests(void)
1027
{
1028
    UtRegisterTest("ByteTest01", ByteTest01);
1029
    UtRegisterTest("ByteTest02", ByteTest02);
1030
    UtRegisterTest("ByteTest03", ByteTest03);
1031
    UtRegisterTest("ByteTest04", ByteTest04);
1032
    UtRegisterTest("ByteTest05", ByteTest05);
1033
    UtRegisterTest("ByteTest06", ByteTest06);
1034
    UtRegisterTest("ByteTest07", ByteTest07);
1035
    UtRegisterTest("ByteTest08", ByteTest08);
1036
    UtRegisterTest("ByteTest09", ByteTest09);
1037
    UtRegisterTest("ByteTest10", ByteTest10);
1038
    UtRegisterTest("ByteTest11", ByteTest11);
1039
    UtRegisterTest("ByteTest12", ByteTest12);
1040
    UtRegisterTest("ByteTest13", ByteTest13);
1041
    UtRegisterTest("ByteTest14", ByteTest14);
1042
    UtRegisterTest("ByteTest15", ByteTest15);
1043
    UtRegisterTest("ByteTest16", ByteTest16);
1044
}
1045
#endif /* UNITTESTS */
1046

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc