common: cast arguments to character classification functions to unsigned char
authorSimon Marchi <simon.marchi@efficios.com>
Fri, 6 Mar 2020 20:05:57 +0000 (15:05 -0500)
committerSimon Marchi <simon.marchi@efficios.com>
Mon, 9 Mar 2020 21:20:51 +0000 (17:20 -0400)
We get failures of this type on the cygwin CI machine:

    15:28:20 common.c: In function `bt_common_string_is_printable`:
    15:28:20 common.c:786:16: error: array subscript has type `char` [-Werror=char-subscripts]
    15:28:20   786 |   if (!isprint(*ch) && *ch != '\n' && *ch != '\r' &&
    15:28:20       |                ^~~

This error only pops up on some platforms that have isprint implemented
using a lookup table.  This table is indexed using `*ch`, which is a
char.  And because char is signed on some platforms, gcc warns that this
is dangerous: we could access the array with a negative index, which
would yield unexpected results.

This is on purpose in newlib (the libc used by cygwin, apparently), see
this comment:

  https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/include/ctype.h;h=a0009af17485acc3d70586a0051269a7a9c350d5;hb=HEAD#l78

The Linux man page for isprint also mentions it:

       The standards require that the argument c for these functions is
       either EOF or a value that is representable in the type unsigned
       char.  If the argument c is of type char, it must be cast to unsigned
       char, as in the following example:

           char c;
           ...
           res = toupper((unsigned char) c);

       This is necessary because char may be the equivalent of signed char,
       in which case a byte where the top bit is set would be sign extended
       when converting to int, yielding a value that is outside the range of
       unsigned char.

Add casts to unsigned char to fix the various instances of this error.

Change-Id: Ice2305490997f595c6f5140a8be2abaa7fd1d8f6
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/3194
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
CI-Build: Michael Jeanson <mjeanson@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
src/common/common.c
src/plugins/ctf/common/metadata/lexer.l
src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c
src/plugins/text/dmesg/dmesg.c
src/plugins/text/pretty/print.c
tests/utils/tap/tap.c

index 1a7d57cc2bb420520508336968ef155d6631b6bf..eed2451ea110400d151fde4ad0dddf558149bb56 100644 (file)
@@ -783,7 +783,7 @@ bool bt_common_string_is_printable(const char *input)
        BT_ASSERT_DBG(input);
 
        for (ch = input; *ch != '\0'; ch++) {
        BT_ASSERT_DBG(input);
 
        for (ch = input; *ch != '\0'; ch++) {
-               if (!isprint(*ch) && *ch != '\n' && *ch != '\r' &&
+               if (!isprint((unsigned char) *ch) && *ch != '\n' && *ch != '\r' &&
                                *ch != '\t' && *ch != '\v') {
                        printable = false;
                        goto end;
                                *ch != '\t' && *ch != '\v') {
                        printable = false;
                        goto end;
index 2dd456216a57044ad38f8bfeee0f3387519cddbb..d0695c6b12e6fafc85555fecbc5c2487f9199278 100644 (file)
@@ -134,5 +134,5 @@ _Imaginary                  setstring(yyextra, yylval, yytext); return CTF_IMAGINARY;
 
 {IDENTIFIER}                   BT_LOGT("Got identifier: id=\"%s\"", yytext); setstring(yyextra, yylval, yytext); if (is_type(yyextra, yytext)) return ID_TYPE; else return IDENTIFIER;
 [ \t\r\n]                      ; /* ignore */
 
 {IDENTIFIER}                   BT_LOGT("Got identifier: id=\"%s\"", yytext); setstring(yyextra, yylval, yytext); if (is_type(yyextra, yytext)) return ID_TYPE; else return IDENTIFIER;
 [ \t\r\n]                      ; /* ignore */
-.                              _BT_LOGE_LINENO(yylineno, "Invalid character: char=\"%c\", val=0x%02x", isprint(yytext[0]) ? yytext[0] : '\0', yytext[0]); return CTF_ERROR;
+.                              _BT_LOGE_LINENO(yylineno, "Invalid character: char=\"%c\", val=0x%02x", isprint((unsigned char) yytext[0]) ? yytext[0] : '\0', yytext[0]); return CTF_ERROR;
 %%
 %%
index c808ef0a76c334a12cd9af7c712397fa295b4ffb..e0a03b2e8be3d02c867e7863f7a8f908d86c8a0c 100644 (file)
@@ -154,14 +154,14 @@ bool ist_valid_identifier(const char *name)
        }
 
        /* Make sure the name starts with a letter or `_` */
        }
 
        /* Make sure the name starts with a letter or `_` */
-       if (!isalpha(name[0]) && name[0] != '_') {
+       if (!isalpha((unsigned char) name[0]) && name[0] != '_') {
                ist_valid = false;
                goto end;
        }
 
        /* Make sure the name only contains letters, digits, and `_` */
        for (at = name; *at != '\0'; at++) {
                ist_valid = false;
                goto end;
        }
 
        /* Make sure the name only contains letters, digits, and `_` */
        for (at = name; *at != '\0'; at++) {
-               if (!isalnum(*at) && *at != '_') {
+               if (!isalnum((unsigned char) *at) && *at != '_') {
                        ist_valid = false;
                        goto end;
                }
                        ist_valid = false;
                        goto end;
                }
index 50ceb7e64454d87833bd46cb8034a0f1eb370e72..199dbf925db862fac3288dcc4e10cb0e8905ce8f 100644 (file)
@@ -773,7 +773,7 @@ bt_message_iterator_class_next_method_status dmesg_msg_iter_next_one(
 
                /* Ignore empty lines, once trimmed */
                for (ch = dmesg_msg_iter->linebuf; *ch != '\0'; ch++) {
 
                /* Ignore empty lines, once trimmed */
                for (ch = dmesg_msg_iter->linebuf; *ch != '\0'; ch++) {
-                       if (!isspace(*ch)) {
+                       if (!isspace((unsigned char) *ch)) {
                                only_spaces = false;
                                break;
                        }
                                only_spaces = false;
                                break;
                        }
index e908d75db9f074f635192136281857cbf950c5bf..79dab4132ce8b26207d1628c07886ad586a5f421 100644 (file)
@@ -639,7 +639,7 @@ void print_escape_string(struct pretty_component *pretty, const char *str)
                }
 
                /* Standard characters. */
                }
 
                /* Standard characters. */
-               if (!iscntrl(str[i])) {
+               if (!iscntrl((unsigned char) str[i])) {
                        bt_common_g_string_append_c(pretty->string, str[i]);
                        continue;
                }
                        bt_common_g_string_append_c(pretty->string, str[i]);
                        continue;
                }
index 7d5920ac89f5b83891e7aa4e10b6fe7843112e3d..8e9f9a645fc38c2ec09a972b1b8d45fbcccb891c 100644 (file)
@@ -109,7 +109,7 @@ _gen_result(int ok, const char *func, const char *file, unsigned int line,
                if(local_test_name) {
                        name_is_digits = 1;
                        for(c = local_test_name; *c != '\0'; c++) {
                if(local_test_name) {
                        name_is_digits = 1;
                        for(c = local_test_name; *c != '\0'; c++) {
-                               if(!isdigit(*c) && !isspace(*c)) {
+                               if(!isdigit((unsigned char) *c) && !isspace((unsigned char) *c)) {
                                        name_is_digits = 0;
                                        break;
                                }
                                        name_is_digits = 0;
                                        break;
                                }
This page took 0.030755 seconds and 4 git commands to generate.