31#define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2,3})?\\s*$"
32static pcre2_code *parse_regex = NULL;
33static pcre2_match_data *parse_regex_match = NULL;
42 pcre2_compile((PCRE2_SPTR8)
PARSE_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
43 if (parse_regex == NULL) {
44 PCRE2_UCHAR errbuffer[256];
45 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
46 SCLogError(
"pcre2 compile of \"%s\" failed at "
51 parse_regex_match = pcre2_match_data_create_from_pattern(parse_regex, NULL);
56 pcre2_code_free(parse_regex);
57 pcre2_match_data_free(parse_regex_match);
62static int ParseSizeString(
const char *size,
double *res)
73 SCLogError(
"invalid size argument: NULL. Valid input is <number><unit>. Unit can be "
74 "kb/KiB, mb/MiB or gb/GiB");
79 pcre2_match_ret = pcre2_match(
80 parse_regex, (PCRE2_SPTR8)size, strlen(size), 0, 0, parse_regex_match, NULL);
82 if (!(pcre2_match_ret == 2 || pcre2_match_ret == 3)) {
83 SCLogError(
"invalid size argument: '%s'. Valid input is <number><unit>. Unit can be "
84 "kb/KiB, mb/MiB or gb/GiB",
90 size_t copylen =
sizeof(
str);
91 r = pcre2_substring_copy_bynumber(parse_regex_match, 1, (PCRE2_UCHAR8 *)
str, ©len);
93 SCLogError(
"pcre2_substring_copy_bynumber failed");
98 char *endptr, *str_ptr =
str;
100 *res = strtod(str_ptr, &endptr);
101 if (errno == ERANGE) {
105 }
else if (endptr == str_ptr) {
111 if (pcre2_match_ret == 3) {
112 copylen =
sizeof(str2);
113 r = pcre2_substring_copy_bynumber(parse_regex_match, 2, (PCRE2_UCHAR8 *)str2, ©len);
116 SCLogError(
"pcre2_substring_copy_bynumber failed");
121 if (strcasecmp(str2,
"kb") == 0 || strcmp(str2,
"KiB") == 0) {
123 }
else if (strcasecmp(str2,
"mb") == 0 || strcmp(str2,
"MiB") == 0) {
125 }
else if (strcasecmp(str2,
"gb") == 0 || strcmp(str2,
"GiB") == 0) {
126 *res *= 1024 * 1024 * 1024;
144 int r = ParseSizeString(size, &temp_res);
148 if (temp_res > UINT8_MAX)
161 int r = ParseSizeString(size, &temp_res);
165 if (temp_res > UINT16_MAX)
178 int r = ParseSizeString(size, &temp_res);
182 if (temp_res > UINT32_MAX)
195 int r = ParseSizeString(size, &temp_res);
199 if (temp_res > (
double) UINT64_MAX)
208 char *output,
size_t output_size,
char c)
210 const size_t str_len = strlen(input);
211 size_t half = (output_size - 1) / 2;
214 if (half * 2 == (output_size - 1)) {
218 size_t spaces = (output_size - 1) - (half * 2);
221 snprintf(output, half+1,
"%s", input);
224 size_t length = half;
225 for (
size_t i = half; i < half + spaces; i++) {
227 snprintf(s,
sizeof(s),
"%c", c);
228 length =
strlcat(output, s, output_size);
231 snprintf(output + length, half + 1,
"%s", input + (str_len - half));
238static int UtilMiscParseSizeStringTest01(
void)
268 FAIL_IF(result != 10 * 1024 * 1024);
273 FAIL_IF(result != 10737418240UL);
300 FAIL_IF(result != 10 * 1024 * 1024);
305 FAIL_IF(result != 10737418240);
332 FAIL_IF(result != 10 * 1024 * 1024);
337 FAIL_IF(result != 10737418240);
364 FAIL_IF(result != 10 * 1024 * 1024);
369 FAIL_IF(result != 10737418240);
398 FAIL_IF(result != 10 * 1024 * 1024);
403 FAIL_IF(result != 10737418240);
430 FAIL_IF(result != 10 * 1024 * 1024);
435 FAIL_IF(result != 10737418240);
462 FAIL_IF(result != 10 * 1024 * 1024);
467 FAIL_IF(result != 10737418240);
494 FAIL_IF(result != 10 * 1024 * 1024);
499 FAIL_IF(result != 10737418240);
511 FAIL_IF(result != 10.5 * 1024);
516 FAIL_IF(result != 10.5 * 1024);
521 FAIL_IF(result != 10.5 * 1024);
526 FAIL_IF(result != 10.5 * 1024 * 1024);
531 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
543 FAIL_IF(result != 10.5 * 1024);
548 FAIL_IF(result != 10.5 * 1024);
553 FAIL_IF(result != 10.5 * 1024);
558 FAIL_IF(result != 10.5 * 1024 * 1024);
563 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
575 FAIL_IF(result != 10.5 * 1024);
580 FAIL_IF(result != 10.5 * 1024);
585 FAIL_IF(result != 10.5 * 1024);
590 FAIL_IF(result != 10.5 * 1024 * 1024);
595 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
607 FAIL_IF(result != 10.5 * 1024);
612 FAIL_IF(result != 10.5 * 1024);
617 FAIL_IF(result != 10.5 * 1024);
622 FAIL_IF(result != 10.5 * 1024 * 1024);
627 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
641 FAIL_IF(result != 10.5 * 1024);
646 FAIL_IF(result != 10.5 * 1024);
651 FAIL_IF(result != 10.5 * 1024);
656 FAIL_IF(result != 10.5 * 1024 * 1024);
661 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
673 FAIL_IF(result != 10.5 * 1024);
678 FAIL_IF(result != 10.5 * 1024);
683 FAIL_IF(result != 10.5 * 1024);
688 FAIL_IF(result != 10.5 * 1024 * 1024);
693 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
705 FAIL_IF(result != 10.5 * 1024);
710 FAIL_IF(result != 10.5 * 1024);
715 FAIL_IF(result != 10.5 * 1024);
720 FAIL_IF(result != 10.5 * 1024 * 1024);
725 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
737 FAIL_IF(result != 10.5 * 1024);
742 FAIL_IF(result != 10.5 * 1024);
747 FAIL_IF(result != 10.5 * 1024);
752 FAIL_IF(result != 10.5 * 1024 * 1024);
757 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
760 FAIL_IF(ParseSizeString(
"32eb", &result) == 0);
765static int UtilMiscParseSizeStringTest02(
void)
794 FAIL_IF(result != 10.5 * 1024);
799 FAIL_IF(result != 10.5 * 1024 * 1024);
804 FAIL_IF(result != 10.5 * 1024 * 1024 * 1024);
812 UtilMiscParseSizeStringTest01);
813 UtRegisterTest(
"UtilMiscParseSizeStringTest02", UtilMiscParseSizeStringTest02);
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
size_t strlcat(char *, const char *src, size_t siz)
#define SCLogError(...)
Macro used to log ERROR messages.
int ParseSizeStringU32(const char *size, uint32_t *res)
void UtilMiscRegisterTests(void)
void ParseSizeDeinit(void)
void ShortenString(const char *input, char *output, size_t output_size, char c)
int ParseSizeStringU8(const char *size, uint8_t *res)
int ParseSizeStringU16(const char *size, uint16_t *res)
int ParseSizeStringU64(const char *size, uint64_t *res)