bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

argp: Don't rely on undefined behaviour of _tolower()


From: Bruno Haible
Subject: argp: Don't rely on undefined behaviour of _tolower()
Date: Tue, 08 Dec 2020 19:16:00 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-193-generic; KDE/5.18.0; x86_64; ; )

'_tolower' has undefined behaviour for many characters, see
<https://linux.die.net/man/3/_tolower>.

Also, 'tolower' has undefined behaviour if its argument is not in the
range 0..UCHAR_MAX, see
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/tolower.html>

This patch fixes argp-help.c accordingly. This patch was already applied
on 2009-09-28, but was reverted on 2016-04-03 through
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=14a582531cef13c855c9e9638aac630c0a43ae37

The 2016-04-03 patch also reverted
1) 
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=ec2348da1754e807233e33beefdb732a119e4adc
   reinstalled through
   
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=a50e906c0c046c57938f786ffb82b36beea75043
2) 
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=2457d7ca6856f84502b09fa4690f6f4187de050f
   reinstalled through
   
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=5297992f06027a12671c52ab258eb3fb337972aa


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.

diff --git a/lib/argp-help.c b/lib/argp-help.c
index 52260f3..03fc6c7 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]