Make sure to use unsigned char for is*() functions
authorRichard Levitte <levitte@openssl.org>
Sun, 14 Feb 2016 12:02:15 +0000 (13:02 +0100)
committerRichard Levitte <levitte@openssl.org>
Sun, 14 Feb 2016 18:31:55 +0000 (19:31 +0100)
On some platforms, the implementation is such that a signed char
triggers a warning when used with is*() functions.  On others, the
behavior is outright buggy when presented with a char that happens
to get promoted to a negative integer.

The safest thing is to cast the char that's used to an unsigned char.

Reviewed-by: Andy Polyakov <appro@openssl.org>
apps/apps.c
apps/apps.h
apps/ca.c
apps/ocsp.c
apps/s_client.c
apps/s_server.c
test/danetest.c

index 7a4608f..2a189f2 100644 (file)
@@ -183,7 +183,7 @@ int chopup_args(ARGS *arg, char *buf)
 
     for (p = buf;;) {
         /* Skip whitespace. */
-        while (*p && isspace(*p))
+        while (*p && isspace(_UC(*p)))
             p++;
         if (!*p)
             break;
@@ -207,7 +207,7 @@ int chopup_args(ARGS *arg, char *buf)
                 p++;
             *p++ = '\0';
         } else {
-            while (*p && !isspace(*p))
+            while (*p && !isspace(_UC(*p)))
                 p++;
             if (*p)
                 *p++ = '\0';
index 8ac7c03..878dc11 100644 (file)
@@ -149,6 +149,13 @@ int opt_umax(const char *value, uintmax_t *result);
 #  define uintmax_t unsigned long
 # endif
 
+/*
+ * quick macro when you need to pass an unsigned char instead of a char.
+ * this is true for some implementations of the is*() functions, for
+ * example.
+ */
+#define _UC(c) ((unsigned char)(c))
+
 int app_RAND_load_file(const char *file, int dont_warn);
 int app_RAND_write_file(const char *file);
 /*
index 9a1b69f..716df02 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -731,7 +731,7 @@ end_of_options:
             goto end;
         }
         for ( ; *p; p++) {
-            if (!isxdigit(*p)) {
+            if (!isxdigit(_UC(*p))) {
                 BIO_printf(bio_err,
                            "entry %d: bad char 0%o '%c' in serial number\n",
                            i + 1, *p, *p);
index 73b407c..f9ba4e1 100644 (file)
@@ -1065,7 +1065,7 @@ static int urldecode(char *p)
     for (; *p; p++) {
         if (*p != '%')
             *out++ = *p;
-        else if (isxdigit(p[1]) && isxdigit(p[2])) {
+        else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) {
             *out++ = (app_hex(p[1]) << 4) | app_hex(p[2]);
             p += 2;
         }
index c122c1a..55d1283 100644 (file)
@@ -509,9 +509,9 @@ static ossl_ssize_t hexdecode(const char **inptr, void *result)
     for (byte = 0; *in; ++in) {
         char c;
 
-        if (isspace(*in))
+        if (isspace(_UC(*in)))
             continue;
-        c = tolower(*in);
+        c = tolower(_UC(*in));
         if ('0' <= c && c <= '9') {
             byte |= c - '0';
         } else if ('a' <= c && c <= 'f') {
@@ -553,11 +553,11 @@ static ossl_ssize_t checked_uint8(const char **inptr, void *out)
     e = restore_errno();
 
     if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) ||
-        endp == in || !isspace(*endp) ||
+        endp == in || !isspace(_UC(*endp)) ||
         v != (*result = (uint8_t) v)) {
         return -1;
     }
-    for (in = endp; isspace(*in); ++in)
+    for (in = endp; isspace(_UC(*in)); ++in)
         continue;
 
     *inptr = in;
@@ -1141,7 +1141,7 @@ int s_client_main(int argc, char **argv)
             break;
         case OPT_PSK:
             for (p = psk_key = opt_arg(); *p; p++) {
-                if (isxdigit(*p))
+                if (isxdigit(_UC(*p)))
                     continue;
                 BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key);
                 goto end;
index 489924c..3803036 100644 (file)
@@ -1380,7 +1380,7 @@ int s_server_main(int argc, char *argv[])
         case OPT_PSK:
 #ifndef OPENSSL_NO_PSK
             for (p = psk_key = opt_arg(); *p; p++) {
-                if (isxdigit(*p))
+                if (isxdigit(_UC(*p)))
                     continue;
                 BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
                 goto end;
index 01f7731..9b7ac1d 100644 (file)
@@ -65,6 +65,8 @@
 
 #include "../e_os.h"
 
+#define _UC(c) ((unsigned char)(c))
+
 static const char *progname;
 
 /*
@@ -229,7 +231,7 @@ static char *read_to_eol(FILE *f)
     }
 
     /* Trim trailing whitespace */
-    while (n > 0 && isspace(buf[n-1]))
+    while (n > 0 && isspace(_UC(buf[n-1])))
         buf[--n] = '\0';
 
     return buf;
@@ -252,9 +254,9 @@ static ossl_ssize_t hexdecode(const char *in, void *result)
     for (byte = 0; *in; ++in) {
         char c;
 
-        if (isspace(*in))
+        if (isspace(_UC(*in)))
             continue;
-        c = tolower(*in);
+        c = tolower(_UC(*in));
         if ('0' <= c && c <= '9') {
             byte |= c - '0';
         } else if ('a' <= c && c <= 'f') {
@@ -291,11 +293,11 @@ static ossl_ssize_t checked_uint8(const char *in, void *out)
     e = restore_errno();
 
     if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) ||
-        endp == cp || !isspace(*endp) ||
+        endp == cp || !isspace(_UC(*endp)) ||
         v != (*(uint8_t *)result = (uint8_t) v)) {
         return -1;
     }
-    for (cp = endp; isspace(*cp); ++cp)
+    for (cp = endp; isspace(_UC(*cp)); ++cp)
         continue;
     return cp - in;
 }
@@ -351,7 +353,7 @@ static int tlsa_import_rr(SSL *ssl, const char *rrdata)
 static int allws(const char *cp)
 {
     while (*cp)
-        if (!isspace(*cp++))
+        if (!isspace(_UC(*cp++)))
             return 0;
     return 1;
 }