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 <appro@openssl.org>
This commit is contained in:
Richard Levitte 2016-02-14 13:02:15 +01:00
parent ef8ca6bd54
commit 18295f0c2d
7 changed files with 25 additions and 16 deletions

View File

@ -183,7 +183,7 @@ int chopup_args(ARGS *arg, char *buf)
for (p = buf;;) { for (p = buf;;) {
/* Skip whitespace. */ /* Skip whitespace. */
while (*p && isspace(*p)) while (*p && isspace(_UC(*p)))
p++; p++;
if (!*p) if (!*p)
break; break;
@ -207,7 +207,7 @@ int chopup_args(ARGS *arg, char *buf)
p++; p++;
*p++ = '\0'; *p++ = '\0';
} else { } else {
while (*p && !isspace(*p)) while (*p && !isspace(_UC(*p)))
p++; p++;
if (*p) if (*p)
*p++ = '\0'; *p++ = '\0';

View File

@ -149,6 +149,13 @@ int opt_umax(const char *value, uintmax_t *result);
# define uintmax_t unsigned long # define uintmax_t unsigned long
# endif # 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_load_file(const char *file, int dont_warn);
int app_RAND_write_file(const char *file); int app_RAND_write_file(const char *file);
/* /*

View File

@ -731,7 +731,7 @@ end_of_options:
goto end; goto end;
} }
for ( ; *p; p++) { for ( ; *p; p++) {
if (!isxdigit(*p)) { if (!isxdigit(_UC(*p))) {
BIO_printf(bio_err, BIO_printf(bio_err,
"entry %d: bad char 0%o '%c' in serial number\n", "entry %d: bad char 0%o '%c' in serial number\n",
i + 1, *p, *p); i + 1, *p, *p);

View File

@ -1065,7 +1065,7 @@ static int urldecode(char *p)
for (; *p; p++) { for (; *p; p++) {
if (*p != '%') if (*p != '%')
*out++ = *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]); *out++ = (app_hex(p[1]) << 4) | app_hex(p[2]);
p += 2; p += 2;
} }

View File

@ -509,9 +509,9 @@ static ossl_ssize_t hexdecode(const char **inptr, void *result)
for (byte = 0; *in; ++in) { for (byte = 0; *in; ++in) {
char c; char c;
if (isspace(*in)) if (isspace(_UC(*in)))
continue; continue;
c = tolower(*in); c = tolower(_UC(*in));
if ('0' <= c && c <= '9') { if ('0' <= c && c <= '9') {
byte |= c - '0'; byte |= c - '0';
} else if ('a' <= c && c <= 'f') { } else if ('a' <= c && c <= 'f') {
@ -553,11 +553,11 @@ static ossl_ssize_t checked_uint8(const char **inptr, void *out)
e = restore_errno(); e = restore_errno();
if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) || if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) ||
endp == in || !isspace(*endp) || endp == in || !isspace(_UC(*endp)) ||
v != (*result = (uint8_t) v)) { v != (*result = (uint8_t) v)) {
return -1; return -1;
} }
for (in = endp; isspace(*in); ++in) for (in = endp; isspace(_UC(*in)); ++in)
continue; continue;
*inptr = in; *inptr = in;
@ -1141,7 +1141,7 @@ int s_client_main(int argc, char **argv)
break; break;
case OPT_PSK: case OPT_PSK:
for (p = psk_key = opt_arg(); *p; p++) { for (p = psk_key = opt_arg(); *p; p++) {
if (isxdigit(*p)) if (isxdigit(_UC(*p)))
continue; continue;
BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key);
goto end; goto end;

View File

@ -1380,7 +1380,7 @@ int s_server_main(int argc, char *argv[])
case OPT_PSK: case OPT_PSK:
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
for (p = psk_key = opt_arg(); *p; p++) { for (p = psk_key = opt_arg(); *p; p++) {
if (isxdigit(*p)) if (isxdigit(_UC(*p)))
continue; continue;
BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
goto end; goto end;

View File

@ -65,6 +65,8 @@
#include "../e_os.h" #include "../e_os.h"
#define _UC(c) ((unsigned char)(c))
static const char *progname; static const char *progname;
/* /*
@ -229,7 +231,7 @@ static char *read_to_eol(FILE *f)
} }
/* Trim trailing whitespace */ /* Trim trailing whitespace */
while (n > 0 && isspace(buf[n-1])) while (n > 0 && isspace(_UC(buf[n-1])))
buf[--n] = '\0'; buf[--n] = '\0';
return buf; return buf;
@ -252,9 +254,9 @@ static ossl_ssize_t hexdecode(const char *in, void *result)
for (byte = 0; *in; ++in) { for (byte = 0; *in; ++in) {
char c; char c;
if (isspace(*in)) if (isspace(_UC(*in)))
continue; continue;
c = tolower(*in); c = tolower(_UC(*in));
if ('0' <= c && c <= '9') { if ('0' <= c && c <= '9') {
byte |= c - '0'; byte |= c - '0';
} else if ('a' <= c && c <= 'f') { } else if ('a' <= c && c <= 'f') {
@ -291,11 +293,11 @@ static ossl_ssize_t checked_uint8(const char *in, void *out)
e = restore_errno(); e = restore_errno();
if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) || 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)) { v != (*(uint8_t *)result = (uint8_t) v)) {
return -1; return -1;
} }
for (cp = endp; isspace(*cp); ++cp) for (cp = endp; isspace(_UC(*cp)); ++cp)
continue; continue;
return cp - in; return cp - in;
} }
@ -351,7 +353,7 @@ static int tlsa_import_rr(SSL *ssl, const char *rrdata)
static int allws(const char *cp) static int allws(const char *cp)
{ {
while (*cp) while (*cp)
if (!isspace(*cp++)) if (!isspace(_UC(*cp++)))
return 0; return 0;
return 1; return 1;
} }