From e520e0fc2c6075a592d62175232849f19f7b7417 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jan 2018 11:48:25 +0100 Subject: [PATCH 1/3] locale-util: add freelocale() cleanup helper --- src/basic/locale-util.h | 8 ++++++++ src/basic/parse-util.c | 12 ++++-------- src/import/curl-util.c | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) 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..ab80c2b04b9 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" @@ -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; } 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; From b5ffbc55791612749ef36925a56e7d2d6fe5227b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jan 2018 11:49:24 +0100 Subject: [PATCH 2/3] parse-util: coding style fix Let's not rely on C's downgrade-to-bool feature to check for NUL bytes --- src/basic/parse-util.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index ab80c2b04b9..14687b16a02 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -84,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; @@ -392,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; @@ -414,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; @@ -436,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; @@ -456,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; @@ -476,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; @@ -500,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; @@ -522,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; From bac794f6071152977f1b6f8478282c440c8e0e19 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Jan 2018 11:50:12 +0100 Subject: [PATCH 3/3] parse-util: detect overflows in parse_percent_unbounded() We shouldn't accept percentages beyon INT32_MAX and consider them valid. --- src/basic/parse-util.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 14687b16a02..2c22753deac 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -592,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) {