Skip to contentSkip to conversation

ctype.h

PATCH In review Rusty Russell 2 participants 2 messages Dec 20, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ctype.h

While writing the unit tests for xen/common/lib.c, I found a bug in islower and isupper. Character 223 ('ß') should not become 255 ('ÿ') when lower-cased, or vice versa. ISO C says in the C locale, nothing above 127 should be upper or lower case. However, it's not completely useless to regard these characters as iso_8859-1, which seems to be the intent. Either way, if (islower(c)), then isupper(toupper(c)) must be true. This is fixed by regarding both 223 and 255 as alpha, but neither upper nor lower. We have to use both bits, since all 8 bits are taken.

xen/common/lib.c +2 -2
diff -r f1b7a73b9457 xen/common/lib.c
@@ -26,9 +26,9 @@
 _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
 _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
 _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
-_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L|_U,    /* 208-223 */
 _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
-_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L|_U};   /* 240-255 */
 
 
 /* a couple of 64 bit operations ported from freebsd */
xen/include/xen/ctype.h +2 -2
diff -r f1b7a73b9457 xen/include/xen/ctype.h
@@ -24,11 +24,11 @@
 #define iscntrl(c)	((__ismask(c)&(_C)) != 0)
 #define isdigit(c)	((__ismask(c)&(_D)) != 0)
 #define isgraph(c)	((__ismask(c)&(_P|_U|_L|_D)) != 0)
-#define islower(c)	((__ismask(c)&(_L)) != 0)
+#define islower(c)	((__ismask(c)&(_U|_L)) == _L)
 #define isprint(c)	((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
 #define ispunct(c)	((__ismask(c)&(_P)) != 0)
 #define isspace(c)	((__ismask(c)&(_S)) != 0)
-#define isupper(c)	((__ismask(c)&(_U)) != 0)
+#define isupper(c)	((__ismask(c)&(_U|_L)) == _U)
 #define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)
 
 #define isascii(c) (((unsigned char)(c))<=0x7f)
Signature · 1 line
 ccontrol: http://ozlabs.org/~rusty/ccontrol
#1 lore raw
Quoted 8 lines · Rusty Russell

While writing the unit tests for xen/common/lib.c, I found a bug in islower and isupper. Character 223 ('ß') should not become 255 ('ÿ') when lower-cased, or vice versa. ISO C says in the C locale, nothing above 127 should be upper or lower case. However, it's not completely useless to regard these characters as iso_8859-1, which seems to be the intent. Either way, if (islower(c)), then isupper(toupper(c)) must be true. This is fixed by regarding both 223 and 255 as alpha, but neither upper nor lower. We have to use both bits, since all 8 bits are taken.

If it gets fixed in Linux, which is where I pulled that code from originally, then I'll pull down a new copy into Xen. I think it's safe to say right now that no caller in Xen is depending on getting an ISO-mandated result from isupper/islower on chars with the msb set. Maybe when the i18n project for the hypervisor kicks off... ;-)

-- Keir