Mail Archives: djgpp-workers/1999/02/11/15:29:17
At first the test program:
#include <ctype.h>
#include <stdio.h>
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 <robert DOT hoehne AT gmx DOT net> *
* Post: Am Berg 3, D-09573 Dittmannsdorf, Germany *
* WWW: http://www.tu-chemnitz.de/~sho/rho *
******************************************************
- Raw text -