www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/02/11/15:29:17

Message-Id: <199902112029.PAA12141@delorie.com>
From: Robert Hoehne <robert DOT hoehne AT gmx DOT net>
Organization: none provided
To: djgpp-workers AT delorie DOT com
Date: Thu, 11 Feb 1999 21:29:47 +0100
MIME-Version: 1.0
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019