ref: 3d3ef19b6beb4639c7471dde143b06500bf8568f
parent: da85f84a98f023ad5abea1f52fe3ea1d1475a16b
author: Quentin Rameau <quinq@fifth.space>
date: Tue Sep 12 07:21:23 EDT 2017
[libc] ctype: don't cast parameter to unsigned char Casting values hides some possible bugs, instead apply friendly undefined behaviour and let the developer fix his code.
--- a/lib/c/include/ctype.h
+++ b/lib/c/include/ctype.h
@@ -29,19 +29,19 @@
extern unsigned char __ctype[];
-#define isalnum(c) (__ctype[(unsigned char) c] & (_U|_L|_D))
-#define isalpha(c) (__ctype[(unsigned char) c] & (_U|_L))
-#define iscntrl(c) (__ctype[(unsigned char) c] & (_C))
-#define isdigit(c) (__ctype[(unsigned char) c] & (_D))
-#define isgraph(c) (__ctype[(unsigned char) c] & (_P|_U|_L|_D))
-#define islower(c) (__ctype[(unsigned char) c] & (_L))
-#define isprint(c) (__ctype[(unsigned char) c] & (_P|_U|_L|_D|_SP))
-#define ispunct(c) (__ctype[(unsigned char) c] & (_P))
-#define isspace(c) (__ctype[(unsigned char) c] & (_S))
-#define isupper(c) (__ctype[(unsigned char) c] & (_U))
-#define isxdigit(c) (__ctype[(unsigned char) c] & (_D|_X))
+#define isalnum(c) ((__ctype+1)[(c)] & (_U|_L|_D))
+#define isalpha(c) ((__ctype+1)[(c)] & (_U|_L))
+#define iscntrl(c) ((__ctype+1)[(c)] & (_C))
+#define isdigit(c) ((__ctype+1)[(c)] & (_D))
+#define isgraph(c) ((__ctype+1)[(c)] & (_P|_U|_L|_D))
+#define islower(c) ((__ctype+1)[(c)] & (_L))
+#define isprint(c) ((__ctype+1)[(c)] & (_P|_U|_L|_D|_SP))
+#define ispunct(c) ((__ctype+1)[(c)] & (_P))
+#define isspace(c) ((__ctype+1)[(c)] & (_S))
+#define isupper(c) ((__ctype+1)[(c)] & (_U))
+#define isxdigit(c) ((__ctype+1)[(c)] & (_D|_X))
-#define isascii(c) (((unsigned) c)<=0x7f)
+#define isascii(c) ((unsigned)(c)<=0x7f)
#endif
--- a/lib/c/src/ctype.c
+++ b/lib/c/src/ctype.c
@@ -2,7 +2,9 @@
#include <ctype.h>
#undef ctype
-unsigned char __ctype[255] = {
+/* __ctype is shifted by one to match EOF */
+unsigned char __ctype[256] = {
+ 0, /* EOF */
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
--- a/lib/c/src/isalnum.c
+++ b/lib/c/src/isalnum.c
@@ -5,5 +5,5 @@
int
isalnum(int c)
{
- return __ctype[(unsigned char) c] & (_U|_L|_D);
+ return (__ctype+1)[c] & (_U|_L|_D);
}
--- a/lib/c/src/isalpha.c
+++ b/lib/c/src/isalpha.c
@@ -5,5 +5,5 @@
int
isalpha(int c)
{
- return __ctype[(unsigned char) c] & (_U|_L);
+ return (__ctype+1)[c] & (_U|_L);
}
--- a/lib/c/src/iscntrl.c
+++ b/lib/c/src/iscntrl.c
@@ -5,5 +5,5 @@
int
iscntrl(int c)
{
- return __ctype[(unsigned char) c] & (_C);
+ return (__ctype+1)[c] & (_C);
}
--- a/lib/c/src/isdigit.c
+++ b/lib/c/src/isdigit.c
@@ -5,5 +5,5 @@
int
isdigit(int c)
{
- return __ctype[(unsigned char) c] & (_D);
+ return (__ctype+1)[c] & (_D);
}
--- a/lib/c/src/isgraph.c
+++ b/lib/c/src/isgraph.c
@@ -5,5 +5,5 @@
int
isgraph(int c)
{
- return __ctype[(unsigned char) c] & (_P|_U|_L|_D);
+ return (__ctype+1)[c] & (_P|_U|_L|_D);
}
--- a/lib/c/src/islower.c
+++ b/lib/c/src/islower.c
@@ -5,5 +5,5 @@
int
islower(int c)
{
- return __ctype[(unsigned char) c] & _L;
+ return (__ctype+1)[c] & _L;
}
--- a/lib/c/src/isprint.c
+++ b/lib/c/src/isprint.c
@@ -5,5 +5,5 @@
int
isprint(int c)
{
- return __ctype[(unsigned char) c] & (_P|_U|_L|_D|_SP);
+ return (__ctype+1)[c] & (_P|_U|_L|_D|_SP);
}
--- a/lib/c/src/ispunct.c
+++ b/lib/c/src/ispunct.c
@@ -5,5 +5,5 @@
int
ispunct(int c)
{
- return __ctype[(unsigned char) c] & (_P);
+ return (__ctype+1)[c] & (_P);
}
--- a/lib/c/src/isspace.c
+++ b/lib/c/src/isspace.c
@@ -5,5 +5,5 @@
int
isspace(int c)
{
- return __ctype[(unsigned char) c] & _S;
+ return (__ctype+1)[c] & _S;
}
--- a/lib/c/src/isupper.c
+++ b/lib/c/src/isupper.c
@@ -5,5 +5,5 @@
int
isupper(int c)
{
- return __ctype[(unsigned char) c] & _U;
+ return (__ctype+1)[c] & _U;
}
--- a/lib/c/src/isxdigit.c
+++ b/lib/c/src/isxdigit.c
@@ -5,5 +5,5 @@
int
isxdigit(int c)
{
- return __ctype[(unsigned char) c] & (_D|_X);
+ return (__ctype+1)[c] & (_D|_X);
}