From: Karel Zak Date: Wed, 2 Apr 2025 09:00:47 +0000 (+0200) Subject: include/cctype: fix string comparison X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=259157b0c1a00806ff75188325e40ba10adf12ce;p=thirdparty%2Futil-linux.git include/cctype: fix string comparison Reimplement c_strcasecmp() and c_strncasecmp() to be libc compatible and fix c_strncasecmp() to avoid \0 misinterpretation. The original implementation was pretty stupid (sorry). Signed-off-by: Karel Zak --- diff --git a/include/cctype.h b/include/cctype.h index b673b6cff..e55c008b8 100644 --- a/include/cctype.h +++ b/include/cctype.h @@ -23,6 +23,9 @@ #ifndef UTIL_LINUX_CCTYPE_H #define UTIL_LINUX_CCTYPE_H +#include +#include + /** * The functions defined in this file assume the "C" locale and a character * set without diacritics (ASCII-US or EBCDIC-US or something like that). @@ -317,38 +320,54 @@ static inline int c_toupper (int c) } } +#define C_CTYPE_CMP(c1, c2) (((c1) > (c2)) - ((c1) < (c2))) + static inline int c_strncasecmp(const char *a, const char *b, size_t n) { - int res = 0; + const unsigned char *p1 = (const unsigned char *) a; + const unsigned char *p2 = (const unsigned char *) b; + unsigned char x, y; - for (; n > 0; a++, b++, n--) { - unsigned int x = (unsigned int) *a; - unsigned int y = (unsigned int) *b; + if (n == 0 || p1 == p2) + return 0; - res = c_tolower(x) - c_tolower(y); - if (res) - break; - } - return res; + do { + x = c_tolower(*p1); + y = c_tolower(*p2); + + if (--n == 0 || x == '\0') + break; + ++p1, ++p2; + } while (x == y); + + if (UCHAR_MAX <= INT_MAX) + return x - y; + + return C_CTYPE_CMP(x, y); } static inline int c_strcasecmp(const char *a, const char *b) { - int res = 0; + const unsigned char *p1 = (const unsigned char *) a; + const unsigned char *p2 = (const unsigned char *) b; + unsigned char x, y; - if (a == b) + if (p1 == p2) return 0; - for (; *a != '\0'; a++, b++) { - unsigned int x = (unsigned int) *a; - unsigned int y = (unsigned int) *b; + do { + x = c_tolower(*p1); + y = c_tolower(*p2); - res = c_tolower(x) - c_tolower(y); - if (res) + if (x == '\0') break; - } + ++p1, ++p2; + } while (x == y); + + if (UCHAR_MAX <= INT_MAX) + return x - y; - return res; + return C_CTYPE_CMP(x, y); } #endif /* UTIL_LINUX_CCTYPE_H */