Does what you expect, and returns false on errors. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- src/libinput-util.h | 23 +++++++++++++++++++++++ test/misc.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/src/libinput-util.h b/src/libinput-util.h index 53fe85f..04a454f 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -26,6 +26,7 @@ #define LIBINPUT_UTIL_H #include <unistd.h> +#include <limits.h> #include <math.h> #include <stdarg.h> #include <stdbool.h> @@ -352,4 +353,26 @@ us2ms(uint64_t us) return (uint32_t)(us / 1000); } +static inline bool +atoi_safe(const char *str, int *val) +{ + char *endptr; + long v; + + if (!str) + return false; + + v = strtol(str, &endptr, 0); + + if (str == endptr || *endptr != '\0') + return false; + + if (v > INT_MAX || v < INT_MIN) + return false; + + *val = v; + + return true; +} + #endif /* LIBINPUT_UTIL_H */ diff --git a/test/misc.c b/test/misc.c index d880496..07cc21e 100644 --- a/test/misc.c +++ b/test/misc.c @@ -772,6 +772,46 @@ START_TEST(dimension_prop_parser) } END_TEST +START_TEST(atoi_safe_test) +{ + struct test_case { + const char *str; + bool success; + int value; + } tests[] = { + { "0", true, 0 }, + { "-1", true, -1 }, + { "1", true, 1 }, + { "0xffff", true, 0xffff }, + { "077", true, 077 }, + { "abc", false, 0 }, + { "-1a", false, 0 }, + { "b-1", false, 0 }, + { "0xffffffffffffffff", false, 0 }, + { "0xffffffff", false, 0 }, + { NULL, false, 0 }, + }; + struct test_case *t = tests; + int val; + bool success; + + while (t->str) { + val = 0x54; + + success = atoi_safe(t->str, &val); + ck_assert_int_eq(success, t->success); + if (success) + ck_assert_int_eq(val, t->value); + else + ck_assert_int_eq(val, 0x54); + t++; + } + + success = atoi_safe(NULL, &val); + ck_assert_int_eq(success, false); +} +END_TEST + START_TEST(time_conversion) { ck_assert_int_eq(us(10), 10); @@ -793,7 +833,6 @@ litest_setup_tests(void) litest_add_for_device("events:conversion", event_conversion_touch, LITEST_WACOM_TOUCH); litest_add_for_device("events:conversion", event_conversion_gesture, LITEST_BCM5974); litest_add_for_device("events:conversion", event_conversion_tablet, LITEST_WACOM_CINTIQ); - litest_add_no_device("bitfield_helpers", bitfield_helpers); litest_add_no_device("context:refcount", context_ref_counting); litest_add_no_device("config:status string", config_status_string); @@ -805,4 +844,6 @@ litest_setup_tests(void) litest_add_no_device("misc:parser", trackpoint_accel_parser); litest_add_no_device("misc:parser", dimension_prop_parser); litest_add_no_device("misc:time", time_conversion); + litest_add_no_device("misc:helpers", bitfield_helpers); + litest_add_no_device("misc:helpers", atoi_safe_test); } -- 2.5.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel