Message-Id: <199902112029.PAA12141@delorie.com> From: Robert Hoehne Organization: none provided To: djgpp-workers AT delorie DOT com Date: Thu, 11 Feb 1999 21:29:47 +0100 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: ctype functions X-mailer: Pegasus Mail for Win32 (v3.01d) Reply-To: djgpp-workers AT delorie DOT com At first the test program: #include #include int main() { char c; c = 142; printf("%d %d\n", tolower(c), tolower((unsigned char)c)); return 0; } If you compile it with gcc -o foo.exe foo.c and then run it, the result will be 108 142 (where the first number might differ). The problem is simply, that tolower (and also the other ctype functions) are declared to take an int argument. So we have now here at first a real bug: calling tolower(-114) (which is tolower(c) in the above example, since c is signed) will access memory, which is not wanted (__dj_type_tolower[-113]). Even when this access is no memory violation, it is wrong. My question is now: Are the ctype functions buggy or my calls to them? In my opinion the ctype functions should be changed, since I can change the calls to for instance tolower() in my code, but I cannot do it in for instance stricmp() which will produce wrong results if I pass it strings with characters above 127. OK, here now the patch, which I would apply: --- include/inlines/ctype.ha~ Sun Jun 28 22:06:22 1998 +++ include/inlines/ctype.ha Wed Feb 10 21:10:56 1999 @@ -17,19 +17,19 @@ extern unsigned char __dj_ctype_toupper[]; extern unsigned char __dj_ctype_tolower[]; -#define isalnum(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISALNUM) -#define isalpha(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISALPHA) -#define iscntrl(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISCNTRL) -#define isdigit(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISDIGIT) -#define isgraph(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISGRAPH) -#define islower(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISLOWER) -#define isprint(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISPRINT) -#define ispunct(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISPUNCT) -#define isspace(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISSPACE) -#define isupper(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISUPPER) -#define isxdigit(c) (__dj_ctype_flags[(int)(c)+1] & __dj_ISXDIGIT) +#define isalnum(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISALNUM) +#define isalpha(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISALPHA) +#define iscntrl(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISCNTRL) +#define isdigit(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISDIGIT) +#define isgraph(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISGRAPH) +#define islower(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISLOWER) +#define isprint(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISPRINT) +#define ispunct(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISPUNCT) +#define isspace(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISSPACE) +#define isupper(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISUPPER) +#define isxdigit(c) (__dj_ctype_flags[((unsigned)(c) & 0xff)+1] & __dj_ISXDIGIT) -#define tolower(c) (__dj_ctype_tolower[(int)(c)+1]) -#define toupper(c) (__dj_ctype_toupper[(int)(c)+1]) +#define tolower(c) (__dj_ctype_tolower[((unsigned)(c) & 0xff)+1]) +#define toupper(c) (__dj_ctype_toupper[((unsigned)(c) & 0xff)+1]) #endif /* __dj_include_inline_ctype_hi_ */ ****************************************************** * email: Robert Hoehne * * Post: Am Berg 3, D-09573 Dittmannsdorf, Germany * * WWW: http://www.tu-chemnitz.de/~sho/rho * ******************************************************