• 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

67.12
/src/util-misc.c
1
/* Copyright (C) 2007-2022 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22
 */
23

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

32
#define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2,3})?\\s*$"
7✔
33
static pcre2_code *parse_regex = NULL;
34
static pcre2_match_data *parse_regex_match = NULL;
35

36
void ParseSizeInit(void)
37
{
7✔
38
    int en;
7✔
39
    PCRE2_SIZE eo;
7✔
40
    int opts = 0;
7✔
41

42
    parse_regex =
7✔
43
            pcre2_compile((PCRE2_SPTR8)PARSE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
7✔
44
    if (parse_regex == NULL) {
7✔
45
        PCRE2_UCHAR errbuffer[256];
×
46
        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
×
47
        SCLogError("pcre2 compile of \"%s\" failed at "
×
48
                   "offset %d: %s",
×
49
                PARSE_REGEX, (int)eo, errbuffer);
×
50
        exit(EXIT_FAILURE);
×
51
    }
×
52
    parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
7✔
53
}
7✔
54

55
void ParseSizeDeinit(void)
UNCOV
56
{
×
UNCOV
57
    pcre2_code_free(parse_regex);
×
UNCOV
58
    pcre2_match_data_free(parse_regex_match);
×
UNCOV
59
}
×
60

61
/* size string parsing API */
62

63
static int ParseSizeString(const char *size, double *res)
64
{
22,784✔
65
    int pcre2_match_ret;
22,784✔
66
    int r;
22,784✔
67
    int retval = 0;
22,784✔
68
    char str[128];
22,784✔
69
    char str2[128];
22,784✔
70

71
    *res = 0;
22,784✔
72

73
    if (size == NULL) {
22,784✔
74
        SCLogError("invalid size argument: NULL. Valid input is <number><unit>. Unit can be "
×
75
                   "kb/KiB, mb/MiB or gb/GiB");
×
76
        retval = -2;
×
77
        goto end;
×
78
    }
×
79

80
    pcre2_match_ret = pcre2_match(
22,784✔
81
            parse_regex, (PCRE2_SPTR8)size, strlen(size), 0, 0, parse_regex_match, NULL);
22,784✔
82

83
    if (!(pcre2_match_ret == 2 || pcre2_match_ret == 3)) {
22,784✔
84
        SCLogError("invalid size argument: '%s'. Valid input is <number><unit>. Unit can be "
5,441✔
85
                   "kb/KiB, mb/MiB or gb/GiB",
5,441✔
86
                size);
5,441✔
87
        retval = -2;
5,441✔
88
        goto end;
5,441✔
89
    }
5,441✔
90

91
    size_t copylen = sizeof(str);
17,343✔
92
    r = pcre2_substring_copy_bynumber(parse_regex_match, 1, (PCRE2_UCHAR8 *)str, &copylen);
17,343✔
93
    if (r < 0) {
17,343✔
94
        SCLogError("pcre2_substring_copy_bynumber failed");
330✔
95
        retval = -2;
330✔
96
        goto end;
330✔
97
    }
330✔
98

99
    char *endptr, *str_ptr = str;
17,013✔
100
    errno = 0;
17,013✔
101
    *res = strtod(str_ptr, &endptr);
17,013✔
102
    if (errno == ERANGE) {
17,013✔
103
        SCLogError("Numeric value out of range");
162✔
104
        retval = -1;
162✔
105
        goto end;
162✔
106
    } else if (endptr == str_ptr) {
16,851✔
107
        SCLogError("Invalid numeric value");
×
108
        retval = -1;
×
109
        goto end;
×
110
    }
×
111

112
    if (pcre2_match_ret == 3) {
16,851✔
113
        copylen = sizeof(str2);
3,100✔
114
        r = pcre2_substring_copy_bynumber(parse_regex_match, 2, (PCRE2_UCHAR8 *)str2, &copylen);
3,100✔
115

116
        if (r < 0) {
3,100✔
117
            SCLogError("pcre2_substring_copy_bynumber failed");
×
118
            retval = -2;
×
119
            goto end;
×
120
        }
×
121

122
        if (strcasecmp(str2, "kb") == 0 || strcmp(str2, "KiB") == 0) {
3,100✔
123
            *res *= 1024;
876✔
124
        } else if (strcasecmp(str2, "mb") == 0 || strcmp(str2, "MiB") == 0) {
2,224✔
125
            *res *= 1024 * 1024;
535✔
126
        } else if (strcasecmp(str2, "gb") == 0 || strcmp(str2, "GiB") == 0) {
1,689✔
127
            *res *= 1024 * 1024 * 1024;
500✔
128
        } else {
1,189✔
129
            /* Bad unit. */
130
            retval = -1;
1,189✔
131
            goto end;
1,189✔
132
        }
1,189✔
133
    }
3,100✔
134

135
    retval = 0;
15,662✔
136
end:
22,784✔
137
    return retval;
22,784✔
138
}
15,662✔
139

140
int ParseSizeStringU8(const char *size, uint8_t *res)
141
{
×
142
    double temp_res = 0;
×
143

144
    *res = 0;
×
145
    int r = ParseSizeString(size, &temp_res);
×
146
    if (r < 0)
×
147
        return r;
×
148

149
    if (temp_res > UINT8_MAX)
×
150
        return -1;
×
151

152
    *res = temp_res;
×
153

154
    return 0;
×
155
}
×
156

157
int ParseSizeStringU16(const char *size, uint16_t *res)
UNCOV
158
{
×
UNCOV
159
    double temp_res = 0;
×
160

UNCOV
161
    *res = 0;
×
UNCOV
162
    int r = ParseSizeString(size, &temp_res);
×
UNCOV
163
    if (r < 0)
×
164
        return r;
×
165

UNCOV
166
    if (temp_res > UINT16_MAX)
×
167
        return -1;
×
168

UNCOV
169
    *res = temp_res;
×
170

UNCOV
171
    return 0;
×
UNCOV
172
}
×
173

174
int ParseSizeStringU32(const char *size, uint32_t *res)
175
{
15,270✔
176
    double temp_res = 0;
15,270✔
177

178
    *res = 0;
15,270✔
179
    int r = ParseSizeString(size, &temp_res);
15,270✔
180
    if (r < 0)
15,270✔
181
        return r;
2,562✔
182

183
    if (temp_res > UINT32_MAX)
12,708✔
184
        return -1;
262✔
185

186
    *res = temp_res;
12,446✔
187

188
    return 0;
12,446✔
189
}
12,708✔
190

191
int ParseSizeStringU64(const char *size, uint64_t *res)
192
{
7,514✔
193
    double temp_res = 0;
7,514✔
194

195
    *res = 0;
7,514✔
196
    int r = ParseSizeString(size, &temp_res);
7,514✔
197
    if (r < 0)
7,514✔
198
        return r;
4,560✔
199

200
    if (temp_res > (double) UINT64_MAX)
2,954✔
201
        return -1;
318✔
202

203
    *res = temp_res;
2,636✔
204

205
    return 0;
2,636✔
206
}
2,954✔
207

208
void ShortenString(const char *input,
209
    char *output, size_t output_size, char c)
210
{
448,733✔
211
    if (output_size == 0)
448,733✔
UNCOV
212
        return;
×
213

214
    const size_t str_len = strlen(input);
448,733✔
215
    size_t half = (output_size - 1) / 2;
448,733✔
216

217
    /* If the output size is an even number */
218
    if (half * 2 == (output_size - 1)) {
448,733✔
219
        half = half - 1;
438,275✔
220
    }
438,275✔
221
    DEBUG_VALIDATE_BUG_ON(half > output_size);
448,733✔
222
    if (half == 0 || half > output_size)
448,733✔
UNCOV
223
        return;
×
224

225
    /* Add the first half to the new string */
226
    snprintf(output, half+1, "%s", input);
448,733✔
227

228
    const size_t second_half_len = (output_size - 1) - half - 1;
448,733✔
229

230
    /* Add space and the separator character */
231
    const char *second_half_start = input + (str_len - second_half_len);
448,733✔
232

233
    size_t remaining_size = output_size - half;
448,733✔
234

235
    snprintf(output + half, remaining_size, "%c%s", c, second_half_start);
448,733✔
236
}
448,733✔
237

238
/*********************************Unittests********************************/
239

240
#ifdef UNITTESTS
241

242
static int UtilMiscParseSizeStringTest01(void)
243
{
244
    const char *str;
245
    double result;
246

247
    /* no space */
248

249
    str = "10";
250
    result = 0;
251
    FAIL_IF(ParseSizeString(str, &result) != 0);
252
    FAIL_IF(result != 10);
253

254
    str = "10kb";
255
    result = 0;
256
    FAIL_IF(ParseSizeString(str, &result) != 0);
257
    FAIL_IF(result != 10 * 1024);
258

259
    str = "10Kb";
260
    result = 0;
261
    FAIL_IF(ParseSizeString(str, &result) != 0);
262
    FAIL_IF(result != 10 * 1024);
263

264
    str = "10KB";
265
    result = 0;
266
    FAIL_IF(ParseSizeString(str, &result) != 0);
267
    FAIL_IF(result != 10 * 1024);
268

269
    str = "10mb";
270
    result = 0;
271
    FAIL_IF(ParseSizeString(str, &result) != 0);
272
    FAIL_IF(result != 10 * 1024 * 1024);
273

274
    str = "10gb";
275
    result = 0;
276
    FAIL_IF(ParseSizeString(str, &result) != 0);
277
    FAIL_IF(result != 10737418240UL);
278

279
    /* space start */
280

281
    str = " 10";
282
    result = 0;
283
    FAIL_IF(ParseSizeString(str, &result) != 0);
284
    FAIL_IF(result != 10);
285

286
    str = " 10kb";
287
    result = 0;
288
    FAIL_IF(ParseSizeString(str, &result) != 0);
289
    FAIL_IF(result != 10 * 1024);
290

291
    str = " 10Kb";
292
    result = 0;
293
    FAIL_IF(ParseSizeString(str, &result) != 0);
294
    FAIL_IF(result != 10 * 1024);
295

296
    str = " 10KB";
297
    result = 0;
298
    FAIL_IF(ParseSizeString(str, &result) != 0);
299
    FAIL_IF(result != 10 * 1024);
300

301
    str = " 10mb";
302
    result = 0;
303
    FAIL_IF(ParseSizeString(str, &result) != 0);
304
    FAIL_IF(result != 10 * 1024 * 1024);
305

306
    str = " 10gb";
307
    result = 0;
308
    FAIL_IF(ParseSizeString(str, &result) != 0);
309
    FAIL_IF(result != 10737418240);
310

311
    /* space end */
312

313
    str = "10 ";
314
    result = 0;
315
    FAIL_IF(ParseSizeString(str, &result) != 0);
316
    FAIL_IF(result != 10);
317

318
    str = "10kb ";
319
    result = 0;
320
    FAIL_IF(ParseSizeString(str, &result) != 0);
321
    FAIL_IF(result != 10 * 1024);
322

323
    str = "10Kb ";
324
    result = 0;
325
    FAIL_IF(ParseSizeString(str, &result) != 0);
326
    FAIL_IF(result != 10 * 1024);
327

328
    str = "10KB ";
329
    result = 0;
330
    FAIL_IF(ParseSizeString(str, &result) != 0);
331
    FAIL_IF(result != 10 * 1024);
332

333
    str = "10mb ";
334
    result = 0;
335
    FAIL_IF(ParseSizeString(str, &result) != 0);
336
    FAIL_IF(result != 10 * 1024 * 1024);
337

338
    str = "10gb ";
339
    result = 0;
340
    FAIL_IF(ParseSizeString(str, &result) != 0);
341
    FAIL_IF(result != 10737418240);
342

343
    /* space start - space end */
344

345
    str = " 10 ";
346
    result = 0;
347
    FAIL_IF(ParseSizeString(str, &result) != 0);
348
    FAIL_IF(result != 10);
349

350
    str = " 10kb ";
351
    result = 0;
352
    FAIL_IF(ParseSizeString(str, &result) != 0);
353
    FAIL_IF(result != 10 * 1024);
354

355
    str = " 10Kb ";
356
    result = 0;
357
    FAIL_IF(ParseSizeString(str, &result) != 0);
358
    FAIL_IF(result != 10 * 1024);
359

360
    str = " 10KB ";
361
    result = 0;
362
    FAIL_IF(ParseSizeString(str, &result) != 0);
363
    FAIL_IF(result != 10 * 1024);
364

365
    str = " 10mb ";
366
    result = 0;
367
    FAIL_IF(ParseSizeString(str, &result) != 0);
368
    FAIL_IF(result != 10 * 1024 * 1024);
369

370
    str = " 10gb ";
371
    result = 0;
372
    FAIL_IF(ParseSizeString(str, &result) != 0);
373
    FAIL_IF(result != 10737418240);
374

375
    /* space between number and scale */
376

377
    /* no space */
378

379
    str = "10";
380
    result = 0;
381
    FAIL_IF(ParseSizeString(str, &result) != 0);
382
    FAIL_IF(result != 10);
383

384
    str = "10 kb";
385
    result = 0;
386
    FAIL_IF(ParseSizeString(str, &result) != 0);
387
    FAIL_IF(result != 10 * 1024);
388

389
    str = "10 Kb";
390
    result = 0;
391
    FAIL_IF(ParseSizeString(str, &result) != 0);
392
    FAIL_IF(result != 10 * 1024);
393

394
    str = "10 KB";
395
    result = 0;
396
    FAIL_IF(ParseSizeString(str, &result) != 0);
397
    FAIL_IF(result != 10 * 1024);
398

399
    str = "10 mb";
400
    result = 0;
401
    FAIL_IF(ParseSizeString(str, &result) != 0);
402
    FAIL_IF(result != 10 * 1024 * 1024);
403

404
    str = "10 gb";
405
    result = 0;
406
    FAIL_IF(ParseSizeString(str, &result) != 0);
407
    FAIL_IF(result != 10737418240);
408

409
    /* space start */
410

411
    str = " 10";
412
    result = 0;
413
    FAIL_IF(ParseSizeString(str, &result) != 0);
414
    FAIL_IF(result != 10);
415

416
    str = " 10 kb";
417
    result = 0;
418
    FAIL_IF(ParseSizeString(str, &result) != 0);
419
    FAIL_IF(result != 10 * 1024);
420

421
    str = " 10 Kb";
422
    result = 0;
423
    FAIL_IF(ParseSizeString(str, &result) != 0);
424
    FAIL_IF(result != 10 * 1024);
425

426
    str = " 10 KB";
427
    result = 0;
428
    FAIL_IF(ParseSizeString(str, &result) != 0);
429
    FAIL_IF(result != 10 * 1024);
430

431
    str = " 10 mb";
432
    result = 0;
433
    FAIL_IF(ParseSizeString(str, &result) != 0);
434
    FAIL_IF(result != 10 * 1024 * 1024);
435

436
    str = " 10 gb";
437
    result = 0;
438
    FAIL_IF(ParseSizeString(str, &result) != 0);
439
    FAIL_IF(result != 10737418240);
440

441
    /* space end */
442

443
    str = "10 ";
444
    result = 0;
445
    FAIL_IF(ParseSizeString(str, &result) != 0);
446
    FAIL_IF(result != 10);
447

448
    str = "10 kb ";
449
    result = 0;
450
    FAIL_IF(ParseSizeString(str, &result) != 0);
451
    FAIL_IF(result != 10 * 1024);
452

453
    str = "10 Kb ";
454
    result = 0;
455
    FAIL_IF(ParseSizeString(str, &result) != 0);
456
    FAIL_IF(result != 10 * 1024);
457

458
    str = "10 KB ";
459
    result = 0;
460
    FAIL_IF(ParseSizeString(str, &result) != 0);
461
    FAIL_IF(result != 10 * 1024);
462

463
    str = "10 mb ";
464
    result = 0;
465
    FAIL_IF(ParseSizeString(str, &result) != 0);
466
    FAIL_IF(result != 10 * 1024 * 1024);
467

468
    str = "10 gb ";
469
    result = 0;
470
    FAIL_IF(ParseSizeString(str, &result) != 0);
471
    FAIL_IF(result != 10737418240);
472

473
    /* space start - space end */
474

475
    str = " 10 ";
476
    result = 0;
477
    FAIL_IF(ParseSizeString(str, &result) != 0);
478
    FAIL_IF(result != 10);
479

480
    str = " 10 kb ";
481
    result = 0;
482
    FAIL_IF(ParseSizeString(str, &result) != 0);
483
    FAIL_IF(result != 10 * 1024);
484

485
    str = " 10 Kb ";
486
    result = 0;
487
    FAIL_IF(ParseSizeString(str, &result) != 0);
488
    FAIL_IF(result != 10 * 1024);
489

490
    str = " 10 KB ";
491
    result = 0;
492
    FAIL_IF(ParseSizeString(str, &result) != 0);
493
    FAIL_IF(result != 10 * 1024);
494

495
    str = " 10 mb ";
496
    result = 0;
497
    FAIL_IF(ParseSizeString(str, &result) != 0);
498
    FAIL_IF(result != 10 * 1024 * 1024);
499

500
    str = " 10 gb ";
501
    result = 0;
502
    FAIL_IF(ParseSizeString(str, &result) != 0);
503
    FAIL_IF(result != 10737418240);
504

505
    /* no space */
506

507
    str = "10.5";
508
    result = 0;
509
    FAIL_IF(ParseSizeString(str, &result) != 0);
510
    FAIL_IF(result != 10.5);
511

512
    str = "10.5kb";
513
    result = 0;
514
    FAIL_IF(ParseSizeString(str, &result) != 0);
515
    FAIL_IF(result != 10.5 * 1024);
516

517
    str = "10.5Kb";
518
    result = 0;
519
    FAIL_IF(ParseSizeString(str, &result) != 0);
520
    FAIL_IF(result != 10.5 * 1024);
521

522
    str = "10.5KB";
523
    result = 0;
524
    FAIL_IF(ParseSizeString(str, &result) != 0);
525
    FAIL_IF(result != 10.5 * 1024);
526

527
    str = "10.5mb";
528
    result = 0;
529
    FAIL_IF(ParseSizeString(str, &result) != 0);
530
    FAIL_IF(result != 10.5 * 1024 * 1024);
531

532
    str = "10.5gb";
533
    result = 0;
534
    FAIL_IF(ParseSizeString(str, &result) != 0);
535
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
536

537
    /* space start */
538

539
    str = " 10.5";
540
    result = 0;
541
    FAIL_IF(ParseSizeString(str, &result) != 0);
542
    FAIL_IF(result != 10.5);
543

544
    str = " 10.5kb";
545
    result = 0;
546
    FAIL_IF(ParseSizeString(str, &result) != 0);
547
    FAIL_IF(result != 10.5 * 1024);
548

549
    str = " 10.5Kb";
550
    result = 0;
551
    FAIL_IF(ParseSizeString(str, &result) != 0);
552
    FAIL_IF(result != 10.5 * 1024);
553

554
    str = " 10.5KB";
555
    result = 0;
556
    FAIL_IF(ParseSizeString(str, &result) != 0);
557
    FAIL_IF(result != 10.5 * 1024);
558

559
    str = " 10.5mb";
560
    result = 0;
561
    FAIL_IF(ParseSizeString(str, &result) != 0);
562
    FAIL_IF(result != 10.5 * 1024 * 1024);
563

564
    str = " 10.5gb";
565
    result = 0;
566
    FAIL_IF(ParseSizeString(str, &result) != 0);
567
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
568

569
    /* space end */
570

571
    str = "10.5 ";
572
    result = 0;
573
    FAIL_IF(ParseSizeString(str, &result) != 0);
574
    FAIL_IF(result != 10.5);
575

576
    str = "10.5kb ";
577
    result = 0;
578
    FAIL_IF(ParseSizeString(str, &result) != 0);
579
    FAIL_IF(result != 10.5 * 1024);
580

581
    str = "10.5Kb ";
582
    result = 0;
583
    FAIL_IF(ParseSizeString(str, &result) != 0);
584
    FAIL_IF(result != 10.5 * 1024);
585

586
    str = "10.5KB ";
587
    result = 0;
588
    FAIL_IF(ParseSizeString(str, &result) != 0);
589
    FAIL_IF(result != 10.5 * 1024);
590

591
    str = "10.5mb ";
592
    result = 0;
593
    FAIL_IF(ParseSizeString(str, &result) != 0);
594
    FAIL_IF(result != 10.5 * 1024 * 1024);
595

596
    str = "10.5gb ";
597
    result = 0;
598
    FAIL_IF(ParseSizeString(str, &result) != 0);
599
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
600

601
    /* space start - space end */
602

603
    str = " 10.5 ";
604
    result = 0;
605
    FAIL_IF(ParseSizeString(str, &result) != 0);
606
    FAIL_IF(result != 10.5);
607

608
    str = " 10.5kb ";
609
    result = 0;
610
    FAIL_IF(ParseSizeString(str, &result) != 0);
611
    FAIL_IF(result != 10.5 * 1024);
612

613
    str = " 10.5Kb ";
614
    result = 0;
615
    FAIL_IF(ParseSizeString(str, &result) != 0);
616
    FAIL_IF(result != 10.5 * 1024);
617

618
    str = " 10.5KB ";
619
    result = 0;
620
    FAIL_IF(ParseSizeString(str, &result) != 0);
621
    FAIL_IF(result != 10.5 * 1024);
622

623
    str = " 10.5mb ";
624
    result = 0;
625
    FAIL_IF(ParseSizeString(str, &result) != 0);
626
    FAIL_IF(result != 10.5 * 1024 * 1024);
627

628
    str = " 10.5gb ";
629
    result = 0;
630
    FAIL_IF(ParseSizeString(str, &result) != 0);
631
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
632

633
    /* space between number and scale */
634

635
    /* no space */
636

637
    str = "10.5";
638
    result = 0;
639
    FAIL_IF(ParseSizeString(str, &result) != 0);
640
    FAIL_IF(result != 10.5);
641

642
    str = "10.5 kb";
643
    result = 0;
644
    FAIL_IF(ParseSizeString(str, &result) != 0);
645
    FAIL_IF(result != 10.5 * 1024);
646

647
    str = "10.5 Kb";
648
    result = 0;
649
    FAIL_IF(ParseSizeString(str, &result) != 0);
650
    FAIL_IF(result != 10.5 * 1024);
651

652
    str = "10.5 KB";
653
    result = 0;
654
    FAIL_IF(ParseSizeString(str, &result) != 0);
655
    FAIL_IF(result != 10.5 * 1024);
656

657
    str = "10.5 mb";
658
    result = 0;
659
    FAIL_IF(ParseSizeString(str, &result) != 0);
660
    FAIL_IF(result != 10.5 * 1024 * 1024);
661

662
    str = "10.5 gb";
663
    result = 0;
664
    FAIL_IF(ParseSizeString(str, &result) != 0);
665
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
666

667
    /* space start */
668

669
    str = " 10.5";
670
    result = 0;
671
    FAIL_IF(ParseSizeString(str, &result) != 0);
672
    FAIL_IF(result != 10.5);
673

674
    str = " 10.5 kb";
675
    result = 0;
676
    FAIL_IF(ParseSizeString(str, &result) != 0);
677
    FAIL_IF(result != 10.5 * 1024);
678

679
    str = " 10.5 Kb";
680
    result = 0;
681
    FAIL_IF(ParseSizeString(str, &result) != 0);
682
    FAIL_IF(result != 10.5 * 1024);
683

684
    str = " 10.5 KB";
685
    result = 0;
686
    FAIL_IF(ParseSizeString(str, &result) != 0);
687
    FAIL_IF(result != 10.5 * 1024);
688

689
    str = " 10.5 mb";
690
    result = 0;
691
    FAIL_IF(ParseSizeString(str, &result) != 0);
692
    FAIL_IF(result != 10.5 * 1024 * 1024);
693

694
    str = " 10.5 gb";
695
    result = 0;
696
    FAIL_IF(ParseSizeString(str, &result) != 0);
697
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
698

699
    /* space end */
700

701
    str = "10.5 ";
702
    result = 0;
703
    FAIL_IF(ParseSizeString(str, &result) != 0);
704
    FAIL_IF(result != 10.5);
705

706
    str = "10.5 kb ";
707
    result = 0;
708
    FAIL_IF(ParseSizeString(str, &result) != 0);
709
    FAIL_IF(result != 10.5 * 1024);
710

711
    str = "10.5 Kb ";
712
    result = 0;
713
    FAIL_IF(ParseSizeString(str, &result) != 0);
714
    FAIL_IF(result != 10.5 * 1024);
715

716
    str = "10.5 KB ";
717
    result = 0;
718
    FAIL_IF(ParseSizeString(str, &result) != 0);
719
    FAIL_IF(result != 10.5 * 1024);
720

721
    str = "10.5 mb ";
722
    result = 0;
723
    FAIL_IF(ParseSizeString(str, &result) != 0);
724
    FAIL_IF(result != 10.5 * 1024 * 1024);
725

726
    str = "10.5 gb ";
727
    result = 0;
728
    FAIL_IF(ParseSizeString(str, &result) != 0);
729
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
730

731
    /* space start - space end */
732

733
    str = " 10.5 ";
734
    result = 0;
735
    FAIL_IF(ParseSizeString(str, &result) != 0);
736
    FAIL_IF(result != 10.5);
737

738
    str = " 10.5 kb ";
739
    result = 0;
740
    FAIL_IF(ParseSizeString(str, &result) != 0);
741
    FAIL_IF(result != 10.5 * 1024);
742

743
    str = " 10.5 Kb ";
744
    result = 0;
745
    FAIL_IF(ParseSizeString(str, &result) != 0);
746
    FAIL_IF(result != 10.5 * 1024);
747

748
    str = " 10.5 KB ";
749
    result = 0;
750
    FAIL_IF(ParseSizeString(str, &result) != 0);
751
    FAIL_IF(result != 10.5 * 1024);
752

753
    str = " 10.5 mb ";
754
    result = 0;
755
    FAIL_IF(ParseSizeString(str, &result) != 0);
756
    FAIL_IF(result != 10.5 * 1024 * 1024);
757

758
    str = " 10.5 gb ";
759
    result = 0;
760
    FAIL_IF(ParseSizeString(str, &result) != 0);
761
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
762

763
    /* Should fail on unknown units. */
764
    FAIL_IF(ParseSizeString("32eb", &result) == 0);
765

766
    PASS;
767
}
768

769
static int UtilMiscParseSizeStringTest02(void)
770
{
771
    const char *str;
772
    double result;
773

774
    str = "10kib";
775
    result = 0;
776
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
777

778
    str = "10Kib";
779
    result = 0;
780
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
781

782
    str = "10KiB";
783
    result = 0;
784
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
785
    FAIL_IF(result != 10 * 1024);
786

787
    str = "10mib";
788
    result = 0;
789
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
790

791
    str = "10gib";
792
    result = 0;
793
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
794

795
    str = " 10.5 KiB ";
796
    result = 0;
797
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
798
    FAIL_IF(result != 10.5 * 1024);
799

800
    str = " 10.5 MiB ";
801
    result = 0;
802
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
803
    FAIL_IF(result != 10.5 * 1024 * 1024);
804

805
    str = " 10.5 GiB ";
806
    result = 0;
807
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
808
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
809

810
    PASS;
811
}
812

813
static int UtilMiscShortenStringTest01(void)
814
{
815
    char buffer[100];
816
    const char *original = "abcdefghijklmnopqrstuvwxyz";
817
    const char sep = '~';
818
    const char *expected = NULL;
819

820
    memset(buffer, 0, sizeof(buffer));
821
    expected = "abc~wxyz";
822
    ShortenString(original, buffer, 9, sep);
823
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
824

825
    memset(buffer, 0, sizeof(buffer));
826
    expected = "abcd~wxyz";
827
    ShortenString(original, buffer, 10, sep);
828
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
829

830
    memset(buffer, 0, sizeof(buffer));
831
    expected = "a~z";
832
    ShortenString(original, buffer, 4, sep);
833
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
834

835
    memset(buffer, 0, sizeof(buffer));
836
    expected = "";
837
    ShortenString(original, buffer, 3, sep);
838
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
839

840
    memset(buffer, 0, sizeof(buffer));
841
    expected = "";
842
    ShortenString(original, buffer, 2, sep);
843
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
844

845
    memset(buffer, 0, sizeof(buffer));
846
    expected = "";
847
    ShortenString(original, buffer, 1, sep);
848
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
849

850
    memset(buffer, 0, sizeof(buffer));
851
    expected = "";
852
    ShortenString(original, buffer, 0, sep);
853
    FAIL_IF_NOT(strcmp(buffer, expected) == 0);
854

855
    PASS;
856
}
857

858
void UtilMiscRegisterTests(void)
859
{
860
    UtRegisterTest("UtilMiscParseSizeStringTest01",
861
                   UtilMiscParseSizeStringTest01);
862
    UtRegisterTest("UtilMiscParseSizeStringTest02", UtilMiscParseSizeStringTest02);
863
    UtRegisterTest("UtilMiscShortenStringTest01", UtilMiscShortenStringTest01);
864
}
865
#endif /* UNITTESTS */
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