Make sure isCNTRL and isASCII work on signed chars
Karl Williamson [Tue, 20 Apr 2010 02:05:31 +0000 (20:05 -0600)]
Prior to this patch, there is a potential bug in these two macros, in
which, if they are called with a signed character outside the ASCII
range, it will be negative and they always returned true for negative.
Casting the parameter to an unsigned should fix that by having it be
interpreted as a number above the ASCII range.

handy.h

diff --git a/handy.h b/handy.h
index b40deba..3f44c69 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -463,6 +463,11 @@ Converts the specified character to lowercase.  Characters outside the
 US-ASCII (Basic Latin) range are viewed as not having any case.
 
 =cut
+
+NOTE:  Since some of these are macros, there is no check in those that the
+parameter is a char or U8.  This means that if called with a larger width
+parameter, casts can silently truncate and yield wrong results.
+
 */
 
 #define isALNUM(c)     (isALPHA(c) || isDIGIT(c) || (c) == '_')
@@ -504,8 +509,8 @@ US-ASCII (Basic Latin) range are viewed as not having any case.
 #   define isUPPER(c)  ((c) >= 'A' && (c) <= 'Z')
 #   define isLOWER(c)  ((c) >= 'a' && (c) <= 'z')
 #   define isALNUMC(c) (isALPHA(c) || isDIGIT(c))
-#   define isASCII(c)  ((c) <= 127)
-#   define isCNTRL(c)  ((c) < ' ' || (c) == 127)
+#   define isASCII(c)  ((U8) (c) <= 127)
+#   define isCNTRL(c)  ((U8) (c) < ' ' || (c) == 127)
 #   define isGRAPH(c)  (isALNUM(c) || isPUNCT(c))
 #   define isPRINT(c)  (((c) >= 32 && (c) < 127))
 #   define isPUNCT(c)  (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64)  || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126))