From 18295f0c2db084fe00d935d8506d6e964f652d21 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sun, 14 Feb 2016 13:02:15 +0100 Subject: [PATCH] Make sure to use unsigned char for is*() functions 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 --- apps/apps.c | 4 ++-- apps/apps.h | 7 +++++++ apps/ca.c | 2 +- apps/ocsp.c | 2 +- apps/s_client.c | 10 +++++----- apps/s_server.c | 2 +- test/danetest.c | 14 ++++++++------ 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/apps/apps.c b/apps/apps.c index 7a4608f75c..2a189f20a0 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -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'; diff --git a/apps/apps.h b/apps/apps.h index 8ac7c03891..878dc11c07 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -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); /* diff --git a/apps/ca.c b/apps/ca.c index 9a1b69f68d..716df02fac 100644 --- 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); diff --git a/apps/ocsp.c b/apps/ocsp.c index 73b407c986..f9ba4e158a 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -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; } diff --git a/apps/s_client.c b/apps/s_client.c index c122c1a613..55d1283b1c 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -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; diff --git a/apps/s_server.c b/apps/s_server.c index 489924ced6..38030364bd 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -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; diff --git a/test/danetest.c b/test/danetest.c index 01f77313ea..9b7ac1d98d 100644 --- a/test/danetest.c +++ b/test/danetest.c @@ -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; }