[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