diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h index 60ce017a151..f75dcbc3d1b 100644 --- a/src/basic/locale-util.h +++ b/src/basic/locale-util.h @@ -22,6 +22,7 @@ #include #include +#include #include "macro.h" @@ -75,3 +76,10 @@ LocaleVariable locale_variable_from_string(const char *s) _pure_; int get_keymaps(char ***l); bool keymap_is_valid(const char *name); + +static inline void freelocalep(locale_t *p) { + if (*p == (locale_t) 0) + return; + + freelocale(*p); +} diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 33f94f3fc2e..2c22753deac 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -28,6 +28,7 @@ #include "alloc-util.h" #include "errno-list.h" #include "extract-word.h" +#include "locale-util.h" #include "macro.h" #include "parse-util.h" #include "process-util.h" @@ -83,7 +84,7 @@ int parse_mode(const char *s, mode_t *ret) { l = strtol(s, &x, 8); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (l < 0 || l > 07777) return -ERANGE; @@ -391,7 +392,7 @@ int safe_atou(const char *s, unsigned *ret_u) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -413,7 +414,7 @@ int safe_atoi(const char *s, int *ret_i) { l = strtol(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if ((long) (int) l != l) return -ERANGE; @@ -435,7 +436,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { l = strtoull(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (*s == '-') return -ERANGE; @@ -455,7 +456,7 @@ int safe_atolli(const char *s, long long int *ret_lli) { l = strtoll(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; *ret_lli = l; @@ -475,7 +476,7 @@ int safe_atou8(const char *s, uint8_t *ret) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -499,7 +500,7 @@ int safe_atou16(const char *s, uint16_t *ret) { l = strtoul(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if (s[0] == '-') return -ERANGE; @@ -521,7 +522,7 @@ int safe_atoi16(const char *s, int16_t *ret) { l = strtol(s, &x, 0); if (errno > 0) return -errno; - if (!x || x == s || *x) + if (!x || x == s || *x != 0) return -EINVAL; if ((long) (int16_t) l != l) return -ERANGE; @@ -531,9 +532,9 @@ int safe_atoi16(const char *s, int16_t *ret) { } int safe_atod(const char *s, double *ret_d) { + _cleanup_(freelocalep) locale_t loc = (locale_t) 0; char *x = NULL; double d = 0; - locale_t loc; assert(s); assert(ret_d); @@ -544,16 +545,11 @@ int safe_atod(const char *s, double *ret_d) { errno = 0; d = strtod_l(s, &x, loc); - if (errno > 0) { - freelocale(loc); + if (errno > 0) return -errno; - } - if (!x || x == s || *x) { - freelocale(loc); + if (!x || x == s || *x != 0) return -EINVAL; - } - freelocale(loc); *ret_d = (double) d; return 0; } @@ -596,19 +592,20 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { int parse_percent_unbounded(const char *p) { const char *pc, *n; - unsigned v; - int r; + int r, v; pc = endswith(p, "%"); if (!pc) return -EINVAL; n = strndupa(p, pc - p); - r = safe_atou(n, &v); + r = safe_atoi(n, &v); if (r < 0) return r; + if (v < 0) + return -ERANGE; - return (int) v; + return v; } int parse_percent(const char *p) { diff --git a/src/import/curl-util.c b/src/import/curl-util.c index 7069c95a9fa..62bbaa500da 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -21,6 +21,7 @@ #include "alloc-util.h" #include "curl-util.h" #include "fd-util.h" +#include "locale-util.h" #include "string-util.h" static void curl_glue_check_finished(CurlGlue *g) { @@ -414,8 +415,8 @@ int curl_header_strdup(const void *contents, size_t sz, const char *field, char } int curl_parse_http_time(const char *t, usec_t *ret) { + _cleanup_(freelocalep) locale_t loc = (locale_t) 0; const char *e; - locale_t loc; struct tm tm; time_t v; @@ -434,7 +435,6 @@ int curl_parse_http_time(const char *t, usec_t *ret) { if (!e || *e != 0) /* ANSI C */ e = strptime_l(t, "%a %b %d %H:%M:%S %Y", &tm, loc); - freelocale(loc); if (!e || *e != 0) return -EINVAL;