add stdbool.h detection and replacement for bool; use ckd_mul/ckd_add/ckd_sub where appropriate; update overflow detection in brace expansion and printf builtin

This commit is contained in:
Chet Ramey
2024-03-18 11:45:39 -04:00
parent 167a9248f9
commit b1e7f68032
15 changed files with 243 additions and 145 deletions
+45
View File
@@ -8851,3 +8851,48 @@ configure.ac
Makefile.in
- CREATED_HEADERS: add stdckdint.h
stringlib.c,externs.h
- substring: now takes size_t arguments for START and END
lib/sh/stringvec.c
- strvec_create,strvec_mcreate,strvec_resize,strvec_mresize: use
ckd_mul to avoid size_t overflow
- strvec_len,strvec_flush: use size_t variable as array index
From a report by Paul Eggert <eggert@cs.ucla.edu>
bashansi.h
- stdbool.h: include if we have it, typedef bool as unsigned char if
we don't and HAVE_C_BOOL isn't defined
m4/c-bool.m4
- autoconf check for `bool' from gnulib
configure.ac
- include m4/c-bool.m4, call gl_C_BOOL; don't explicitly check for
stdbool.h using AC_CHECK_HEADERS any more
config.h.in
- HAVE_C_BOOL: define
3/16
----
builtins/printf.def
- decodeprec: now decodeint, takes new arguments: a char ** that is
the string to parse and update, an argument saying whether or not
to print an error message on overflow, and an argument that should
be the return value on overflow; use ckd_* macros to check overflow
- printstr, printwidestr: use a different mechanism to check overflow;
call decodeint to get precision and field width
braces.c
- include stdckdint.h for the ckd_* overflow checking macros
- mkseq: the width argument is now size_t
- mkseq: perform overflow detection using the ckd_* macros
- mkseq: perform zero-padding directly instead of using asprintf; the
sprintf family has trouble when width > INT_MAX
- expand_seqterm: use size_t instead of int for length and width
variables
From a report by Paul Eggert <eggert@cs.ucla.edu>
+1
View File
@@ -530,6 +530,7 @@ m4/strtoimax.m4 f
m4/stat-time.m4 f
m4/timespec.m4 f
m4/bison.m4 f
m4/c-bool.m4 f
m4/codeset.m4 f
m4/extern-inline.m4 f
m4/fcntl-o.m4 f
+11 -1
View File
@@ -1,6 +1,6 @@
/* bashansi.h -- Typically included information required by picky compilers. */
/* Copyright (C) 1993-2021 Free Software Foundation, Inc.
/* Copyright (C) 1993-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -35,4 +35,14 @@
# include "ansi_stdlib.h"
#endif /* !HAVE_STDLIB_H */
/* Prefer stdbool.h if we have it, maybe have to rethink this later */
#if defined (HAVE_STDBOOL_H)
# include <stdbool.h>
#else
# ifndef HAVE_C_BOOL
# undef bool
typedef unsigned char bool;
# endif
#endif
#endif /* !_BASHANSI_H_ */
+42 -44
View File
@@ -32,6 +32,7 @@
#endif
#include <errno.h>
#include <stdckdint.h>
#include "bashansi.h"
#include "bashintl.h"
@@ -77,7 +78,7 @@ static const int brace_arg_separator = ',';
static int brace_gobbler (char *, size_t, int *, int);
static char **expand_amble (char *, size_t, int);
static char **expand_seqterm (char *, size_t);
static char **mkseq (intmax_t, intmax_t, intmax_t, int, int);
static char **mkseq (intmax_t, intmax_t, intmax_t, int, size_t);
static char **array_concat (char **, char **);
#if 0
@@ -349,51 +350,37 @@ expand_amble (char *text, size_t tlen, int flags)
#define ST_ZINT 3
static char **
mkseq (intmax_t start, intmax_t end, intmax_t incr, int type, int width)
mkseq (intmax_t start, intmax_t end, intmax_t incr, int type, size_t width)
{
intmax_t n, prevn;
int i, nelem;
intmax_t prevn, n, abs_incr;
size_t nelem, i;
char **result, *t;
char lbuf[INT_BUFSIZE_BOUND (uintmax_t)];
if (incr == 0)
incr = 1;
if (start > end && incr > 0)
incr = -incr;
else if (start < end && incr < 0)
{
if (incr == INTMAX_MIN) /* Don't use -INTMAX_MIN */
return ((char **)NULL);
incr = -incr;
}
/* Check that end-start will not overflow INTMAX_MIN, INTMAX_MAX. The +3
and -2, not strictly necessary, are there because of the way the number
of elements and value passed to strvec_create() are calculated below. */
if (SUBOVERFLOW (end, start, INTMAX_MIN+3, INTMAX_MAX-2))
abs_incr = incr;
if (incr < 0 && ckd_sub (&abs_incr, 0, incr))
return ((char **)NULL);
prevn = sh_imaxabs (end - start);
/* Need to check this way in case INT_MAX == INTMAX_MAX */
if (INT_MAX == INTMAX_MAX && (ADDOVERFLOW (prevn, 2, INT_MIN, INT_MAX)))
return ((char **)NULL);
/* Make sure the assignment to nelem below doesn't end up <= 0 due to
intmax_t overflow */
else if (ADDOVERFLOW ((prevn/sh_imaxabs(incr)), 1, INTMAX_MIN, INTMAX_MAX))
/* Make sure incr agrees with start and end */
if ((start < end) == (incr < 0) && ckd_sub (&incr, 0, incr))
return ((char **)NULL);
/* XXX - TOFIX: potentially allocating a lot of extra memory if
imaxabs(incr) != 1 */
/* Instead of a simple nelem = prevn + 1, something like:
nelem = (prevn / imaxabs(incr)) + 1;
would work */
if ((prevn / sh_imaxabs (incr)) > INT_MAX - 3) /* check int overflow */
/* prevn = sh_imaxabs (end - start); */
if (start < end ? ckd_sub (&prevn, end, start) : ckd_sub (&prevn, start, end))
return ((char **)NULL);
nelem = (prevn / sh_imaxabs(incr)) + 1;
result = strvec_mcreate (nelem + 1);
/* nelem = floor (abs ((end - start) / incr)) plus 1 for first element plus
trailing null. Account for trailing null up here for overflow check */
if (ckd_add (&nelem, prevn / abs_incr, 2))
return ((char **)NULL);
result = strvec_mcreate (nelem);
if (result == 0)
{
internal_error (_("brace expansion: failed to allocate memory for %u elements"), (unsigned int)nelem);
internal_error (_("brace expansion: failed to allocate memory for %s elements"), uinttostr (nelem - 1, lbuf, sizeof (lbuf)));
return ((char **)NULL);
}
@@ -415,9 +402,23 @@ mkseq (intmax_t start, intmax_t end, intmax_t incr, int type, int width)
result[i++] = t = itos (n);
else if (type == ST_ZINT)
{
int len, arg;
arg = n;
len = asprintf (&t, "%0*d", width, arg);
size_t tlen;
t = itos (n);
tlen = strlen (t);
if (tlen < width) /* zero-pad the result directly to avoid sprintf */
{
char *t0;
t0 = t;
t = realloc (t, width + 1);
if (t == 0)
free (t0);
else
{
memmove (t + (width - tlen), t, tlen + 1);
memset (t + (n < 0), '0', width - tlen);
}
}
result[i++] = t;
}
else
@@ -433,23 +434,19 @@ mkseq (intmax_t start, intmax_t end, intmax_t incr, int type, int width)
/* We failed to allocate memory for this number, so we bail. */
if (t == 0)
{
char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1];
char *p;
/* Easier to do this than mess around with various intmax_t printf
formats (%ld? %lld? %jd?) and PRIdMAX. */
p = inttostr (n, lbuf, sizeof (lbuf));
p = uinttostr (n, lbuf, sizeof (lbuf));
internal_error (_("brace expansion: failed to allocate memory for `%s'"), p);
strvec_dispose (result);
return ((char **)NULL);
}
/* Handle overflow and underflow of n+incr */
if (ADDOVERFLOW (n, incr, INTMAX_MIN, INTMAX_MAX))
break;
n += incr;
if ((incr < 0 && n < end) || (incr > 0 && n > end))
if (i == nelem - 1)
break;
}
while (1);
@@ -462,7 +459,8 @@ static char **
expand_seqterm (char *text, size_t tlen)
{
char *t, *lhs, *rhs;
int lhs_t, rhs_t, lhs_l, rhs_l, width;
int lhs_t, rhs_t;
size_t lhs_l, rhs_l, width;
intmax_t lhs_v, rhs_v, incr;
intmax_t tl, tr;
char **result, *ep, *oep;
+37 -73
View File
@@ -70,6 +70,7 @@ $END
#include <stdarg.h>
#include <stdckdint.h>
#include <stdio.h>
#include <chartypes.h>
@@ -245,24 +246,29 @@ static char *conv_buf;
static size_t conv_bufsize;
static inline int
decodeprec (char *ps)
decodeint (char **str, int diagnose, int overflow_return)
{
intmax_t mpr;
int pr;
char *s;
int pr, v;
char *ps;
s = ps; /* error checking */
mpr = *ps++ - '0';
while (DIGIT (*ps))
mpr = (mpr * 10) + (*ps++ - '0');
if (mpr < 0 || mpr > INT_MAX)
ps = *str;
pr = *ps++ - '0';
v = 0;
/* use C23 macros to check overflow */
for (; DIGIT (*ps); ps++)
{
#if 0
report_erange (s, ps);
#endif
v |= ckd_mul (&pr, pr, 10);
v |= ckd_add (&pr, pr, *ps - '0');
}
if (v && diagnose)
{
report_erange (*str, ps);
return -1;
}
return (pr = mpr);
}
*str = ps;
return (v ? overflow_return : pr);
}
int
@@ -668,7 +674,11 @@ printf_builtin (WORD_LIST *list)
if (convch == 'Q' && (have_precision || precstart))
{
if (precstart)
precision = decodeprec (precstart);
{
char *prec;
prec = precstart;
precision = decodeint (&prec, 0, -1);
}
slen = strlen (p);
/* printf precision works in bytes. */
if (precision >= 0 && precision < slen)
@@ -838,10 +848,11 @@ report_erange (char *s, char *e)
static int
printstr (char *fmt, char *string, int len, int fieldwidth, int precision)
{
#if 0
char *s;
#endif
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
intmax_t mfw, mpr;
if (string == 0)
string = "";
@@ -854,8 +865,6 @@ printstr (char *fmt, char *string, int len, int fieldwidth, int precision)
ljust = fw = 0;
pr = -1;
mfw = 0;
mpr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
@@ -877,20 +886,7 @@ printstr (char *fmt, char *string, int len, int fieldwidth, int precision)
}
}
else if (DIGIT (*fmt))
{
s = fmt;
mfw = *fmt++ - '0';
while (DIGIT (*fmt))
mfw = (mfw * 10) + (*fmt++ - '0');
/* Error if fieldwidth > INT_MAX here */
if (mfw < 0 || mfw > INT_MAX)
{
report_erange (s, fmt);
fw = 0;
}
else
fw = mfw;
}
fw = decodeint (&fmt, 1, 0);
/* get precision, if present. doesn't handle negative precisions */
if (*fmt == '.')
@@ -903,20 +899,11 @@ printstr (char *fmt, char *string, int len, int fieldwidth, int precision)
}
else if (DIGIT (*fmt))
{
s = fmt;
mpr = *fmt++ - '0';
while (DIGIT (*fmt))
mpr = (mpr * 10) + (*fmt++ - '0');
/* Error if precision > INT_MAX here */
if (mpr < 0 || mpr > INT_MAX)
{
report_erange (s, fmt);
pr = -1;
}
else
pr = mpr;
pr = decodeint (&fmt, 1, -1);
/* pr < precision means we adjusted precision in printf_builtin
for the quoted string length (%Q), so we use the adjusted value */
if (pr < precision && precision < INT_MAX)
pr = precision; /* XXX */
pr = precision;
}
else
pr = 0; /* "a null digit string is treated as zero" */
@@ -964,7 +951,6 @@ printwidestr (char *fmt, wchar_t *wstring, size_t len, int fieldwidth, int preci
char *string;
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
intmax_t mfw, mpr;
if (wstring == 0)
wstring = L"";
@@ -977,8 +963,6 @@ printwidestr (char *fmt, wchar_t *wstring, size_t len, int fieldwidth, int preci
ljust = fw = 0;
pr = -1;
mfw = 0;
mpr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
@@ -1000,19 +984,7 @@ printwidestr (char *fmt, wchar_t *wstring, size_t len, int fieldwidth, int preci
}
}
else if (DIGIT (*fmt))
{
mfw = *fmt++ - '0';
while (DIGIT (*fmt))
mfw = (mfw * 10) + (*fmt++ - '0');
/* Error if fieldwidth > INT_MAX here */
if (mfw < 0 || mfw > INT_MAX)
{
report_erange (s, fmt);
fw = 0;
}
else
fw = mfw;
}
fw = decodeint (&fmt, 1, 0);
/* get precision, if present. doesn't handle negative precisions */
if (*fmt == '.')
@@ -1025,19 +997,11 @@ printwidestr (char *fmt, wchar_t *wstring, size_t len, int fieldwidth, int preci
}
else if (DIGIT (*fmt))
{
mpr = *fmt++ - '0';
while (DIGIT (*fmt))
mpr = (mpr * 10) + (*fmt++ - '0');
/* Error if precision > INT_MAX here */
if (mpr < 0 || mpr > INT_MAX)
{
report_erange (s, fmt);
pr = -1;
}
else
pr = mpr;
pr = decodeint (&fmt, 1, -1);
/* pr < precision means we adjusted precision in printf_builtin
for the quoted string length (%Q), so we use the adjusted value */
if (pr < precision && precision < INT_MAX)
pr = precision; /* XXX */
pr = precision;
}
else
pr = 0; /* "a null digit string is treated as zero" */
+2
View File
@@ -239,6 +239,8 @@
/* The number of bytes in a `wchar_t', if supported */
#undef SIZEOF_WCHAR_T
#undef HAVE_C_BOOL
/* System paths */
#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail"
Vendored
+52 -14
View File
@@ -2988,6 +2988,7 @@ as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H"
as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H"
as_fn_append ac_header_c_list " stdbool.h stdbool_h HAVE_STDBOOL_H"
gt_needs="$gt_needs need-ngettext"
as_fn_append ac_header_c_list " sys/param.h sys_param_h HAVE_SYS_PARAM_H"
as_fn_append ac_func_c_list " getpagesize HAVE_GETPAGESIZE"
@@ -7111,6 +7112,12 @@ fi
# Check for bool that conforms to C2023.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
printf %s "checking for an ANSI C-conforming const... " >&6; }
if test ${ac_cv_c_const+y}
@@ -7668,6 +7675,43 @@ printf "%s\n" "$ac_cv_c_restrict" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bool, true, false" >&5
printf %s "checking for bool, true, false... " >&6; }
if test ${gl_cv_c_bool+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#if true == false
#error "true == false"
#endif
extern bool b;
bool b = true == false;
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
gl_cv_c_bool=yes
else $as_nop
gl_cv_c_bool=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_c_bool" >&5
printf "%s\n" "$gl_cv_c_bool" >&6; }
if test "$gl_cv_c_bool" = yes; then
printf "%s\n" "#define HAVE_C_BOOL 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5
printf %s "checking for a race-free mkdir -p... " >&6; }
if test -z "$MKDIR_P"; then
@@ -9068,8 +9112,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9071: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9072: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9115: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9116: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9095,7 +9139,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9098: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9142: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9249,7 +9293,7 @@ fi
fi
fi
echo "$as_me:9252: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9296: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -9477,8 +9521,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9480: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9481: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9524: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9525: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9504,7 +9548,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9507: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9551: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9658,7 +9702,7 @@ fi
fi
fi
echo "$as_me:9661: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9705: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -14491,12 +14535,6 @@ if test "x$ac_cv_header_dlfcn_h" = xyes
then :
printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
if test "x$ac_cv_header_stdbool_h" = xyes
then :
printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
if test "x$ac_cv_header_stddef_h" = xyes
+5 -1
View File
@@ -765,6 +765,8 @@ m4_include([m4/xsize.m4])
m4_include([m4/glibc21.m4])
m4_include([m4/host-cpu-c-abi.m4])
m4_include([m4/c-bool.m4])
dnl C compiler characteristics
AC_C_CONST
AC_C_INLINE
@@ -775,6 +777,8 @@ AC_C_CHAR_UNSIGNED
AC_C_VOLATILE
AC_C_RESTRICT
gl_C_BOOL
dnl initialize GNU gettext
dnl the use-libtool is a lie, we just use the standard Unix tools
BASH_GNU_GETTEXT([use-libtool], [need-ngettext], [lib/intl])
@@ -787,7 +791,7 @@ BASH_HEADER_INTTYPES
AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h limits.h string.h \
memory.h locale.h termcap.h termio.h termios.h dlfcn.h \
stdbool.h stddef.h stdint.h netdb.h pwd.h grp.h strings.h \
stddef.h stdint.h netdb.h pwd.h grp.h strings.h \
stdckdint.h \
regex.h syslog.h ulimit.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h sys/ioctl.h \
+1 -1
View File
@@ -484,7 +484,7 @@ current locale. The gettext infrastructure performs the lookup and
translation, using the LC_MESSAGES, TEXTDOMAINDIR, and TEXTDOMAIN
shell variables, as explained below. See the gettext documentation for
additional details not covered here. If the current locale is C or
POSIX, if there are no translations available, of if the string is not
POSIX, if there are no translations available, or if the string is not
translated, the dollar sign is ignored. Since this is a form of double
quoting, the string remains double-quoted by default, whether or not it
is translated and replaced. If the noexpand_translation option is
+1 -1
View File
@@ -485,7 +485,7 @@ current locale. The gettext infrastructure performs the lookup and
translation, using the LC_MESSAGES, TEXTDOMAINDIR, and TEXTDOMAIN
shell variables, as explained below. See the gettext documentation for
additional details not covered here. If the current locale is C or
POSIX, if there are no translations available, of if the string is not
POSIX, if there are no translations available, or if the string is not
translated, the dollar sign is ignored. Since this is a form of double
quoting, the string remains double-quoted by default, whether or not it
is translated and replaced. If the noexpand_translation option is
+1 -1
View File
@@ -547,7 +547,7 @@ and @code{TEXTDOMAIN} shell variables, as explained below.
See the gettext documentation for additional details not covered here.
If the current locale is @code{C} or @code{POSIX},
if there are no translations available,
of if the string is not translated,
or if the string is not translated,
the dollar sign is ignored.
Since this is a form of double quoting, the string remains double-quoted
by default, whether or not it is translated and replaced.
+1 -1
View File
@@ -164,7 +164,7 @@ extern int find_string_in_alist (char *, STRING_INT_ALIST *, int);
extern char *find_token_in_alist (int, STRING_INT_ALIST *, int);
extern int find_index_in_alist (char *, STRING_INT_ALIST *, int);
extern char *substring (const char *, int, int);
extern char *substring (const char *, size_t, size_t);
extern char *strsub (const char *, const char *, const char *, int);
extern char *strcreplace (const char *, int, const char *, int);
extern void strip_leading (char *);
+15 -6
View File
@@ -27,6 +27,7 @@
#endif
#include <bashansi.h>
#include <stdckdint.h>
#include <stdio.h>
#include <chartypes.h>
@@ -36,33 +37,41 @@
char **
strvec_create (size_t n)
{
return ((char **)xmalloc ((n) * sizeof (char *)));
size_t nbytes;
return ckd_mul (&nbytes, n, sizeof (char *)) ? NULL : xmalloc (nbytes);
}
/* Allocate an array of strings with room for N members. */
char **
strvec_mcreate (size_t n)
{
return ((char **)malloc ((n) * sizeof (char *)));
size_t nbytes;
return ckd_mul (&nbytes, n, sizeof (char *)) ? NULL : malloc (nbytes);
}
char **
strvec_resize (char **array, size_t nsize)
{
return ((char **)xrealloc (array, nsize * sizeof (char *)));
size_t nbytes;
return ckd_mul (&nbytes, nsize, sizeof (char *)) ? NULL : (char **)xrealloc (array, nbytes);
}
char **
strvec_mresize (char **array, size_t nsize)
{
return ((char **)realloc (array, nsize * sizeof (char *)));
size_t nbytes;
return ckd_mul (&nbytes, nsize, sizeof (char *)) ? NULL : (char **)realloc (array, nbytes);
}
/* Return the length of ARRAY, a NULL terminated array of char *. */
size_t
strvec_len (char * const *array)
{
register int i;
register size_t i;
for (i = 0; array[i]; i++);
return (i);
@@ -72,7 +81,7 @@ strvec_len (char * const *array)
void
strvec_flush (char **array)
{
register int i;
register size_t i;
if (array == 0)
return;
+27
View File
@@ -0,0 +1,27 @@
# Check for bool that conforms to C2023.
dnl Copyright 2022-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_C_BOOL],
[
AC_CACHE_CHECK([for bool, true, false], [gl_cv_c_bool],
[AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
#if true == false
#error "true == false"
#endif
extern bool b;
bool b = true == false;]])],
[gl_cv_c_bool=yes],
[gl_cv_c_bool=no])])
if test "$gl_cv_c_bool" = yes; then
AC_DEFINE([HAVE_C_BOOL], [1],
[Define to 1 if bool, true and false work as per C2023.])
fi
AC_CHECK_HEADERS_ONCE([stdbool.h])
])
+2 -2
View File
@@ -115,9 +115,9 @@ find_index_in_alist (char *string, STRING_INT_ALIST *alist, int flags)
/* Cons a new string from STRING starting at START and ending at END,
not including END. */
char *
substring (const char *string, int start, int end)
substring (const char *string, size_t start, size_t end)
{
int len;
size_t len;
char *result;
len = end - start;