[PATCH v2 libinput 04/14] util: add a safe_atou() as unsigned equivalent to safe_atoi()

Peter Hutterer peter.hutterer at who-t.net
Fri Jun 8 06:00:11 UTC 2018


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/libinput-util.h |  30 ++++++++++++++
 test/test-misc.c    | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)

diff --git a/src/libinput-util.h b/src/libinput-util.h
index 6524d940..955d1ae7 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -516,6 +516,36 @@ safe_atoi(const char *str, int *val)
 	return safe_atoi_base(str, val, 10);
 }
 
+static inline bool
+safe_atou_base(const char *str, unsigned int *val, int base)
+{
+	char *endptr;
+	unsigned long v;
+
+	assert(base == 10 || base == 16 || base == 8);
+
+	errno = 0;
+	v = strtoul(str, &endptr, base);
+	if (errno > 0)
+		return false;
+	if (str == endptr)
+		return false;
+	if (*str != '\0' && *endptr != '\0')
+		return false;
+
+	if (v > UINT_MAX)
+		return false;
+
+	*val = v;
+	return true;
+}
+
+static inline bool
+safe_atou(const char *str, unsigned int *val)
+{
+	return safe_atou_base(str, val, 10);
+}
+
 static inline bool
 safe_atod(const char *str, double *val)
 {
diff --git a/test/test-misc.c b/test/test-misc.c
index 779baf31..08aa1c8b 100644
--- a/test/test-misc.c
+++ b/test/test-misc.c
@@ -1198,6 +1198,118 @@ START_TEST(safe_atoi_base_8_test)
 }
 END_TEST
 
+struct atou_test {
+	char *str;
+	bool success;
+	unsigned int val;
+};
+
+START_TEST(safe_atou_test)
+{
+	struct atou_test tests[] = {
+		{ "10", true, 10 },
+		{ "20", true, 20 },
+		{ "-1", false, 0 },
+		{ "2147483647", true, 2147483647 },
+		{ "-2147483648", false, 0},
+		{ "4294967295", true, 4294967295 },
+		{ "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 }
+	};
+	unsigned int v;
+	bool success;
+
+	for (int i = 0; tests[i].str != NULL; i++) {
+		v = 0xad;
+		success = safe_atou(tests[i].str, &v);
+		ck_assert(success == tests[i].success);
+		if (success)
+			ck_assert_int_eq(v, tests[i].val);
+		else
+			ck_assert_int_eq(v, 0xad);
+	}
+}
+END_TEST
+
+START_TEST(safe_atou_base_16_test)
+{
+	struct atou_test tests[] = {
+		{ "10", true, 0x10 },
+		{ "20", true, 0x20 },
+		{ "-1", false, 0 },
+		{ "0x10", true, 0x10 },
+		{ "0xff", true, 0xff },
+		{ "abc", true, 0xabc },
+		{ "-10", false, 0 },
+		{ "0x0", true, 0 },
+		{ "0", true, 0 },
+		{ "0x-99", false, 0 },
+		{ "0xak", false, 0 },
+		{ "0x", false, 0 },
+		{ "x10", false, 0 },
+		{ NULL, false, 0 }
+	};
+
+	unsigned int v;
+	bool success;
+
+	for (int i = 0; tests[i].str != NULL; i++) {
+		v = 0xad;
+		success = safe_atou_base(tests[i].str, &v, 16);
+		ck_assert(success == tests[i].success);
+		if (success)
+			ck_assert_int_eq(v, tests[i].val);
+		else
+			ck_assert_int_eq(v, 0xad);
+	}
+}
+END_TEST
+
+START_TEST(safe_atou_base_8_test)
+{
+	struct atou_test tests[] = {
+		{ "7", true, 07 },
+		{ "10", true, 010 },
+		{ "20", true, 020 },
+		{ "-1", false, 0 },
+		{ "010", true, 010 },
+		{ "0ff", false, 0 },
+		{ "abc", false, 0},
+		{ "0xabc", false, 0},
+		{ "-10", false, 0 },
+		{ "0", true, 0 },
+		{ "00", true, 0 },
+		{ "0x0", false, 0 },
+		{ "0x-99", false, 0 },
+		{ "0xak", false, 0 },
+		{ "0x", false, 0 },
+		{ "x10", false, 0 },
+		{ NULL, false, 0 }
+	};
+
+	unsigned int v;
+	bool success;
+
+	for (int i = 0; tests[i].str != NULL; i++) {
+		v = 0xad;
+		success = safe_atou_base(tests[i].str, &v, 8);
+		ck_assert(success == tests[i].success);
+		if (success)
+			ck_assert_int_eq(v, tests[i].val);
+		else
+			ck_assert_int_eq(v, 0xad);
+	}
+}
+END_TEST
+
 struct atod_test {
 	char *str;
 	bool success;
@@ -1675,6 +1787,9 @@ TEST_COLLECTION(misc)
 	litest_add_no_device("misc:parser", safe_atoi_test);
 	litest_add_no_device("misc:parser", safe_atoi_base_16_test);
 	litest_add_no_device("misc:parser", safe_atoi_base_8_test);
+	litest_add_no_device("misc:parser", safe_atou_test);
+	litest_add_no_device("misc:parser", safe_atou_base_16_test);
+	litest_add_no_device("misc:parser", safe_atou_base_8_test);
 	litest_add_no_device("misc:parser", safe_atod_test);
 	litest_add_no_device("misc:parser", strsplit_test);
 	litest_add_no_device("misc:parser", kvsplit_double_test);
-- 
2.14.4



More information about the wayland-devel mailing list