From 1850ea18f4e29eb122c16b3aa0c4222a7e28a2de Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 12 Jun 2025 11:37:56 +1000 Subject: [PATCH] util: add safe_atou64 for 64-bit values Copy/paste from safe_atou Part-of: --- src/util-strings.h | 34 ++++++++++++++++++++++++++++++++++ test/test-utils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/util-strings.h b/src/util-strings.h index abe1fb69..4cdefd75 100644 --- a/src/util-strings.h +++ b/src/util-strings.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -232,6 +233,39 @@ safe_atou(const char *str, unsigned int *val) return safe_atou_base(str, val, 10); } +static inline bool +safe_atou64_base(const char *str, uint64_t *val, int base) +{ + assert(str != NULL); + + char *endptr; + unsigned long long v; + + assert(base == 10 || base == 16 || base == 8); + + errno = 0; + v = strtoull(str, &endptr, base); + if (errno > 0) + return false; + if (str == endptr) + return false; + if (*str != '\0' && *endptr != '\0') + return false; + + if ((long long)v < 0) + return false; + + *val = v; + return true; +} + +static inline bool +safe_atou64(const char *str, uint64_t *val) +{ + assert(str != NULL); + return safe_atou64_base(str, val, 10); +} + static inline bool safe_atod(const char *str, double *val) { diff --git a/test/test-utils.c b/test/test-utils.c index 6400960b..de4de613 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -1209,6 +1209,47 @@ START_TEST(safe_atou_base_8_test) } END_TEST +struct atou64_test { + char *str; + bool success; + unsigned long val; +}; + +START_TEST(safe_atou64_test) +{ + struct atou64_test tests[] = { + { "10", true, 10 }, + { "20", true, 20 }, + { "-1", false, 0 }, + { "9999999999", true, 9999999999 }, + { "2147483647", true, 2147483647 }, + { "-2147483648", false, 0}, + { "0x0", false, 0 }, + { "-10x10", false, 0 }, + { "1x-99", false, 0 }, + { "", false, 0 }, + { "abd", false, 0 }, + { "xabd", false, 0 }, + { "0xaf", false, 0 }, + { "0x0x", false, 0 }, + { "x10", false, 0 }, + { NULL, false, 0 } + }; + uint64_t v; + bool success; + + for (int i = 0; tests[i].str != NULL; i++) { + v = 0xad; + success = safe_atou64(tests[i].str, &v); + litest_assert(success == tests[i].success); + if (success) + litest_assert_int_eq(v, tests[i].val); + else + litest_assert_int_eq(v, 0xadU); + } +} +END_TEST + START_TEST(safe_atod_test) { struct atod_test { @@ -2697,6 +2738,7 @@ int main(void) ADD_TEST(safe_atou_test); ADD_TEST(safe_atou_base_16_test); ADD_TEST(safe_atou_base_8_test); + ADD_TEST(safe_atou64_test); ADD_TEST(safe_atod_test); ADD_TEST(strsplit_test); ADD_TEST(strv_for_each_test);