ctype bug

Matthew Dillon dillon at apollo.backplane.com
Wed Jul 6 16:56:37 PDT 2005


:I agree we should prevent missindexing. how about:
:
:#ifdef __CTYPE_FAST
:#define	VALID_BOUNDS(c)	/**/
:#else
:#ifdef __CTYPE_ASSERT
:#define	VALID_BOUNDS(c)	assert(c >= -1 && i < 256)
:#else
:#define	VALID_BOUND(c)	if (c != -1) c &= 255;
:#endif
:#endif
:
:static __inline int
:isprint(int c)
:{
:	VALID_BOUNDS(c);
:	return ((int)((__libc_ctype_ + 1)[c] & _R));
:}
:
:oh well, doesn't look too good. maybe it's too late here.
:
:cheers
:   simon

    We can't use assert without including assert.h, but it does bring up
    the point as to whether we should fault out the program or whether
    we should silently return 0.

    Here's what I'm thinking of.  The only thing I don't like about it is
    the way _CTYPE_NUM_CHARS is defined, but on the other hand I'm not
    particularly expecting that we will ever port to an architecture where
    a character is more then 8 bits.

						-Matt

Index: include/ctype.h
===================================================================
RCS file: /cvs/src/include/ctype.h,v
retrieving revision 1.12
diff -u -r1.12 ctype.h
--- include/ctype.h	27 Jun 2005 20:27:35 -0000	1.12
+++ include/ctype.h	6 Jul 2005 23:48:20 -0000
@@ -86,21 +86,53 @@
 #endif
 __END_DECLS
 
+#ifdef _CTYPE_PRIVATE
+extern const __uint16_t	__libc_C_ctype_[];
+extern const __int16_t	__libc_C_toupper_[];
+extern const __int16_t	__libc_C_tolower_[];
+#endif
+
+/*
+ * don't get all wishy washy and try to support architectures where
+ * char isn't 8 bits.   It's 8 bits, period.
+ */
 #if !defined(_CTYPE_H_DISABLE_MACROS_)
 
-#define	isdigit(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _D))
-#define	islower(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _L))
-#define	isspace(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _S))
-#define	ispunct(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _P))
-#define	isupper(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _U))
-#define	isalpha(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _A))
-#define	isxdigit(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _X))
-#define	isalnum(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & (_A|_D)))
-#define	isprint(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _R))
-#define	isgraph(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _G))
-#define	iscntrl(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _C))
-#define	tolower(c)	((int)((__libc_tolower_tab_ + 1)[(int)(c)]))
-#define	toupper(c)	((int)((__libc_toupper_tab_ + 1)[(int)(c)]))
+#define _CTYPE_NUM_CHARS	256
+
+static __inline int
+__libc_ctype_index(__uint16_t mask, int c)
+{
+	if (c < -1 || c >= _CTYPE_NUM_CHARS)
+		return(0);
+	return(__libc_ctype_[c + 1] & mask);
+}
+
+static __inline int
+__libc_ctype_convert(__int16_t *array, int c)
+{
+	if (c < -1 || c >= _CTYPE_NUM_CHARS)
+		return(c);
+	return(array[c + 1]);
+}
+
+#ifndef _CTYPE_PRIVATE
+#undef _CTYPE_NUM_CHARS
+#endif
+
+#define	isdigit(c)	__libc_ctype_index(_D, c)
+#define	islower(c)	__libc_ctype_index(_L, c)
+#define	isspace(c)	__libc_ctype_index(_S, c)
+#define	ispunct(c)	__libc_ctype_index(_P, c)
+#define	isupper(c)	__libc_ctype_index(_U, c)
+#define	isalpha(c)	__libc_ctype_index(_A, c)
+#define	isxdigit(c)	__libc_ctype_index(_X, c)
+#define	isalnum(c)	__libc_ctype_index(_A|_D, c)
+#define	isprint(c)	__libc_ctype_index(_R, c)
+#define	isgraph(c)	__libc_ctype_index(_G, c)
+#define	iscntrl(c)	__libc_ctype_index(_C, c)
+#define	tolower(c)	__libc_ctype_convert(__libc_tolower_tab_, c)
+#define	toupper(c)	__libc_ctype_convert(__libc_toupper_tab, c)
 
 #if defined(__XSI_VISIBLE)
 #define	isascii(c)	((unsigned)(c) <= 0177)
