mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-07 17:17:44 +03:00
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: 8d9156660d
This commit is contained in:
parent
82c3a0b74c
commit
ff25d3385d
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 == '-';
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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, '-', '_');
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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--;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user