#include "io.h"
#include "format.h"
-#include <ctype.h>
#include <string.h>
return -1;
fmt->format_string_len--;
- c = toupper (*fmt->format_string++);
+ c = safe_toupper (*fmt->format_string++);
fmt->error_element = c;
}
while ((c == ' ' || c == '\t') && !literal);
case '+':
c = next_char (fmt, 0);
- if (!isdigit (c))
+ if (!safe_isdigit (c))
{
token = FMT_UNKNOWN;
break;
for (;;)
{
c = next_char (fmt, 0);
- if (!isdigit (c))
+ if (!safe_isdigit (c))
break;
fmt->value = 10 * fmt->value + c - '0';
for (;;)
{
c = next_char (fmt, 0);
- if (!isdigit (c))
+ if (!safe_isdigit (c))
break;
fmt->value = 10 * fmt->value + c - '0';
#include "fbuf.h"
#include "unix.h"
#include <string.h>
-#include <ctype.h>
typedef unsigned char uchar;
if (parse_repeat (dtp))
return;
- c = tolower (next_char (dtp));
+ c = safe_tolower (next_char (dtp));
l_push_char (dtp, c);
switch (c)
{
break;
case '.':
- c = tolower (next_char (dtp));
+ c = safe_tolower (next_char (dtp));
switch (c)
{
case 't':
}
get_integer:
- if (!isdigit (c))
+ if (!safe_isdigit (c))
goto bad_integer;
push_char (dtp, c);
if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
c = '.';
- if (!isdigit (c) && c != '.')
+ if (!safe_isdigit (c) && c != '.')
{
if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
goto inf_nan;
}
exp2:
- if (!isdigit (c))
+ if (!safe_isdigit (c))
{
/* Extension: allow default exponent of 0 when omitted. */
if (dtp->common.flags & IOPARM_DT_DEC_EXT)
if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
c = '.';
- if (!isdigit (c) && c != '.')
+ if (!safe_isdigit (c) && c != '.')
{
if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
goto inf_nan;
}
exp2:
- if (!isdigit (c))
+ if (!safe_isdigit (c))
{
/* Extension: allow default exponent of 0 when omitted. */
if (dtp->common.flags & IOPARM_DT_DEC_EXT)
for (i = 0; i < len; i++)
{
c = next_char (dtp);
- if (c == EOF || (tolower (c) != tolower (name[i])))
+ if (c == EOF || (safe_tolower (c) != safe_tolower (name[i])))
{
dtp->u.p.nml_read_error = 1;
break;
do
{
if (!is_separator (c))
- push_char_default (dtp, tolower(c));
+ push_char_default (dtp, safe_tolower(c));
if ((c = next_char (dtp)) == EOF)
goto nml_err_ret;
}
#include "format.h"
#include "unix.h"
#include <string.h>
-#include <ctype.h>
#include <assert.h>
#include "async.h"
between "NaN" and the optional perenthesis is not permitted. */
while (w > 0)
{
- *out = tolower (*p);
+ *out = safe_tolower (*p);
switch (*p)
{
case ' ':
goto bad_float;
break;
default:
- if (!isalnum (*out))
+ if (!safe_isalnum (*out))
goto bad_float;
}
--w;
if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
{
- while (w > 0 && isdigit (*p))
+ while (w > 0 && safe_isdigit (*p))
{
exponent *= 10;
exponent += *p - '0';
else
assert (dtp->u.p.blank_status == BLANK_NULL);
}
- else if (!isdigit (*p))
+ else if (!safe_isdigit (*p))
goto bad_float;
else
{
#include "unix.h"
#include <assert.h>
#include <string.h>
-#include <ctype.h>
#define star_fill(p, n) memset(p, '*', n)
base_name_len = strlen (base_name);
for (dim_i = 0; dim_i < base_name_len; dim_i++)
{
- cup = toupper ((int) base_name[dim_i]);
+ cup = safe_toupper (base_name[dim_i]);
write_character (dtp, &cup, 1, 1, NODELIM);
}
}
clen = strlen (obj->var_name);
for (dim_i = len; dim_i < clen; dim_i++)
{
- cup = toupper ((int) obj->var_name[dim_i]);
+ cup = safe_toupper (obj->var_name[dim_i]);
if (cup == '+')
cup = '%';
write_character (dtp, &cup, 1, 1, NODELIM);
/* Write namelist name in upper case - f95 std. */
for (gfc_charlen_type i = 0; i < dtp->namelist_name_len; i++ )
{
- c = toupper ((int) dtp->namelist_name[i]);
+ c = safe_toupper (dtp->namelist_name[i]);
write_character (dtp, &c, 1 ,1, NODELIM);
}
/* config.h MUST be first because it can affect system headers. */
#include "config.h"
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#endif
+/* These functions from <ctype.h> should only be used on values that can be
+ represented as unsigned char, otherwise the behavior is undefined.
+ Some targets have a char type that is signed, so we cast the argument
+ to unsigned char. See:
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95177
+ https://wiki.sei.cmu.edu/confluence/x/BNcxBQ
+ */
+
+#define safe_isalnum(x) isalnum((unsigned char) (x))
+#define safe_isdigit(x) isdigit((unsigned char) (x))
+#define safe_tolower(x) tolower((unsigned char) (x))
+#define safe_toupper(x) toupper((unsigned char) (x))
+
+
/* The following macros can be used to annotate conditions which are likely or
unlikely to be true. Avoid using them when a condition is only slightly
more likely/less unlikely than average to avoid the performance penalties of
#include <string.h>
#include <strings.h>
-#include <ctype.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
return;
for (q = p; *q; q++)
- if (!isdigit (*q) && (p != q || *q != '-'))
+ if (!safe_isdigit (*q) && (p != q || *q != '-'))
return;
*v->var = atoi (p);
match_integer (void)
{
unit_num = 0;
- while (isdigit (*p))
+ while (safe_isdigit (*p))
unit_num = unit_num * 10 + (*p++ - '0');
return INTEGER;
}