@@ -111,17 +143,7 @@
 
 #if __ISO_C_VISIBLE >= 1999 || __POSIX_VISIBLE >= 200112L || \
     __XSI_VISIBLE >= 600
-#define isblank(c)	((int)((__libc_ctype_ + 1)[(int)(c)] & _B))
-#endif
-
-#ifdef _CTYPE_PRIVATE
-#include <machine/limits.h>	/* for CHAR_BIT */
-
-#define _CTYPE_NUM_CHARS	(1 << CHAR_BIT)
-
-extern const __uint16_t	__libc_C_ctype_[];
-extern const __int16_t	__libc_C_toupper_[];
-extern const __int16_t	__libc_C_tolower_[];
+#define isblank(c)	__libc_ctype_index(_B, c)
 #endif
 
 #endif /* !_CTYPE_H_DISABLE_MACROS_ */
Index: lib/libc/gen/isctype.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/isctype.c,v
retrieving revision 1.4
diff -u -r1.4 isctype.c
--- lib/libc/gen/isctype.c	8 May 2005 15:52:05 -0000	1.4
+++ lib/libc/gen/isctype.c	6 Jul 2005 23:30:58 -0000
@@ -42,84 +42,84 @@
 int
 isalnum(int c)
 {
-	return((__libc_ctype_ + 1)[c] & (_A|_D));
+	return(__libc_ctype_index(_A|_D, c));
 }
 
 #undef isalpha
 int
 isalpha(int c)
 {
-	return((__libc_ctype_ + 1)[c] & (_A));
+	return(__libc_ctype_index(_A, c));
 }
 
 #undef isblank
 int
 isblank(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _B);
+	return(__libc_ctype_index(_B, c));
 }
 
 #undef iscntrl
 int
 iscntrl(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _C);
+	return(__libc_ctype_index(_C, c));
 }
 
 #undef isdigit
 int
 isdigit(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _D);
+	return(__libc_ctype_index(_D, c));
 }
 
 #undef isgraph
 int
 isgraph(int c)
 {
-	return((__libc_ctype_ + 1)[c] & (_G));
+	return(__libc_ctype_index(_G, c));
 }
 
 #undef islower
 int
 islower(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _L);
+	return(__libc_ctype_index(_L, c));
 }
 
 #undef isprint
 int
 isprint(int c)
 {
-	return((__libc_ctype_ + 1)[c] & (_R));
+	return(__libc_ctype_index(_R, c));
 }
 
 #undef ispunct
 int
 ispunct(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _P);
+	return(__libc_ctype_index(_P, c));
 }
 
 #undef isspace
 int
 isspace(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _S);
+	return(__libc_ctype_index(_S, c));
 }
 
 #undef isupper
 int
 isupper(int c)
 {
-	return((__libc_ctype_ + 1)[c] & _U);
+	return(__libc_ctype_index(_U, c));
 }
 
 #undef isxdigit
 int
 isxdigit(int c)
 {
-	return((__libc_ctype_ + 1)[c] & (_X));
+	return(__libc_ctype_index(_X, c));
 }
 
 #undef _toupper
Index: lib/libc/gen/tolower.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/tolower.c,v
retrieving revision 1.1
diff -u -r1.1 tolower.c
--- lib/libc/gen/tolower.c	21 Apr 2005 16:36:34 -0000	1.1
+++ lib/libc/gen/tolower.c	6 Jul 2005 23:30:10 -0000
@@ -56,5 +56,5 @@
 int
 tolower(int c)
 {
-	return((__libc_tolower_tab_ + 1)[c]);
+	return(__libc_ctype_convert(__libc_tolower_tab_, c));
 }
Index: lib/libc/gen/toupper.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/toupper.c,v
retrieving revision 1.1
diff -u -r1.1 toupper.c
--- lib/libc/gen/toupper.c	21 Apr 2005 16:36:34 -0000	1.1
+++ lib/libc/gen/toupper.c	6 Jul 2005 23:29:50 -0000
@@ -56,5 +56,5 @@
 int
 toupper(int c)
 {
-	return((__libc_toupper_tab_ + 1)[c]);
+	return(__libc_ctype_convert(__libc_toupper_tab_, c));
 }





More information about the Commits mailing list