diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-07-05 11:55:26 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-07-05 14:25:07 +0200 |
commit | ff25d3385dfbf493c878c9e227df56db3dc10b6a (patch) | |
tree | a4302f4eb82e157abfa94c3045a65abeafdbb3af /src | |
parent | sd-id128: don't allow chars > f in valid id128 values (diff) | |
download | systemd-ff25d3385dfbf493c878c9e227df56db3dc10b6a.tar.xz systemd-ff25d3385dfbf493c878c9e227df56db3dc10b6a.zip |
tree-wide: add global ascii_isdigit() + ascii_isalpha()
We now have a local implementation in string-util-fundamental.c, but
it's useful at a lot of other places, hence let's give it a more
expressive name and share it across the tree.
Follow-up for: 8d9156660d6958c8d63b1d44692968f1b5d33920
Diffstat (limited to 'src')
25 files changed, 68 insertions, 89 deletions
diff --git a/src/basic/bus-label.c b/src/basic/bus-label.c index cd6c58a3d3..d33fc92290 100644 --- a/src/basic/bus-label.c +++ b/src/basic/bus-label.c @@ -26,12 +26,10 @@ char *bus_label_escape(const char *s) { for (f = s, t = r; *f; f++) { - /* Escape everything that is not a-zA-Z0-9. We also - * escape 0-9 if it's the first character */ + /* Escape everything that is not a-zA-Z0-9. We also escape 0-9 if it's the first character */ - if (!(*f >= 'A' && *f <= 'Z') && - !(*f >= 'a' && *f <= 'z') && - !(f > s && *f >= '0' && *f <= '9')) { + if (!ascii_isalpha(*f) && + !(f > s && ascii_isdigit(*f))) { *(t++) = '_'; *(t++) = hexchar(*f >> 4); *(t++) = hexchar(*f); diff --git a/src/basic/env-util.c b/src/basic/env-util.c index b60c9f9fdc..62914f1587 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -32,7 +32,7 @@ static bool env_name_is_valid_n(const char *e, size_t n) { if (n <= 0) return false; - if (e[0] >= '0' && e[0] <= '9') + if (ascii_isdigit(e[0])) return false; /* POSIX says the overall size of the environment block cannot diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c index d5d1388102..b710f07929 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -75,10 +75,8 @@ int gethostname_full(GetHostnameFlags flags, char **ret) { bool valid_ldh_char(char c) { /* "LDH" → "Letters, digits, hyphens", as per RFC 5890, Section 2.3.1 */ - return - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || + return ascii_isalpha(c) || + ascii_isdigit(c) || c == '-'; } diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 35fbb5ec6a..787a681870 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -210,7 +210,7 @@ int parse_size(const char *t, uint64_t base, uint64_t *size) { e++; /* strtoull() itself would accept space/+/- */ - if (*e >= '0' && *e <= '9') { + if (ascii_isdigit(*e)) { unsigned long long l2; char *e2; @@ -599,7 +599,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { /* accept any number of digits, strtoull is limited to 19 */ for (size_t i = 0; i < digits; i++,s++) { - if (*s < '0' || *s > '9') { + if (!ascii_isdigit(*s)) { if (i == 0) return -EINVAL; diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index c642718e95..f39be19a59 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -833,7 +833,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { if (!ifname_valid_char(*t)) return false; - numeric = numeric && (*t >= '0' && *t <= '9'); + numeric = numeric && ascii_isdigit(*t); } /* It's fully numeric but didn't parse as valid ifindex above? if so, it must be too large or zero or diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index a142ba2dfb..0c092597eb 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -624,7 +624,7 @@ int vtnr_from_tty(const char *tty) { if (!startswith(tty, "tty") ) return -EINVAL; - if (tty[3] < '0' || tty[3] > '9') + if (!ascii_isdigit(tty[3])) return -EINVAL; r = safe_atoi(tty+3, &i); diff --git a/src/basic/time-util.c b/src/basic/time-util.c index c309369406..abbc4ad5cd 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -1411,9 +1411,8 @@ int verify_timezone(const char *name, int log_level) { return -EINVAL; for (p = name; *p; p++) { - if (!(*p >= '0' && *p <= '9') && - !(*p >= 'a' && *p <= 'z') && - !(*p >= 'A' && *p <= 'Z') && + if (!ascii_isdigit(*p) && + !ascii_isalpha(*p) && !IN_SET(*p, '-', '_', '+', '/')) return -EINVAL; diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 8b1283a9ec..16185332f9 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -814,15 +814,13 @@ bool valid_user_group_name(const char *u, ValidUserFlags flags) { * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. */ - if (!(u[0] >= 'a' && u[0] <= 'z') && - !(u[0] >= 'A' && u[0] <= 'Z') && + if (!ascii_isalpha(u[0]) && u[0] != '_') return false; for (i = u+1; *i; i++) - if (!(*i >= 'a' && *i <= 'z') && - !(*i >= 'A' && *i <= 'Z') && - !(*i >= '0' && *i <= '9') && + if (!ascii_isalpha(*i) && + !ascii_isdigit(*i) && !IN_SET(*i, '_', '-')) return false; diff --git a/src/fundamental/string-util-fundamental.c b/src/fundamental/string-util-fundamental.c index 6f690b9c90..11701ebe52 100644 --- a/src/fundamental/string-util-fundamental.c +++ b/src/fundamental/string-util-fundamental.c @@ -77,18 +77,8 @@ sd_char* endswith_no_case(const sd_char *s, const sd_char *postfix) { return (sd_char*) s + sl - pl; } -static bool is_digit(sd_char a) { - /* Locale-independent version of isdigit(). */ - return a >= '0' && a <= '9'; -} - -static bool is_alpha(sd_char a) { - /* Locale-independent version of isalpha(). */ - return (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'); -} - static bool is_valid_version_char(sd_char a) { - return is_digit(a) || is_alpha(a) || IN_SET(a, '~', '-', '^', '.'); + return ascii_isdigit(a) || ascii_isalpha(a) || IN_SET(a, '~', '-', '^', '.'); } int strverscmp_improved(const sd_char *a, const sd_char *b) { @@ -186,12 +176,12 @@ int strverscmp_improved(const sd_char *a, const sd_char *b) { b++; } - if (is_digit(*a) || is_digit(*b)) { + if (ascii_isdigit(*a) || ascii_isdigit(*b)) { /* Find the leading numeric segments. One may be an empty string. So, * numeric segments are always newer than alpha segments. */ - for (aa = a; is_digit(*aa); aa++) + for (aa = a; ascii_isdigit(*aa); aa++) ; - for (bb = b; is_digit(*bb); bb++) + for (bb = b; ascii_isdigit(*bb); bb++) ; /* Check if one of the strings was empty, but the other not. */ @@ -217,9 +207,9 @@ int strverscmp_improved(const sd_char *a, const sd_char *b) { return r; } else { /* Find the leading non-numeric segments. */ - for (aa = a; is_alpha(*aa); aa++) + for (aa = a; ascii_isalpha(*aa); aa++) ; - for (bb = b; is_alpha(*bb); bb++) + for (bb = b; ascii_isalpha(*bb); bb++) ; /* Note that the segments are usually not NUL-terminated. */ diff --git a/src/fundamental/string-util-fundamental.h b/src/fundamental/string-util-fundamental.h index 72fa0d7c90..ecf32e519f 100644 --- a/src/fundamental/string-util-fundamental.h +++ b/src/fundamental/string-util-fundamental.h @@ -104,3 +104,13 @@ static inline void *memory_startswith(const void *p, size_t sz, const sd_char *t #define STRV_FOREACH(s, l) \ _STRV_FOREACH(s, l, UNIQ_T(i, UNIQ)) + +static inline bool ascii_isdigit(sd_char a) { + /* A pure ASCII, locale independent version of isdigit() */ + return a >= '0' && a <= '9'; +} + +static inline bool ascii_isalpha(sd_char a) { + /* A pure ASCII, locale independent version of isalpha() */ + return (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'); +} diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c index ea535a27af..3e87a93a9e 100644 --- a/src/journal/journald-audit.c +++ b/src/journal/journald-audit.c @@ -161,9 +161,8 @@ static int map_generic_field( if (*e == '=') break; - if (!((*e >= 'a' && *e <= 'z') || - (*e >= 'A' && *e <= 'Z') || - (*e >= '0' && *e <= '9') || + if (!(ascii_isalpha(*e) || + ascii_isdigit(*e) || IN_SET(*e, '_', '-'))) return 0; } diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index 925bd502d3..ce02378675 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -279,14 +279,13 @@ static int syslog_skip_timestamp(const char **buf) { _fallthrough_; case NUMBER: - if (*p < '0' || *p > '9') + if (!ascii_isdigit(*p)) return 0; break; case LETTER: - if (!(*p >= 'A' && *p <= 'Z') && - !(*p >= 'a' && *p <= 'z')) + if (!ascii_isalpha(*p)) return 0; break; diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index 0f1ea45c08..a249b848ca 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -29,10 +29,8 @@ bool object_path_is_valid(const char *p) { } else { bool good; - good = - (*q >= 'a' && *q <= 'z') || - (*q >= 'A' && *q <= 'Z') || - (*q >= '0' && *q <= '9') || + good = ascii_isalpha(*q) || + ascii_isdigit(*q) || *q == '_'; if (!good) @@ -87,9 +85,8 @@ bool interface_name_is_valid(const char *p) { bool good; good = - (*q >= 'a' && *q <= 'z') || - (*q >= 'A' && *q <= 'Z') || - (!dot && *q >= '0' && *q <= '9') || + ascii_isalpha(*q) || + (!dot && ascii_isdigit(*q)) || *q == '_'; if (!good) { @@ -134,9 +131,8 @@ bool service_name_is_valid(const char *p) { bool good; good = - (*q >= 'a' && *q <= 'z') || - (*q >= 'A' && *q <= 'Z') || - ((!dot || unique) && *q >= '0' && *q <= '9') || + ascii_isalpha(*q) || + ((!dot || unique) && ascii_isdigit(*q)) || IN_SET(*q, '_', '-'); if (!good) @@ -167,9 +163,8 @@ bool member_name_is_valid(const char *p) { bool good; good = - (*q >= 'a' && *q <= 'z') || - (*q >= 'A' && *q <= 'Z') || - (*q >= '0' && *q <= '9') || + ascii_isalpha(*q) || + ascii_isdigit(*q) || *q == '_'; if (!good) @@ -301,9 +296,8 @@ char *bus_address_escape(const char *v) { for (a = v, b = r; *a; a++) { - if ((*a >= '0' && *a <= '9') || - (*a >= 'a' && *a <= 'z') || - (*a >= 'A' && *a <= 'Z') || + if (ascii_isdigit(*a) || + ascii_isalpha(*a) || strchr("_-/.", *a)) *(b++) = *a; else { diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index ba7767ee49..6a03582fd9 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -171,7 +171,7 @@ static void test_sd_device_one(sd_device *d) { assert_se(val > sysname); assert_se(val < sysname + strlen(sysname)); assert_se(in_charset(val, DIGITS)); - assert_se(!isdigit(val[-1])); + assert_se(!ascii_isdigit(val[-1])); } else assert_se(r == -ENOENT); diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index afdf4b7f98..4f52c14f64 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -25,7 +25,7 @@ bool id128_is_valid(const char *s) { for (i = 0; i < l; i++) { char c = s[i]; - if (!(c >= '0' && c <= '9') && + if (!ascii_isdigit(c) && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return false; @@ -42,7 +42,7 @@ bool id128_is_valid(const char *s) { if (c != '-') return false; } else { - if (!(c >= '0' && c <= '9') && + if (!ascii_isdigit(c) && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return false; diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 976e28e54b..bbe7c78306 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -1470,13 +1470,13 @@ bool journal_field_valid(const char *p, size_t l, bool allow_protected) { return false; /* Don't allow digits as first character */ - if (p[0] >= '0' && p[0] <= '9') + if (ascii_isdigit(p[0])) return false; /* Only allow A-Z0-9 and '_' */ for (const char *a = p; a < p + l; a++) if ((*a < 'A' || *a > 'Z') && - (*a < '0' || *a > '9') && + !ascii_isdigit(*a) && *a != '_') return false; diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index 4a9f1a90b2..60e352022f 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -167,7 +167,7 @@ static int match_is_valid(const void *data, size_t size) { if (*p >= 'A' && *p <= 'Z') continue; - if (*p >= '0' && *p <= '9') + if (ascii_isdigit(*p)) continue; return false; @@ -2246,7 +2246,7 @@ static bool field_is_valid(const char *field) { if (*p >= 'A' && *p <= 'Z') continue; - if (*p >= '0' && *p <= '9') + if (ascii_isdigit(*p)) continue; return false; diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 88ff4ce45e..43c72da11f 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -646,9 +646,8 @@ void seat_add_to_gc_queue(Seat *s) { static bool seat_name_valid_char(char c) { return - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || + ascii_isalpha(c) || + ascii_isdigit(c) || IN_SET(c, '-', '_'); } diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 2047dc1817..cb6a6fb514 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -195,8 +195,7 @@ static bool display_is_local(const char *display) { return display[0] == ':' && - display[1] >= '0' && - display[1] <= '9'; + ascii_isdigit(display[1]); } static int socket_from_display(const char *display) { diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index d2eaea584b..7b83b91bee 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1163,7 +1163,7 @@ static int manager_next_random_name(const char *old, char **ret_new) { assert(p); while (p > old) { - if (!strchr(DIGITS, p[-1])) + if (!ascii_isdigit(p[-1])) break; p--; diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c index 767c1b7856..86a6d3f608 100644 --- a/src/shared/calendarspec.c +++ b/src/shared/calendarspec.c @@ -521,7 +521,7 @@ static int parse_component_decimal(const char **p, bool usec, int *res) { const char *e = NULL; int r; - if (!isdigit(**p)) + if (!ascii_isdigit(**p)) return -EINVAL; r = parse_one_number(*p, &e, &value); diff --git a/src/shared/device-nodes.c b/src/shared/device-nodes.c index ec5613ac58..40e469379f 100644 --- a/src/shared/device-nodes.c +++ b/src/shared/device-nodes.c @@ -5,13 +5,13 @@ #include <string.h> #include "device-nodes.h" +#include "string-util.h" #include "utf8.h" int allow_listed_char_for_devnode(char c, const char *white) { return - (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || + ascii_isdigit(c) || + ascii_isalpha(c) || strchr("#+-.:=@_", c) || (white && strchr(white, c)); } diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 36174f8743..68f7912674 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -251,7 +251,7 @@ static int make_partition_devname( if (isempty(whole_devname)) /* Make sure there *is* a last char */ return -EINVAL; - need_p = strchr(DIGITS, whole_devname[strlen(whole_devname)-1]); /* Last char a digit? */ + need_p = ascii_isdigit(whole_devname[strlen(whole_devname)-1]); /* Last char a digit? */ return asprintf(ret, "%s%s%i", whole_devname, need_p ? "p" : "", nr); } diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index 1292a3359f..ebf86d2405 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -236,9 +236,8 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) { sz -= 2; } else if (IN_SET(*p, '_', '-') || - (*p >= '0' && *p <= '9') || - (*p >= 'a' && *p <= 'z') || - (*p >= 'A' && *p <= 'Z')) { + ascii_isdigit(*p) || + ascii_isalpha(*p)) { /* Proper character */ @@ -907,15 +906,13 @@ static bool srv_type_label_is_valid(const char *label, size_t n) { return false; /* Second char must be a letter */ - if (!(label[1] >= 'A' && label[1] <= 'Z') && - !(label[1] >= 'a' && label[1] <= 'z')) + if (!ascii_isalpha(label[1])) return false; /* Third and further chars must be alphanumeric or a hyphen */ for (k = 2; k < n; k++) { - if (!(label[k] >= 'A' && label[k] <= 'Z') && - !(label[k] >= 'a' && label[k] <= 'z') && - !(label[k] >= '0' && label[k] <= '9') && + if (!ascii_isalpha(label[k]) && + !ascii_isdigit(label[k]) && label[k] != '-') return false; } diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index ae92e45205..d33eede984 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -695,9 +695,8 @@ static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *ar /* compose valid udev tag name */ for (const char *p = path; *p; p++) { - if ((*p >= '0' && *p <= '9') || - (*p >= 'A' && *p <= 'Z') || - (*p >= 'a' && *p <= 'z') || + if (ascii_isdigit(*p) || + ascii_isalpha(*p) || *p == '-') { tag[i++] = *p; continue; |