[newlib-cygwin/main] strcasecmp family: cast character to unsigned when calling tolower
Corinna Vinschen
corinna@sourceware.org
Mon Feb 17 09:52:55 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=ed18acfe8c7662d8befe86bd8368287046598606
commit ed18acfe8c7662d8befe86bd8368287046598606
Author: Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Feb 17 10:52:11 2025 +0100
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Feb 17 10:52:28 2025 +0100
strcasecmp family: cast character to unsigned when calling tolower
The strcasecmp family of functions (strcasecmp, strncasecmp,
strcasecmp_l, strncasecmp_l) call tolower on the incoming
character before comparison. tolower takes an int as parameter.
All four strcasecmp functions neglect to cast the character to
unsigned before using it as parameter to tolower. This tolower
is called with negative values if the incoming character is not
in the ASCII range. This breaks case-insensitive comparison in
other singlebyte codesets like ISO-8859-1 with native characters.
Adding casts to unsigned char when calling tolower fixes it.
Reported-by: Bruno Haible <bruno@clisp.org>
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
newlib/libc/string/strcasecmp.c | 4 ++--
newlib/libc/string/strcasecmp_l.c | 4 ++--
newlib/libc/string/strncasecmp.c | 6 +++---
newlib/libc/string/strncasecmp_l.c | 6 +++---
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/newlib/libc/string/strcasecmp.c b/newlib/libc/string/strcasecmp.c
index c75a3e20d253..f087328b2a39 100644
--- a/newlib/libc/string/strcasecmp.c
+++ b/newlib/libc/string/strcasecmp.c
@@ -42,8 +42,8 @@ strcasecmp (const char *s1,
int d = 0;
for ( ; ; )
{
- const int c1 = tolower(*s1++);
- const int c2 = tolower(*s2++);
+ const int c1 = tolower(*(unsigned char *)s1++);
+ const int c2 = tolower(*(unsigned char *)s2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
diff --git a/newlib/libc/string/strcasecmp_l.c b/newlib/libc/string/strcasecmp_l.c
index 587f56ee12bf..6a18365fd4de 100644
--- a/newlib/libc/string/strcasecmp_l.c
+++ b/newlib/libc/string/strcasecmp_l.c
@@ -45,8 +45,8 @@ strcasecmp_l (const char *s1, const char *s2, struct __locale_t *locale)
int d = 0;
for ( ; ; )
{
- const int c1 = tolower_l (*s1++, locale);
- const int c2 = tolower_l (*s2++, locale);
+ const int c1 = tolower_l (*(unsigned char*)s1++, locale);
+ const int c2 = tolower_l (*(unsigned char*)s2++, locale);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
diff --git a/newlib/libc/string/strncasecmp.c b/newlib/libc/string/strncasecmp.c
index 09dd98bf53da..84173c8ece01 100644
--- a/newlib/libc/string/strncasecmp.c
+++ b/newlib/libc/string/strncasecmp.c
@@ -36,7 +36,7 @@ QUICKREF
#include <strings.h>
#include <ctype.h>
-int
+int
strncasecmp (const char *s1,
const char *s2,
size_t n)
@@ -44,8 +44,8 @@ strncasecmp (const char *s1,
int d = 0;
for ( ; n != 0; n--)
{
- const int c1 = tolower(*s1++);
- const int c2 = tolower(*s2++);
+ const int c1 = tolower(*(unsigned char*)s1++);
+ const int c2 = tolower(*(unsigned char*)s2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
diff --git a/newlib/libc/string/strncasecmp_l.c b/newlib/libc/string/strncasecmp_l.c
index b15c6c5452a5..8d016860f2a6 100644
--- a/newlib/libc/string/strncasecmp_l.c
+++ b/newlib/libc/string/strncasecmp_l.c
@@ -40,15 +40,15 @@ QUICKREF
#include <strings.h>
#include <ctype.h>
-int
+int
strncasecmp_l (const char *s1, const char *s2, size_t n,
struct __locale_t *locale)
{
int d = 0;
for ( ; n != 0; n--)
{
- const int c1 = tolower_l (*s1++, locale);
- const int c2 = tolower_l (*s2++, locale);
+ const int c1 = tolower_l (*(unsigned char*)s1++, locale);
+ const int c2 = tolower_l (*(unsigned char*)s2++, locale);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
More information about the Newlib-cvs
mailing list