Coverage Report

Created: 2026-05-16 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/util-misc.c
Line
Count
Source
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
31
80
#define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2,3})?\\s*$"
32
static pcre2_code *parse_regex = NULL;
33
static pcre2_match_data *parse_regex_match = NULL;
34
35
void ParseSizeInit(void)
36
80
{
37
80
    int en;
38
80
    PCRE2_SIZE eo;
39
80
    int opts = 0;
40
41
80
    parse_regex =
42
80
            pcre2_compile((PCRE2_SPTR8)PARSE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
43
80
    if (parse_regex == NULL) {
44
0
        PCRE2_UCHAR errbuffer[256];
45
0
        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
46
0
        SCLogError("pcre2 compile of \"%s\" failed at "
47
0
                   "offset %d: %s",
48
0
                PARSE_REGEX, (int)eo, errbuffer);
49
0
        exit(EXIT_FAILURE);
50
0
    }
51
80
    parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
52
80
}
53
54
void ParseSizeDeinit(void)
55
0
{
56
0
    pcre2_code_free(parse_regex);
57
0
    pcre2_match_data_free(parse_regex_match);
58
0
}
59
60
/* size string parsing API */
61
62
static int ParseSizeString(const char *size, double *res)
63
35.6k
{
64
35.6k
    int pcre2_match_ret;
65
35.6k
    int r;
66
35.6k
    int retval = 0;
67
35.6k
    char str[128];
68
35.6k
    char str2[128];
69
70
35.6k
    *res = 0;
71
72
35.6k
    if (size == NULL) {
73
0
        SCLogError("invalid size argument - NULL. Valid size "
74
0
                   "argument should be in the format - \n"
75
0
                   "xxx <- indicates it is just bytes\n"
76
0
                   "xxxkb or xxxKb or xxxKB or xxxkB <- indicates kilobytes\n"
77
0
                   "xxxmb or xxxMb or xxxMB or xxxmB <- indicates megabytes\n"
78
0
                   "xxxgb or xxxGb or xxxGB or xxxgB <- indicates gigabytes.\n");
79
0
        retval = -2;
80
0
        goto end;
81
0
    }
82
83
35.6k
    pcre2_match_ret = pcre2_match(
84
35.6k
            parse_regex, (PCRE2_SPTR8)size, strlen(size), 0, 0, parse_regex_match, NULL);
85
86
35.6k
    if (!(pcre2_match_ret == 2 || pcre2_match_ret == 3)) {
87
10.0k
        SCLogError("invalid size argument - %s. Valid size "
88
10.0k
                   "argument should be in the format - \n"
89
10.0k
                   "xxx <- indicates it is just bytes\n"
90
10.0k
                   "xxxkb or xxxKb or xxxKB or xxxkB <- indicates kilobytes\n"
91
10.0k
                   "xxxmb or xxxMb or xxxMB or xxxmB <- indicates megabytes\n"
92
10.0k
                   "xxxgb or xxxGb or xxxGB or xxxgB <- indicates gigabytes.\n",
93
10.0k
                size);
94
10.0k
        retval = -2;
95
10.0k
        goto end;
96
10.0k
    }
97
98
25.5k
    size_t copylen = sizeof(str);
99
25.5k
    r = pcre2_substring_copy_bynumber(parse_regex_match, 1, (PCRE2_UCHAR8 *)str, &copylen);
100
25.5k
    if (r < 0) {
101
359
        SCLogError("pcre2_substring_copy_bynumber failed");
102
359
        retval = -2;
103
359
        goto end;
104
359
    }
105
106
25.2k
    char *endptr, *str_ptr = str;
107
25.2k
    errno = 0;
108
25.2k
    *res = strtod(str_ptr, &endptr);
109
25.2k
    if (errno == ERANGE) {
110
370
        SCLogError("Numeric value out of range");
111
370
        retval = -1;
112
370
        goto end;
113
24.8k
    } else if (endptr == str_ptr) {
114
0
        SCLogError("Invalid numeric value");
115
0
        retval = -1;
116
0
        goto end;
117
0
    }
118
119
24.8k
    if (pcre2_match_ret == 3) {
120
6.22k
        copylen = sizeof(str2);
121
6.22k
        r = pcre2_substring_copy_bynumber(parse_regex_match, 2, (PCRE2_UCHAR8 *)str2, &copylen);
122
123
6.22k
        if (r < 0) {
124
0
            SCLogError("pcre2_substring_copy_bynumber failed");
125
0
            retval = -2;
126
0
            goto end;
127
0
        }
128
129
6.22k
        if (strcasecmp(str2, "kb") == 0 || strcmp(str2, "KiB") == 0) {
130
1.47k
            *res *= 1024;
131
4.75k
        } else if (strcasecmp(str2, "mb") == 0 || strcmp(str2, "MiB") == 0) {
132
1.64k
            *res *= 1024 * 1024;
133
3.10k
        } else if (strcasecmp(str2, "gb") == 0 || strcmp(str2, "GiB") == 0) {
134
942
            *res *= 1024 * 1024 * 1024;
135
2.16k
        } else {
136
            /* Bad unit. */
137
2.16k
            retval = -1;
138
2.16k
            goto end;
139
2.16k
        }
140
6.22k
    }
141
142
22.6k
    retval = 0;
143
35.6k
end:
144
35.6k
    return retval;
145
22.6k
}
146
147
int ParseSizeStringU8(const char *size, uint8_t *res)
148
0
{
149
0
    double temp_res = 0;
150
151
0
    *res = 0;
152
0
    int r = ParseSizeString(size, &temp_res);
153
0
    if (r < 0)
154
0
        return r;
155
156
0
    if (temp_res > UINT8_MAX)
157
0
        return -1;
158
159
0
    *res = temp_res;
160
161
0
    return 0;
162
0
}
163
164
int ParseSizeStringU16(const char *size, uint16_t *res)
165
0
{
166
0
    double temp_res = 0;
167
168
0
    *res = 0;
169
0
    int r = ParseSizeString(size, &temp_res);
170
0
    if (r < 0)
171
0
        return r;
172
173
0
    if (temp_res > UINT16_MAX)
174
0
        return -1;
175
176
0
    *res = temp_res;
177
178
0
    return 0;
179
0
}
180
181
int ParseSizeStringU32(const char *size, uint32_t *res)
182
24.1k
{
183
24.1k
    double temp_res = 0;
184
185
24.1k
    *res = 0;
186
24.1k
    int r = ParseSizeString(size, &temp_res);
187
24.1k
    if (r < 0)
188
6.02k
        return r;
189
190
18.1k
    if (temp_res > UINT32_MAX)
191
750
        return -1;
192
193
17.4k
    *res = temp_res;
194
195
17.4k
    return 0;
196
18.1k
}
197
198
int ParseSizeStringU64(const char *size, uint64_t *res)
199
11.4k
{
200
11.4k
    double temp_res = 0;
201
202
11.4k
    *res = 0;
203
11.4k
    int r = ParseSizeString(size, &temp_res);
204
11.4k
    if (r < 0)
205
6.89k
        return r;
206
207
4.53k
    if (temp_res > (double) UINT64_MAX)
208
425
        return -1;
209
210
4.10k
    *res = temp_res;
211
212
4.10k
    return 0;
213
4.53k
}
214
215
void ShortenString(const char *input,
216
    char *output, size_t output_size, char c)
217
203k
{
218
203k
    const size_t str_len = strlen(input);
219
203k
    size_t half = (output_size - 1) / 2;
220
221
    /* If the output size is an even number */
222
203k
    if (half * 2 == (output_size - 1)) {
223
219
        half = half - 1;
224
219
    }
225
226
203k
    size_t spaces = (output_size - 1) - (half * 2);
227
228
    /* Add the first half to the new string */
229
203k
    snprintf(output, half+1, "%s", input);
230
231
    /* Add the amount of spaces wanted */
232
203k
    size_t length = half;
233
407k
    for (size_t i = half; i < half + spaces; i++) {
234
203k
        char s[2] = "";
235
203k
        snprintf(s, sizeof(s), "%c", c);
236
203k
        length = strlcat(output, s, output_size);
237
203k
    }
238
239
203k
    snprintf(output + length, half + 1, "%s", input + (str_len - half));
240
203k
}
241
242
/*********************************Unittests********************************/
243
244
#ifdef UNITTESTS
245
246
static int UtilMiscParseSizeStringTest01(void)
247
{
248
    const char *str;
249
    double result;
250
251
    /* no space */
252
253
    str = "10";
254
    result = 0;
255
    FAIL_IF(ParseSizeString(str, &result) != 0);
256
    FAIL_IF(result != 10);
257
258
    str = "10kb";
259
    result = 0;
260
    FAIL_IF(ParseSizeString(str, &result) != 0);
261
    FAIL_IF(result != 10 * 1024);
262
263
    str = "10Kb";
264
    result = 0;
265
    FAIL_IF(ParseSizeString(str, &result) != 0);
266
    FAIL_IF(result != 10 * 1024);
267
268
    str = "10KB";
269
    result = 0;
270
    FAIL_IF(ParseSizeString(str, &result) != 0);
271
    FAIL_IF(result != 10 * 1024);
272
273
    str = "10mb";
274
    result = 0;
275
    FAIL_IF(ParseSizeString(str, &result) != 0);
276
    FAIL_IF(result != 10 * 1024 * 1024);
277
278
    str = "10gb";
279
    result = 0;
280
    FAIL_IF(ParseSizeString(str, &result) != 0);
281
    FAIL_IF(result != 10737418240UL);
282
283
    /* space start */
284
285
    str = " 10";
286
    result = 0;
287
    FAIL_IF(ParseSizeString(str, &result) != 0);
288
    FAIL_IF(result != 10);
289
290
    str = " 10kb";
291
    result = 0;
292
    FAIL_IF(ParseSizeString(str, &result) != 0);
293
    FAIL_IF(result != 10 * 1024);
294
295
    str = " 10Kb";
296
    result = 0;
297
    FAIL_IF(ParseSizeString(str, &result) != 0);
298
    FAIL_IF(result != 10 * 1024);
299
300
    str = " 10KB";
301
    result = 0;
302
    FAIL_IF(ParseSizeString(str, &result) != 0);
303
    FAIL_IF(result != 10 * 1024);
304
305
    str = " 10mb";
306
    result = 0;
307
    FAIL_IF(ParseSizeString(str, &result) != 0);
308
    FAIL_IF(result != 10 * 1024 * 1024);
309
310
    str = " 10gb";
311
    result = 0;
312
    FAIL_IF(ParseSizeString(str, &result) != 0);
313
    FAIL_IF(result != 10737418240);
314
315
    /* space end */
316
317
    str = "10 ";
318
    result = 0;
319
    FAIL_IF(ParseSizeString(str, &result) != 0);
320
    FAIL_IF(result != 10);
321
322
    str = "10kb ";
323
    result = 0;
324
    FAIL_IF(ParseSizeString(str, &result) != 0);
325
    FAIL_IF(result != 10 * 1024);
326
327
    str = "10Kb ";
328
    result = 0;
329
    FAIL_IF(ParseSizeString(str, &result) != 0);
330
    FAIL_IF(result != 10 * 1024);
331
332
    str = "10KB ";
333
    result = 0;
334
    FAIL_IF(ParseSizeString(str, &result) != 0);
335
    FAIL_IF(result != 10 * 1024);
336
337
    str = "10mb ";
338
    result = 0;
339
    FAIL_IF(ParseSizeString(str, &result) != 0);
340
    FAIL_IF(result != 10 * 1024 * 1024);
341
342
    str = "10gb ";
343
    result = 0;
344
    FAIL_IF(ParseSizeString(str, &result) != 0);
345
    FAIL_IF(result != 10737418240);
346
347
    /* space start - space end */
348
349
    str = " 10 ";
350
    result = 0;
351
    FAIL_IF(ParseSizeString(str, &result) != 0);
352
    FAIL_IF(result != 10);
353
354
    str = " 10kb ";
355
    result = 0;
356
    FAIL_IF(ParseSizeString(str, &result) != 0);
357
    FAIL_IF(result != 10 * 1024);
358
359
    str = " 10Kb ";
360
    result = 0;
361
    FAIL_IF(ParseSizeString(str, &result) != 0);
362
    FAIL_IF(result != 10 * 1024);
363
364
    str = " 10KB ";
365
    result = 0;
366
    FAIL_IF(ParseSizeString(str, &result) != 0);
367
    FAIL_IF(result != 10 * 1024);
368
369
    str = " 10mb ";
370
    result = 0;
371
    FAIL_IF(ParseSizeString(str, &result) != 0);
372
    FAIL_IF(result != 10 * 1024 * 1024);
373
374
    str = " 10gb ";
375
    result = 0;
376
    FAIL_IF(ParseSizeString(str, &result) != 0);
377
    FAIL_IF(result != 10737418240);
378
379
    /* space between number and scale */
380
381
    /* no space */
382
383
    str = "10";
384
    result = 0;
385
    FAIL_IF(ParseSizeString(str, &result) != 0);
386
    FAIL_IF(result != 10);
387
388
    str = "10 kb";
389
    result = 0;
390
    FAIL_IF(ParseSizeString(str, &result) != 0);
391
    FAIL_IF(result != 10 * 1024);
392
393
    str = "10 Kb";
394
    result = 0;
395
    FAIL_IF(ParseSizeString(str, &result) != 0);
396
    FAIL_IF(result != 10 * 1024);
397
398
    str = "10 KB";
399
    result = 0;
400
    FAIL_IF(ParseSizeString(str, &result) != 0);
401
    FAIL_IF(result != 10 * 1024);
402
403
    str = "10 mb";
404
    result = 0;
405
    FAIL_IF(ParseSizeString(str, &result) != 0);
406
    FAIL_IF(result != 10 * 1024 * 1024);
407
408
    str = "10 gb";
409
    result = 0;
410
    FAIL_IF(ParseSizeString(str, &result) != 0);
411
    FAIL_IF(result != 10737418240);
412
413
    /* space start */
414
415
    str = " 10";
416
    result = 0;
417
    FAIL_IF(ParseSizeString(str, &result) != 0);
418
    FAIL_IF(result != 10);
419
420
    str = " 10 kb";
421
    result = 0;
422
    FAIL_IF(ParseSizeString(str, &result) != 0);
423
    FAIL_IF(result != 10 * 1024);
424
425
    str = " 10 Kb";
426
    result = 0;
427
    FAIL_IF(ParseSizeString(str, &result) != 0);
428
    FAIL_IF(result != 10 * 1024);
429
430
    str = " 10 KB";
431
    result = 0;
432
    FAIL_IF(ParseSizeString(str, &result) != 0);
433
    FAIL_IF(result != 10 * 1024);
434
435
    str = " 10 mb";
436
    result = 0;
437
    FAIL_IF(ParseSizeString(str, &result) != 0);
438
    FAIL_IF(result != 10 * 1024 * 1024);
439
440
    str = " 10 gb";
441
    result = 0;
442
    FAIL_IF(ParseSizeString(str, &result) != 0);
443
    FAIL_IF(result != 10737418240);
444
445
    /* space end */
446
447
    str = "10 ";
448
    result = 0;
449
    FAIL_IF(ParseSizeString(str, &result) != 0);
450
    FAIL_IF(result != 10);
451
452
    str = "10 kb ";
453
    result = 0;
454
    FAIL_IF(ParseSizeString(str, &result) != 0);
455
    FAIL_IF(result != 10 * 1024);
456
457
    str = "10 Kb ";
458
    result = 0;
459
    FAIL_IF(ParseSizeString(str, &result) != 0);
460
    FAIL_IF(result != 10 * 1024);
461
462
    str = "10 KB ";
463
    result = 0;
464
    FAIL_IF(ParseSizeString(str, &result) != 0);
465
    FAIL_IF(result != 10 * 1024);
466
467
    str = "10 mb ";
468
    result = 0;
469
    FAIL_IF(ParseSizeString(str, &result) != 0);
470
    FAIL_IF(result != 10 * 1024 * 1024);
471
472
    str = "10 gb ";
473
    result = 0;
474
    FAIL_IF(ParseSizeString(str, &result) != 0);
475
    FAIL_IF(result != 10737418240);
476
477
    /* space start - space end */
478
479
    str = " 10 ";
480
    result = 0;
481
    FAIL_IF(ParseSizeString(str, &result) != 0);
482
    FAIL_IF(result != 10);
483
484
    str = " 10 kb ";
485
    result = 0;
486
    FAIL_IF(ParseSizeString(str, &result) != 0);
487
    FAIL_IF(result != 10 * 1024);
488
489
    str = " 10 Kb ";
490
    result = 0;
491
    FAIL_IF(ParseSizeString(str, &result) != 0);
492
    FAIL_IF(result != 10 * 1024);
493
494
    str = " 10 KB ";
495
    result = 0;
496
    FAIL_IF(ParseSizeString(str, &result) != 0);
497
    FAIL_IF(result != 10 * 1024);
498
499
    str = " 10 mb ";
500
    result = 0;
501
    FAIL_IF(ParseSizeString(str, &result) != 0);
502
    FAIL_IF(result != 10 * 1024 * 1024);
503
504
    str = " 10 gb ";
505
    result = 0;
506
    FAIL_IF(ParseSizeString(str, &result) != 0);
507
    FAIL_IF(result != 10737418240);
508
509
    /* no space */
510
511
    str = "10.5";
512
    result = 0;
513
    FAIL_IF(ParseSizeString(str, &result) != 0);
514
    FAIL_IF(result != 10.5);
515
516
    str = "10.5kb";
517
    result = 0;
518
    FAIL_IF(ParseSizeString(str, &result) != 0);
519
    FAIL_IF(result != 10.5 * 1024);
520
521
    str = "10.5Kb";
522
    result = 0;
523
    FAIL_IF(ParseSizeString(str, &result) != 0);
524
    FAIL_IF(result != 10.5 * 1024);
525
526
    str = "10.5KB";
527
    result = 0;
528
    FAIL_IF(ParseSizeString(str, &result) != 0);
529
    FAIL_IF(result != 10.5 * 1024);
530
531
    str = "10.5mb";
532
    result = 0;
533
    FAIL_IF(ParseSizeString(str, &result) != 0);
534
    FAIL_IF(result != 10.5 * 1024 * 1024);
535
536
    str = "10.5gb";
537
    result = 0;
538
    FAIL_IF(ParseSizeString(str, &result) != 0);
539
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
540
541
    /* space start */
542
543
    str = " 10.5";
544
    result = 0;
545
    FAIL_IF(ParseSizeString(str, &result) != 0);
546
    FAIL_IF(result != 10.5);
547
548
    str = " 10.5kb";
549
    result = 0;
550
    FAIL_IF(ParseSizeString(str, &result) != 0);
551
    FAIL_IF(result != 10.5 * 1024);
552
553
    str = " 10.5Kb";
554
    result = 0;
555
    FAIL_IF(ParseSizeString(str, &result) != 0);
556
    FAIL_IF(result != 10.5 * 1024);
557
558
    str = " 10.5KB";
559
    result = 0;
560
    FAIL_IF(ParseSizeString(str, &result) != 0);
561
    FAIL_IF(result != 10.5 * 1024);
562
563
    str = " 10.5mb";
564
    result = 0;
565
    FAIL_IF(ParseSizeString(str, &result) != 0);
566
    FAIL_IF(result != 10.5 * 1024 * 1024);
567
568
    str = " 10.5gb";
569
    result = 0;
570
    FAIL_IF(ParseSizeString(str, &result) != 0);
571
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
572
573
    /* space end */
574
575
    str = "10.5 ";
576
    result = 0;
577
    FAIL_IF(ParseSizeString(str, &result) != 0);
578
    FAIL_IF(result != 10.5);
579
580
    str = "10.5kb ";
581
    result = 0;
582
    FAIL_IF(ParseSizeString(str, &result) != 0);
583
    FAIL_IF(result != 10.5 * 1024);
584
585
    str = "10.5Kb ";
586
    result = 0;
587
    FAIL_IF(ParseSizeString(str, &result) != 0);
588
    FAIL_IF(result != 10.5 * 1024);
589
590
    str = "10.5KB ";
591
    result = 0;
592
    FAIL_IF(ParseSizeString(str, &result) != 0);
593
    FAIL_IF(result != 10.5 * 1024);
594
595
    str = "10.5mb ";
596
    result = 0;
597
    FAIL_IF(ParseSizeString(str, &result) != 0);
598
    FAIL_IF(result != 10.5 * 1024 * 1024);
599
600
    str = "10.5gb ";
601
    result = 0;
602
    FAIL_IF(ParseSizeString(str, &result) != 0);
603
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
604
605
    /* space start - space end */
606
607
    str = " 10.5 ";
608
    result = 0;
609
    FAIL_IF(ParseSizeString(str, &result) != 0);
610
    FAIL_IF(result != 10.5);
611
612
    str = " 10.5kb ";
613
    result = 0;
614
    FAIL_IF(ParseSizeString(str, &result) != 0);
615
    FAIL_IF(result != 10.5 * 1024);
616
617
    str = " 10.5Kb ";
618
    result = 0;
619
    FAIL_IF(ParseSizeString(str, &result) != 0);
620
    FAIL_IF(result != 10.5 * 1024);
621
622
    str = " 10.5KB ";
623
    result = 0;
624
    FAIL_IF(ParseSizeString(str, &result) != 0);
625
    FAIL_IF(result != 10.5 * 1024);
626
627
    str = " 10.5mb ";
628
    result = 0;
629
    FAIL_IF(ParseSizeString(str, &result) != 0);
630
    FAIL_IF(result != 10.5 * 1024 * 1024);
631
632
    str = " 10.5gb ";
633
    result = 0;
634
    FAIL_IF(ParseSizeString(str, &result) != 0);
635
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
636
637
    /* space between number and scale */
638
639
    /* no space */
640
641
    str = "10.5";
642
    result = 0;
643
    FAIL_IF(ParseSizeString(str, &result) != 0);
644
    FAIL_IF(result != 10.5);
645
646
    str = "10.5 kb";
647
    result = 0;
648
    FAIL_IF(ParseSizeString(str, &result) != 0);
649
    FAIL_IF(result != 10.5 * 1024);
650
651
    str = "10.5 Kb";
652
    result = 0;
653
    FAIL_IF(ParseSizeString(str, &result) != 0);
654
    FAIL_IF(result != 10.5 * 1024);
655
656
    str = "10.5 KB";
657
    result = 0;
658
    FAIL_IF(ParseSizeString(str, &result) != 0);
659
    FAIL_IF(result != 10.5 * 1024);
660
661
    str = "10.5 mb";
662
    result = 0;
663
    FAIL_IF(ParseSizeString(str, &result) != 0);
664
    FAIL_IF(result != 10.5 * 1024 * 1024);
665
666
    str = "10.5 gb";
667
    result = 0;
668
    FAIL_IF(ParseSizeString(str, &result) != 0);
669
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
670
671
    /* space start */
672
673
    str = " 10.5";
674
    result = 0;
675
    FAIL_IF(ParseSizeString(str, &result) != 0);
676
    FAIL_IF(result != 10.5);
677
678
    str = " 10.5 kb";
679
    result = 0;
680
    FAIL_IF(ParseSizeString(str, &result) != 0);
681
    FAIL_IF(result != 10.5 * 1024);
682
683
    str = " 10.5 Kb";
684
    result = 0;
685
    FAIL_IF(ParseSizeString(str, &result) != 0);
686
    FAIL_IF(result != 10.5 * 1024);
687
688
    str = " 10.5 KB";
689
    result = 0;
690
    FAIL_IF(ParseSizeString(str, &result) != 0);
691
    FAIL_IF(result != 10.5 * 1024);
692
693
    str = " 10.5 mb";
694
    result = 0;
695
    FAIL_IF(ParseSizeString(str, &result) != 0);
696
    FAIL_IF(result != 10.5 * 1024 * 1024);
697
698
    str = " 10.5 gb";
699
    result = 0;
700
    FAIL_IF(ParseSizeString(str, &result) != 0);
701
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
702
703
    /* space end */
704
705
    str = "10.5 ";
706
    result = 0;
707
    FAIL_IF(ParseSizeString(str, &result) != 0);
708
    FAIL_IF(result != 10.5);
709
710
    str = "10.5 kb ";
711
    result = 0;
712
    FAIL_IF(ParseSizeString(str, &result) != 0);
713
    FAIL_IF(result != 10.5 * 1024);
714
715
    str = "10.5 Kb ";
716
    result = 0;
717
    FAIL_IF(ParseSizeString(str, &result) != 0);
718
    FAIL_IF(result != 10.5 * 1024);
719
720
    str = "10.5 KB ";
721
    result = 0;
722
    FAIL_IF(ParseSizeString(str, &result) != 0);
723
    FAIL_IF(result != 10.5 * 1024);
724
725
    str = "10.5 mb ";
726
    result = 0;
727
    FAIL_IF(ParseSizeString(str, &result) != 0);
728
    FAIL_IF(result != 10.5 * 1024 * 1024);
729
730
    str = "10.5 gb ";
731
    result = 0;
732
    FAIL_IF(ParseSizeString(str, &result) != 0);
733
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
734
735
    /* space start - space end */
736
737
    str = " 10.5 ";
738
    result = 0;
739
    FAIL_IF(ParseSizeString(str, &result) != 0);
740
    FAIL_IF(result != 10.5);
741
742
    str = " 10.5 kb ";
743
    result = 0;
744
    FAIL_IF(ParseSizeString(str, &result) != 0);
745
    FAIL_IF(result != 10.5 * 1024);
746
747
    str = " 10.5 Kb ";
748
    result = 0;
749
    FAIL_IF(ParseSizeString(str, &result) != 0);
750
    FAIL_IF(result != 10.5 * 1024);
751
752
    str = " 10.5 KB ";
753
    result = 0;
754
    FAIL_IF(ParseSizeString(str, &result) != 0);
755
    FAIL_IF(result != 10.5 * 1024);
756
757
    str = " 10.5 mb ";
758
    result = 0;
759
    FAIL_IF(ParseSizeString(str, &result) != 0);
760
    FAIL_IF(result != 10.5 * 1024 * 1024);
761
762
    str = " 10.5 gb ";
763
    result = 0;
764
    FAIL_IF(ParseSizeString(str, &result) != 0);
765
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
766
767
    /* Should fail on unknown units. */
768
    FAIL_IF(ParseSizeString("32eb", &result) == 0);
769
770
    PASS;
771
}
772
773
static int UtilMiscParseSizeStringTest02(void)
774
{
775
    const char *str;
776
    double result;
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) == -1);
785
786
    str = "10KiB";
787
    result = 0;
788
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
789
    FAIL_IF(result != 10 * 1024);
790
791
    str = "10mib";
792
    result = 0;
793
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
794
795
    str = "10gib";
796
    result = 0;
797
    FAIL_IF_NOT(ParseSizeString(str, &result) == -1);
798
799
    str = " 10.5 KiB ";
800
    result = 0;
801
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
802
    FAIL_IF(result != 10.5 * 1024);
803
804
    str = " 10.5 MiB ";
805
    result = 0;
806
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
807
    FAIL_IF(result != 10.5 * 1024 * 1024);
808
809
    str = " 10.5 GiB ";
810
    result = 0;
811
    FAIL_IF_NOT(ParseSizeString(str, &result) == 0);
812
    FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
813
814
    PASS;
815
}
816
817
void UtilMiscRegisterTests(void)
818
{
819
    UtRegisterTest("UtilMiscParseSizeStringTest01",
820
                   UtilMiscParseSizeStringTest01);
821
    UtRegisterTest("UtilMiscParseSizeStringTest02", UtilMiscParseSizeStringTest02);
822
}
823
#endif /* UNITTESTS */