Add a check in rte_str_to_size validating that strtoull() consumed at least one character. If not, set errno to EINVAL and return 0.
Also move rte_str_to_size unit coverage from malloc tests to string_autotest, where string utility tests belong, and add a new test to test for handling invalid numerical input. Signed-off-by: Anatoly Burakov <[email protected]> --- app/test/test_malloc.c | 30 ------------ app/test/test_string_fns.c | 66 ++++++++++++++++++++++++++ lib/eal/common/eal_common_string_fns.c | 4 ++ 3 files changed, 70 insertions(+), 30 deletions(-) diff --git a/app/test/test_malloc.c b/app/test/test_malloc.c index 344a730e28..da868c8091 100644 --- a/app/test/test_malloc.c +++ b/app/test/test_malloc.c @@ -271,35 +271,6 @@ test_reordered_free(void) return ret; } -/* test function inside the malloc lib*/ -static int -test_str_to_size(void) -{ - struct { - const char *str; - uint64_t value; - } test_values[] = - {{ "5G", (uint64_t)5 * 1024 * 1024 *1024 }, - {"0x20g", (uint64_t)0x20 * 1024 * 1024 *1024}, - {"10M", 10 * 1024 * 1024}, - {"050m", 050 * 1024 * 1024}, - {"8K", 8 * 1024}, - {"15k", 15 * 1024}, - {"0200", 0200}, - {"0x103", 0x103}, - {"432", 432}, - {"-1", 0}, /* negative values return 0 */ - {" -2", 0}, - {" -3MB", 0}, - {"18446744073709551616", 0} /* ULLONG_MAX + 1 == out of range*/ - }; - unsigned i; - for (i = 0; i < RTE_DIM(test_values); i++) - if (rte_str_to_size(test_values[i].str) != test_values[i].value) - return -1; - return 0; -} - static int test_multi_alloc_statistics(void) { @@ -1145,7 +1116,6 @@ test_free_sensitive(void) static struct unit_test_suite test_suite = { .suite_name = "Malloc test suite", .unit_test_cases = { - TEST_CASE(test_str_to_size), TEST_CASE(test_zero_aligned_alloc), TEST_CASE(test_malloc_bad_params), TEST_CASE(test_realloc), diff --git a/app/test/test_string_fns.c b/app/test/test_string_fns.c index 786eda9e49..697cb7ed15 100644 --- a/app/test/test_string_fns.c +++ b/app/test/test_string_fns.c @@ -5,6 +5,7 @@ #include <stdio.h> #include <stdarg.h> #include <stddef.h> +#include <inttypes.h> #include <errno.h> #include <string.h> @@ -314,6 +315,69 @@ test_rte_basename(void) return 0; } +static int +test_rte_str_to_size(void) +{ + struct { + const char *str; + uint64_t value; + } valid_values[] = { + {"5G", (uint64_t)5 * 1024 * 1024 * 1024}, + {"0x20g", (uint64_t)0x20 * 1024 * 1024 * 1024}, + {"10M", 10 * 1024 * 1024}, + {"050m", 050 * 1024 * 1024}, + {"8K", 8 * 1024}, + {"15k", 15 * 1024}, + {"0200", 0200}, + {"0x103", 0x103}, + {"432", 432}, + {"-1", 0}, + {" -2", 0}, + {" -3MB", 0}, + }; + struct { + const char *str; + } invalid_values[] = { + /* we can only check for invalid input at the start of the string */ + {"garbage"}, + {""}, + {" "}, + }; + unsigned int i; + uint64_t value; + + LOG("Checking valid rte_str_to_size inputs\n"); + + for (i = 0; i < RTE_DIM(valid_values); i++) { + errno = 0; + value = rte_str_to_size(valid_values[i].str); + if (value != valid_values[i].value) { + LOG("FAIL: valid input '%s'\n", valid_values[i].str); + return -1; + } + LOG("PASS: valid input '%s' -> %" PRIu64 "\n", + valid_values[i].str, value); + } + + LOG("Checking invalid rte_str_to_size inputs\n"); + + for (i = 0; i < RTE_DIM(invalid_values); i++) { + errno = 0; + (void)rte_str_to_size(invalid_values[i].str); + if (errno == 0) { + LOG("FAIL: invalid input '%s' did not set errno\n", + invalid_values[i].str); + return -1; + } + LOG("PASS: invalid input '%s' set errno=%d\n", + invalid_values[i].str, errno); + } + + LOG("%s - PASSED\n", __func__); + + return 0; +} + static int test_string_fns(void) { @@ -325,6 +389,8 @@ test_string_fns(void) return -1; if (test_rte_basename() < 0) return -1; + if (test_rte_str_to_size() < 0) + return -1; return 0; } diff --git a/lib/eal/common/eal_common_string_fns.c b/lib/eal/common/eal_common_string_fns.c index fa87831c3a..e0dc48bd80 100644 --- a/lib/eal/common/eal_common_string_fns.c +++ b/lib/eal/common/eal_common_string_fns.c @@ -85,6 +85,10 @@ rte_str_to_size(const char *str) errno = 0; size = strtoull(str, &endptr, 0); + if (endptr == str) { + errno = EINVAL; + return 0; + } if (errno) return 0; -- 2.47.3

