diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2024-01-04 13:16:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-04 13:16:39 +0100 |
commit | f23e9dc7bb7ffc4fe0b5c1151ecefa29a0ce5b79 (patch) | |
tree | f935e033f08dad050b163ab41a827da8feb55125 | |
parent | 7f9973bd0ce2366c09c614d2fdb2883f27ba1106 (diff) |
Add an implementation of the BSD function `strtonum` (#2238)
The main difference with the original function is that we allow to
specify the base.
Credit for the original idea and the first implementation to @0xA50C1A1
-rw-r--r-- | example/ndpiReader.c | 24 | ||||
-rw-r--r-- | src/include/ndpi_api.h | 1 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 37 |
3 files changed, 62 insertions, 0 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index ce697026d..3fba97bbf 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -5377,6 +5377,29 @@ void compressedBitmapUnitTest() { /* *********************************************** */ +void strtonumUnitTest() { + const char *errstrp; + + assert(ndpi_strtonum("0", -10, +10, &errstrp, 10) == 0); + assert(errstrp == NULL); + assert(ndpi_strtonum("0", +10, -10, &errstrp, 10) == 0); + assert(errstrp != NULL); + assert(ndpi_strtonum(" -11 ", -10, +10, &errstrp, 10) == 0); + assert(errstrp != NULL); + assert(ndpi_strtonum(" -11 ", -100, +100, &errstrp, 10) == -11); + assert(errstrp == NULL); + assert(ndpi_strtonum("123abc", LLONG_MIN, LLONG_MAX, &errstrp, 10) == 123); + assert(errstrp == NULL); + assert(ndpi_strtonum("123abc", LLONG_MIN, LLONG_MAX, &errstrp, 16) == 0x123abc); + assert(errstrp == NULL); + assert(ndpi_strtonum(" 0x123abc", LLONG_MIN, LLONG_MAX, &errstrp, 16) == 0x123abc); + assert(errstrp == NULL); + assert(ndpi_strtonum("ghi", -10, +10, &errstrp, 10) == 0); + assert(errstrp != NULL); +} + +/* *********************************************** */ + void filterUnitTest() { ndpi_filter* f = ndpi_filter_alloc(); u_int32_t v, i; @@ -5628,6 +5651,7 @@ int main(int argc, char **argv) { ndpi_self_check_host_match(stderr); analysisUnitTest(); compressedBitmapUnitTest(); + strtonumUnitTest(); #endif } diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 7238b04b3..b20305e33 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -2209,6 +2209,7 @@ extern "C" { /* ******************************* */ + int64_t ndpi_strtonum(const char *numstr, int64_t minval, int64_t maxval, const char **errstrp, int base); int ndpi_vsnprintf(char * str, size_t size, char const * format, va_list va_args); int ndpi_snprintf(char * str, size_t size, char const * format, ...); struct tm *ndpi_gmtime_r(const time_t *timep, diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index da5727915..dd5067906 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -3065,3 +3065,40 @@ int tpkt_verify_hdr(const struct ndpi_packet_struct * const packet) (packet->payload[0] == 3) && (packet->payload[1] == 0) && (get_u_int16_t(packet->payload,2) == htons(packet->payload_packet_len))); } + +/* ******************************************* */ + +int64_t ndpi_strtonum(const char *numstr, int64_t minval, int64_t maxval, const char **errstrp, int base) +{ + int64_t val = 0; + char* endptr; + + if (minval > maxval) { + *errstrp = "minval > maxval"; + return 0; + } + + errno = 0; /* To distinguish success/failure after call */ + val = (int64_t)strtoll(numstr, &endptr, base); + + if((val == LLONG_MIN && errno == ERANGE) || (val < minval)) { + *errstrp = "value too small"; + return 0; + } + if((val == LLONG_MAX && errno == ERANGE) || (val > maxval )) { + *errstrp = "value too large"; + return 0; + } + if(errno != 0 && val == 0) { + *errstrp = "generic error"; + return 0; + } + if(endptr == numstr) { + *errstrp = "No digits were found"; + return 0; + } + /* Like the original strtonum, we allow further characters after the number */ + + *errstrp = NULL; + return val; +} |