From 5ef56aa205b5c36e622ed0401d4c4c32be6bb47b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Mar 2018 22:27:19 +0100 Subject: [PATCH 1/2] parse-util: introduce safe_atou16_full() safe_atou16_full() is like safe_atou16() but also takes a base parameter. safe_atou16() is then implemented as inline function on top of it, passing 0 as base. Similar safe_atoux16() is reworked as inline function too, with 16 as base. --- src/basic/parse-util.c | 29 +++-------------------------- src/basic/parse-util.h | 13 ++++++++++--- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index fa5b4a353af..f0bf57916e8 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -487,17 +487,18 @@ int safe_atou8(const char *s, uint8_t *ret) { return 0; } -int safe_atou16(const char *s, uint16_t *ret) { +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) { char *x = NULL; unsigned long l; assert(s); assert(ret); + assert(base <= 16); s += strspn(s, WHITESPACE); errno = 0; - l = strtoul(s, &x, 0); + l = strtoul(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) @@ -531,30 +532,6 @@ int safe_atoi16(const char *s, int16_t *ret) { return 0; } -int safe_atoux16(const char *s, uint16_t *ret) { - char *x = NULL; - unsigned long l; - - assert(s); - assert(ret); - - s += strspn(s, WHITESPACE); - - errno = 0; - l = strtoul(s, &x, 16); - if (errno > 0) - return -errno; - if (!x || x == s || *x != 0) - return -EINVAL; - if (s[0] == '-') - return -ERANGE; - if ((unsigned long) (uint16_t) l != l) - return -ERANGE; - - *ret = (uint16_t) l; - return 0; -} - int safe_atod(const char *s, double *ret_d) { _cleanup_(freelocalep) locale_t loc = (locale_t) 0; char *x = NULL; diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 727422056a3..82265fcd0cd 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -51,10 +51,17 @@ int safe_atolli(const char *s, long long int *ret_i); int safe_atou8(const char *s, uint8_t *ret); -int safe_atou16(const char *s, uint16_t *ret); -int safe_atoi16(const char *s, int16_t *ret); +int safe_atou16_full(const char *s, unsigned base, uint16_t *ret); -int safe_atoux16(const char *s, uint16_t *ret); +static inline int safe_atou16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 0, ret); +} + +static inline int safe_atoux16(const char *s, uint16_t *ret) { + return safe_atou16_full(s, 16, ret); +} + +int safe_atoi16(const char *s, int16_t *ret); static inline int safe_atou32(const char *s, uint32_t *ret_u) { assert_cc(sizeof(uint32_t) == sizeof(unsigned)); From 65baa289cf6e6cc18d4eeea390a913a88fc4e1c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Mar 2018 22:31:40 +0100 Subject: [PATCH 2/2] parse-util: similar to safe_atou16_full() add safe_atou_full() What's good for uint16_t is also good for unsigned. This is preparation for: #8140 --- src/basic/parse-util.c | 5 +++-- src/basic/parse-util.h | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index f0bf57916e8..32ea870e341 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -371,12 +371,13 @@ finish: } -int safe_atou(const char *s, unsigned *ret_u) { +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) { char *x = NULL; unsigned long l; assert(s); assert(ret_u); + assert(base <= 16); /* strtoul() is happy to parse negative values, and silently * converts them to unsigned values without generating an @@ -389,7 +390,7 @@ int safe_atou(const char *s, unsigned *ret_u) { s += strspn(s, WHITESPACE); errno = 0; - l = strtoul(s, &x, 0); + l = strtoul(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 82265fcd0cd..1605cc4ff5c 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -44,7 +44,12 @@ int parse_syscall_and_errno(const char *in, char **name, int *error); #define FORMAT_BYTES_MAX 8 char *format_bytes(char *buf, size_t l, uint64_t t); -int safe_atou(const char *s, unsigned *ret_u); +int safe_atou_full(const char *s, unsigned base, unsigned *ret_u); + +static inline int safe_atou(const char *s, unsigned *ret_u) { + return safe_atou_full(s, 0, ret_u); +} + int safe_atoi(const char *s, int *ret_i); int safe_atollu(const char *s, unsigned long long *ret_u); int safe_atolli(const char *s, long long int *ret_i);