]> Savannah Git Hosting - gnulib.git/commitdiff
argp: Don't rely on undefined behaviour of _tolower().
authorBruno Haible <bruno@clisp.org>
Tue, 8 Dec 2020 18:02:02 +0000 (19:02 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 8 Dec 2020 18:02:02 +0000 (19:02 +0100)
Patch by Eric Blake
<https://lists.gnu.org/archive/html/bug-gnulib/2009-09/msg00287.html>.

* lib/argp-help.c (hol_entry_cmp): Don't use _tolower on values that are
not upper-case.  Pass correct range to tolower.

ChangeLog
lib/argp-help.c

index 5992c891d9f04001c73ee5464dbaaa06bc52da00..eaea8df7caab9f902b3a3912614be1fe73ac3b7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2020-12-08  Bruno Haible  <bruno@clisp.org>
+
+       argp: Don't rely on undefined behaviour of _tolower().
+       Patch by Eric Blake
+       <https://lists.gnu.org/archive/html/bug-gnulib/2009-09/msg00287.html>.
+       * lib/argp-help.c (hol_entry_cmp): Don't use _tolower on values that are
+       not upper-case.  Pass correct range to tolower.
+
 2020-12-07  Bruno Haible  <bruno@clisp.org>
 
        unicodeio: Fix wrong result on FreeBSD.
index 52260f35e83aa2fd213fcf8f0d8283691ba7f9eb..03fc6c79eb004393b104c54a0cc30e7560d76e42 100644 (file)
@@ -789,13 +789,11 @@ hol_entry_cmp (const struct hol_entry *entry1,
            first, but as they're not displayed, it doesn't matter where
            they are.  */
         {
-          char first1 = short1 ? short1 : long1 ? *long1 : 0;
-          char first2 = short2 ? short2 : long2 ? *long2 : 0;
-#ifdef _tolower
-          int lower_cmp = _tolower (first1) - _tolower (first2);
-#else
+          unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0;
+          unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0;
+          /* Use tolower, not _tolower, since the latter has undefined
+             behaviour for characters that are not uppercase letters.  */
           int lower_cmp = tolower (first1) - tolower (first2);
-#endif
           /* Compare ignoring case, except when the options are both the
              same letter, in which case lower-case always comes first.  */
           return lower_cmp ? lower_cmp : first2 - first1;