diff --git a/lib/Makefile.am b/lib/Makefile.am index c402ff02a3..3312662b04 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -186,14 +186,14 @@ libshadow_la_SOURCES = \ spawn.c \ sssd.c \ sssd.h \ - string/ctype/strchrisascii/strchriscntrl.c \ - string/ctype/strchrisascii/strchriscntrl.h \ - string/ctype/strisascii/strisdigit.c \ - string/ctype/strisascii/strisdigit.h \ - string/ctype/strisascii/strisprint.c \ - string/ctype/strisascii/strisprint.h \ - string/ctype/strtoascii/strtolower.c \ - string/ctype/strtoascii/strtolower.h \ + string/ctype/isascii.c \ + string/ctype/isascii.h \ + string/ctype/strchrisascii.c \ + string/ctype/strchrisascii.h \ + string/ctype/strisascii.c \ + string/ctype/strisascii.h \ + string/ctype/strtoascii.c \ + string/ctype/strtoascii.h \ string/memset/memzero.c \ string/memset/memzero.h \ string/sprintf/aprintf.c \ diff --git a/lib/chkname.c b/lib/chkname.c index 0abee4d294..57588220fb 100644 --- a/lib/chkname.c +++ b/lib/chkname.c @@ -33,8 +33,9 @@ #include "defines.h" #include "chkname.h" -#include "string/ctype/strchrisascii/strchriscntrl.h" -#include "string/ctype/strisascii/strisdigit.h" +#include "string/ctype/isascii.h" +#include "string/ctype/strchrisascii.h" +#include "string/ctype/strisascii.h" #include "string/strcmp/streq.h" #include "string/strcmp/strcaseeq.h" @@ -68,8 +69,8 @@ is_valid_name(const char *name) || streq(name, "..") || strspn(name, "-") || strpbrk(name, " \"#',/:;") - || strchriscntrl(name) - || strisdigit(name)) + || strchriscntrl_c(name) + || strisdigit_c(name)) { errno = EINVAL; return false; @@ -87,26 +88,16 @@ is_valid_name(const char *name) * sake of Samba 3.x "add machine script" */ - if (!((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.')) - { + if (!ispfchar_c(*name)) { errno = EILSEQ; return false; } while (!streq(++name, "")) { - if (!((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.' || - *name == '-' || - streq(name, "$") - )) - { + if (streq(name, "$")) // Samba + return true; + + if (!ispfchar_c(*name)) { errno = EILSEQ; return false; } diff --git a/lib/fields.c b/lib/fields.c index 144e5fd09a..b8e3bb9e8a 100644 --- a/lib/fields.c +++ b/lib/fields.c @@ -17,8 +17,8 @@ #include #include "prototypes.h" -#include "string/ctype/strisascii/strisprint.h" -#include "string/ctype/strchrisascii/strchriscntrl.h" +#include "string/ctype/strisascii.h" +#include "string/ctype/strchrisascii.h" #include "string/strcmp/streq.h" #include "string/strspn/stpspn.h" #include "string/strspn/stprspn.h" @@ -41,12 +41,12 @@ valid_field_(const char *field, const char *illegal) if (strpbrk(field, illegal)) return -1; - if (strchriscntrl(field)) + if (strchriscntrl_c(field)) return -1; - if (strisprint(field)) - return 0; if (streq(field, "")) return 0; + if (strisprint_c(field)) + return 0; return 1; // !ASCII } diff --git a/lib/getrange.c b/lib/getrange.c index a7f8f05963..a7dd844f67 100644 --- a/lib/getrange.c +++ b/lib/getrange.c @@ -13,6 +13,7 @@ #include "atoi/a2i.h" #include "defines.h" #include "prototypes.h" +#include "string/ctype/isascii.h" #include "string/strcmp/streq.h" @@ -57,7 +58,7 @@ getrange(const char *range, if (streq(end, "")) return 0; /* - */ parse_max: - if (!isdigit((unsigned char) *end)) + if (!isdigit_c(*end)) return -1; if (a2ul(max, end, NULL, 10, *min, ULONG_MAX) == -1) diff --git a/lib/obscure.c b/lib/obscure.c index c572b96a34..485bfd2407 100644 --- a/lib/obscure.c +++ b/lib/obscure.c @@ -19,7 +19,7 @@ #include "prototypes.h" #include "defines.h" #include "getdef.h" -#include "string/ctype/strtoascii/strtolower.h" +#include "string/ctype/strtoascii.h" #include "string/memset/memzero.h" #include "string/sprintf/aprintf.h" #include "string/strcmp/streq.h" diff --git a/lib/port.c b/lib/port.c index 357be218cc..b12d7d282c 100644 --- a/lib/port.c +++ b/lib/port.c @@ -19,6 +19,7 @@ #include "defines.h" #include "port.h" #include "prototypes.h" +#include "string/ctype/isascii.h" #include "string/strcmp/streq.h" #include "string/strcmp/strprefix.h" #include "string/strtok/stpsep.h" @@ -211,7 +212,7 @@ getportent(void) * week or the other two values. */ - for (i = 0; isalpha(cp[i]) && ('\0' != cp[i + 1]); i += 2) { + for (i = 0; isalpha_c(cp[i]) && ('\0' != cp[i + 1]); i += 2) { switch ((cp[i] << 8) | (cp[i + 1])) { case ('S' << 8) | 'u': port.pt_times[j].t_days |= 01; @@ -260,7 +261,7 @@ getportent(void) * representing the times of day. */ - for (dtime = 0; isdigit (cp[i]); i++) { + for (dtime = 0; isdigit_c(cp[i]); i++) { dtime = dtime * 10 + cp[i] - '0'; } @@ -270,7 +271,7 @@ getportent(void) port.pt_times[j].t_start = dtime; cp = cp + i + 1; - for (dtime = 0, i = 0; isdigit (cp[i]); i++) { + for (dtime = 0, i = 0; isdigit_c(cp[i]); i++) { dtime = dtime * 10 + cp[i] - '0'; } diff --git a/lib/setupenv.c b/lib/setupenv.c index 263221636d..f109e10afc 100644 --- a/lib/setupenv.c +++ b/lib/setupenv.c @@ -105,7 +105,7 @@ static void read_env_file (const char *filename) } else if (*cp == '\0') { /* end of string */ goto finished; - } else if (isspace (*cp)) { + } else if (isspace_c(*cp)) { /* unescaped whitespace - end of string */ stpcpy(cp, ""); goto finished; diff --git a/lib/string/README b/lib/string/README index 9fbcbd842c..6ad0e1f5c8 100644 --- a/lib/string/README +++ b/lib/string/README @@ -69,21 +69,26 @@ Specific guidelines: ctype/ - Character classification and conversion functions - strchrisascii/ - The functions defined under this directory + isascii.h + The functions defined in this file + return true + if the character + belongs to the category specified in the function name. + + strchrisascii.h + The functions defined in this file return true if the string has any characters that belong to the category specified in the function name. - strisascii/ - The functions defined under this directory + strisascii.h + The functions defined in this file return true if all of the characters of the string - belong to the category specified in the function name - and the string is not an empty string. + belong to the category specified in the function name. - strtoascii/ - The functions defined under this directory + strtoascii.h + The functions defined in this file translate all characters in a string. memset/ - Memory zeroing diff --git a/lib/string/ctype/isascii.c b/lib/string/ctype/isascii.c new file mode 100644 index 0000000000..5409883124 --- /dev/null +++ b/lib/string/ctype/isascii.c @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include "config.h" + +#include "string/ctype/isascii.h" diff --git a/lib/string/ctype/isascii.h b/lib/string/ctype/isascii.h new file mode 100644 index 0000000000..d0f59fbd58 --- /dev/null +++ b/lib/string/ctype/isascii.h @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_ISASCII_H_ +#define SHADOW_INCLUDE_LIB_STRING_CTYPE_ISASCII_H_ + + +#include "config.h" + +#include + +#include "string/strcmp/streq.h" + + +#define CTYPE_CNTRL_C \ + "\x1F\x1E\x1D\x1C\x1B\x1A\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10" \ + "\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01" /*NUL*/ + +#define CTYPE_LOWER_C "abcdefghijklmnopqrstuvwxyz" +#define CTYPE_UPPER_C "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define CTYPE_DIGIT_C "0123456789" +#define CTYPE_PUNCT_C "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" +#define CTYPE_SPACE_C " \t\n\v\f\r" +#define CTYPE_ALPHA_C CTYPE_LOWER_C CTYPE_UPPER_C +#define CTYPE_ALNUM_C CTYPE_ALPHA_C CTYPE_DIGIT_C +#define CTYPE_GRAPH_C CTYPE_ALNUM_C CTYPE_PUNCT_C +#define CTYPE_PRINT_C CTYPE_GRAPH_C " " +#define CTYPE_XDIGIT_C CTYPE_DIGIT_C "abcdefABCDEF" +#define CTYPE_ASCII_C CTYPE_PRINT_C CTYPE_CNTRL_C /*NUL*/ +#define CTYPE_PFCHAR_C CTYPE_ALNUM_C "._-" // portable filename character set + + +// isascii_c - is [:ascii:] C-locale +#define isascii_c(c) (!!strchr(CTYPE_ASCII_C, c)) +#define iscntrl_c(c) (!!strchr(CTYPE_CNTRL_C, c)) +#define islower_c(c) (!streq(strchrnul(CTYPE_LOWER_C, c), "")) +#define isupper_c(c) (!streq(strchrnul(CTYPE_UPPER_C, c), "")) +#define isdigit_c(c) (!streq(strchrnul(CTYPE_DIGIT_C, c), "")) +#define ispunct_c(c) (!streq(strchrnul(CTYPE_PUNCT_C, c), "")) +#define isspace_c(c) (!streq(strchrnul(CTYPE_SPACE_C, c), "")) +#define isalpha_c(c) (!streq(strchrnul(CTYPE_ALPHA_C, c), "")) +#define isalnum_c(c) (!streq(strchrnul(CTYPE_ALNUM_C, c), "")) +#define isgraph_c(c) (!streq(strchrnul(CTYPE_GRAPH_C, c), "")) +#define isprint_c(c) (!streq(strchrnul(CTYPE_PRINT_C, c), "")) +#define isxdigit_c(c) (!streq(strchrnul(CTYPE_XDIGIT_C, c), "")) +#define ispfchar_c(c) (!streq(strchrnul(CTYPE_PFCHAR_C, c), "")) + + +#endif // include guard diff --git a/lib/string/ctype/strisascii/strisprint.c b/lib/string/ctype/strchrisascii.c similarity index 52% rename from lib/string/ctype/strisascii/strisprint.c rename to lib/string/ctype/strchrisascii.c index 47fb2a3bfe..905430628a 100644 --- a/lib/string/ctype/strisascii/strisprint.c +++ b/lib/string/ctype/strchrisascii.c @@ -4,9 +4,4 @@ #include "config.h" -#include "string/ctype/strisascii/strisprint.h" - -#include - - -extern inline bool strisprint(const char *s); +#include "string/ctype/strchrisascii.h" diff --git a/lib/string/ctype/strchrisascii.h b/lib/string/ctype/strchrisascii.h new file mode 100644 index 0000000000..6d1c4ff022 --- /dev/null +++ b/lib/string/ctype/strchrisascii.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_H_ +#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_H_ + + +#include "config.h" + +#include + +#include "string/ctype/isascii.h" + + +// strchriscntrl_c - string character is [:cntrl:] C-locale +#define strchriscntrl_c(s) (!!strpbrk(s, CTYPE_CNTRL_C)) + + +#endif // include guard diff --git a/lib/string/ctype/strchrisascii/strchriscntrl.c b/lib/string/ctype/strchrisascii/strchriscntrl.c deleted file mode 100644 index ca77b4cfba..0000000000 --- a/lib/string/ctype/strchrisascii/strchriscntrl.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2024, Alejandro Colomar -// SPDX-License-Identifier: BSD-3-Clause - - -#include "config.h" - -#include "string/ctype/strchrisascii/strchriscntrl.h" - -#include - - -extern inline bool strchriscntrl(const char *s); diff --git a/lib/string/ctype/strchrisascii/strchriscntrl.h b/lib/string/ctype/strchrisascii/strchriscntrl.h deleted file mode 100644 index a1eaca371e..0000000000 --- a/lib/string/ctype/strchrisascii/strchriscntrl.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar -// SPDX-License-Identifier: BSD-3-Clause - - -#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_STRCHRISCNTRL_H_ -#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_STRCHRISCNTRL_H_ - - -#include "config.h" - -#include -#include - -#include "string/strcmp/streq.h" - - -inline bool strchriscntrl(const char *s); - - -// string character is [:cntrl:] -// Return true if any iscntrl(3) character is found in the string. -inline bool -strchriscntrl(const char *s) -{ - for (; !streq(s, ""); s++) { - unsigned char c = *s; - - if (iscntrl(c)) - return true; - } - - return false; -} - - -#endif // include guard diff --git a/lib/string/ctype/strisascii.c b/lib/string/ctype/strisascii.c new file mode 100644 index 0000000000..24e8a9cbb4 --- /dev/null +++ b/lib/string/ctype/strisascii.c @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include "config.h" + +#include "string/ctype/strisascii.h" diff --git a/lib/string/ctype/strisascii.h b/lib/string/ctype/strisascii.h new file mode 100644 index 0000000000..eb4d831bbd --- /dev/null +++ b/lib/string/ctype/strisascii.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_H_ +#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_H_ + + +#include "config.h" + +#include "string/ctype/isascii.h" +#include "string/strcmp/streq.h" +#include "string/strspn/stpspn.h" + + +// strisascii_c - string is [:ascii:] C-locale +#define strisdigit_c(s) streq(stpspn(s, CTYPE_DIGIT_C), "") +#define strisprint_c(s) streq(stpspn(s, CTYPE_PRINT_C), "") + + +#endif // include guard diff --git a/lib/string/ctype/strisascii/strisdigit.c b/lib/string/ctype/strisascii/strisdigit.c deleted file mode 100644 index acd4522882..0000000000 --- a/lib/string/ctype/strisascii/strisdigit.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2024, Alejandro Colomar -// SPDX-License-Identifier: BSD-3-Clause - - -#include "config.h" - -#include "string/ctype/strisascii/strisdigit.h" - -#include - - -extern inline bool strisdigit(const char *s); diff --git a/lib/string/ctype/strisascii/strisdigit.h b/lib/string/ctype/strisascii/strisdigit.h deleted file mode 100644 index 0c5175fc8d..0000000000 --- a/lib/string/ctype/strisascii/strisdigit.h +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: 2024, Alejandro Colomar -// SPDX-License-Identifier: BSD-3-Clause - - -#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISDIGIT_H_ -#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISDIGIT_H_ - - -#include "config.h" - -#include - -#include "string/strcmp/streq.h" -#include "string/strspn/stpspn.h" - - -inline bool strisdigit(const char *s); - - -// string is [:digit:] -// Like isdigit(3), but check all characters in the string. -inline bool -strisdigit(const char *s) -{ - if (streq(s, "")) - return false; - - return streq(stpspn(s, "0123456789"), ""); -} - - -#endif // include guard diff --git a/lib/string/ctype/strisascii/strisprint.h b/lib/string/ctype/strisascii/strisprint.h deleted file mode 100644 index 566dbf886d..0000000000 --- a/lib/string/ctype/strisascii/strisprint.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar -// SPDX-License-Identifier: BSD-3-Clause - - -#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISPRINT_H_ -#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISPRINT_H_ - - -#include "config.h" - -#include -#include - -#include "string/strcmp/streq.h" - - -inline bool strisprint(const char *s); - - -// string is [:print:] -// Like isprint(3), but check all characters in the string. -inline bool -strisprint(const char *s) -{ - if (streq(s, "")) - return false; - - for (; !streq(s, ""); s++) { - unsigned char c = *s; - - if (!isprint(c)) - return false; - } - - return true; -} - - -#endif // include guard diff --git a/lib/string/ctype/strtoascii/strtolower.c b/lib/string/ctype/strtoascii.c similarity index 78% rename from lib/string/ctype/strtoascii/strtolower.c rename to lib/string/ctype/strtoascii.c index 99ea4097ca..1e89acaaf5 100644 --- a/lib/string/ctype/strtoascii/strtolower.c +++ b/lib/string/ctype/strtoascii.c @@ -4,7 +4,7 @@ #include "config.h" -#include "string/ctype/strtoascii/strtolower.h" +#include "string/ctype/strtoascii.h" extern inline char *strtolower(char *str); diff --git a/lib/string/ctype/strtoascii/strtolower.h b/lib/string/ctype/strtoascii.h similarity index 61% rename from lib/string/ctype/strtoascii/strtolower.h rename to lib/string/ctype/strtoascii.h index d283fe1e87..c0c3be7177 100644 --- a/lib/string/ctype/strtoascii/strtolower.h +++ b/lib/string/ctype/strtoascii.h @@ -2,8 +2,8 @@ // SPDX-License-Identifier: BSD-3-Clause -#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_STRTOLOWER_H_ -#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_STRTOLOWER_H_ +#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_H_ +#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_H_ #include "config.h" @@ -16,9 +16,7 @@ inline char *strtolower(char *str); -// string convert-to lower-case -// Like tolower(3), but convert all characters in the string. -// Returns the input pointer. +// strtolower - string convert-to lower-case inline char * strtolower(char *str) { diff --git a/lib/subordinateio.c b/lib/subordinateio.c index acd3f1ffdc..5ed5288fbb 100644 --- a/lib/subordinateio.c +++ b/lib/subordinateio.c @@ -22,7 +22,7 @@ #include "alloc/malloc.h" #include "alloc/reallocf.h" #include "atoi/a2i.h" -#include "string/ctype/strisascii/strisdigit.h" +#include "string/ctype/strisascii.h" #include "string/sprintf/snprintf.h" #include "string/strcmp/streq.h" #include "string/strtok/strsep2arr.h" @@ -938,7 +938,7 @@ static int append_uids(uid_t **uids, const char *owner, int n) int i; uid_t owner_uid; - if (strisdigit(owner)) { + if (strisdigit_c(owner)) { i = sscanf(owner, "%d", &owner_uid); if (i != 1) { // should not happen diff --git a/src/newusers.c b/src/newusers.c index e9353fdc0a..6ac29c673d 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -56,6 +56,7 @@ #include "shadow/gshadow/sgrp.h" #include "shadowlog.h" #include "sssd.h" +#include "string/ctype/isascii.h" #include "string/sprintf/snprintf.h" #include "string/strcmp/streq.h" #include "string/strdup/strdup.h" @@ -248,7 +249,7 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid) return 0; } - if (isdigit (gid[0])) { + if (isdigit_c(gid[0])) { /* * The GID is a number, which means either this is a brand * new group, or an existing group. @@ -292,7 +293,7 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid) /* * Now I have all of the fields required to create the new group. */ - if (!streq(gid, "") && (!isdigit(gid[0]))) { + if (!streq(gid, "") && (!isdigit_c(gid[0]))) { grent.gr_name = xstrdup (gid); } else { grent.gr_name = xstrdup (name); @@ -357,7 +358,7 @@ static int get_user_id (const char *uid, uid_t *nuid) { * The first guess for the UID is either the numerical UID that the * caller provided, or the next available UID. */ - if (isdigit (uid[0])) { + if (isdigit_c(uid[0])) { if ((get_uid(uid, nuid) == -1) || (*nuid == (uid_t)-1)) { fprintf (stderr, _("%s: invalid user ID '%s'\n"),