summaryrefslogtreecommitdiff
path: root/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'macros/texinfo/texinfo/gnulib/lib/vasnprintf.c')
-rw-r--r--macros/texinfo/texinfo/gnulib/lib/vasnprintf.c423
1 files changed, 332 insertions, 91 deletions
diff --git a/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c b/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
index b3854e3ef9..f9124fa716 100644
--- a/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
+++ b/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
@@ -1,5 +1,5 @@
/* vsprintf with automatic memory allocation.
- Copyright (C) 1999, 2002-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,7 +41,14 @@
DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
- DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
+ DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t.
+ ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
+ ENABLE_WCHAR_FALLBACK Set to 1 to avoid EILSEQ during conversion of wide
+ characters (wchar_t) and wide character strings
+ (wchar_t[]) to multibyte sequences. The fallback is the
+ hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
+ if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
+ */
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
This must come before <config.h> because <config.h> may include
@@ -87,6 +94,7 @@
/* Checked size_t computations. */
#include "xsize.h"
+#include "attribute.h"
#include "verify.h"
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
@@ -118,14 +126,6 @@
# include "fpucw.h"
#endif
-#ifndef FALLTHROUGH
-# if __GNUC__ < 7
-# define FALLTHROUGH ((void) 0)
-# else
-# define FALLTHROUGH __attribute__ ((__fallthrough__))
-# endif
-#endif
-
/* Default parameters. */
#ifndef VASNPRINTF
# if WIDE_CHAR_VERSION
@@ -277,6 +277,74 @@ local_wcsnlen (const wchar_t *s, size_t maxlen)
# endif
#endif
+#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
+# if ENABLE_WCHAR_FALLBACK
+static size_t
+wctomb_fallback (char *s, wchar_t wc)
+{
+ static char hex[16] = "0123456789ABCDEF";
+
+ s[0] = '\\';
+ if (sizeof (wchar_t) > 2 && wc > 0xffff)
+ {
+# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
+ s[1] = 'U';
+# else
+ s[1] = 'W';
+# endif
+ s[2] = hex[(wc & 0xf0000000U) >> 28];
+ s[3] = hex[(wc & 0xf000000U) >> 24];
+ s[4] = hex[(wc & 0xf00000U) >> 20];
+ s[5] = hex[(wc & 0xf0000U) >> 16];
+ s[6] = hex[(wc & 0xf000U) >> 12];
+ s[7] = hex[(wc & 0xf00U) >> 8];
+ s[8] = hex[(wc & 0xf0U) >> 4];
+ s[9] = hex[wc & 0xfU];
+ return 10;
+ }
+ else
+ {
+# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
+ s[1] = 'u';
+# else
+ s[1] = 'w';
+# endif
+ s[2] = hex[(wc & 0xf000U) >> 12];
+ s[3] = hex[(wc & 0xf00U) >> 8];
+ s[4] = hex[(wc & 0xf0U) >> 4];
+ s[5] = hex[wc & 0xfU];
+ return 6;
+ }
+}
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+static size_t
+local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
+{
+ size_t count = wcrtomb (s, wc, ps);
+ if (count == (size_t)(-1))
+ count = wctomb_fallback (s, wc);
+ return count;
+}
+# else
+static int
+local_wctomb (char *s, wchar_t wc)
+{
+ int count = wctomb (s, wc);
+ if (count < 0)
+ count = wctomb_fallback (s, wc);
+ return count;
+}
+# define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
+# endif
+# else
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+# define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
+# else
+# define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
+# endif
+# endif
+#endif
+
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
/* Determine the decimal-point character according to the current locale. */
# ifndef decimal_point_char_defined
@@ -565,7 +633,8 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
/* Determine s = GMP_LIMB_BITS - integer_length (msd).
Code copied from gnulib's integer_length.c. */
-# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
+ || (__clang_major__ >= 4)
s = __builtin_clz (msd);
# else
# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
@@ -1553,16 +1622,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
switch (conversion)
{
case 'd': case 'i': case 'u':
-# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
- else
-# endif
- if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+ else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
@@ -1583,16 +1649,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'o':
-# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
- else
-# endif
- if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+ else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
@@ -1611,16 +1674,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'x': case 'X':
-# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
- else
-# endif
- if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+ else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
@@ -1686,7 +1746,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
case 'c':
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
- tmp_length = MB_CUR_MAX;
+ {
+ tmp_length = MB_CUR_MAX;
+# if ENABLE_WCHAR_FALLBACK
+ if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
+ tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
+# endif
+ }
else
# endif
tmp_length = 1;
@@ -1939,11 +2005,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
case TYPE_COUNT_LONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longint_pointer = length;
break;
-#if HAVE_LONG_LONG_INT
case TYPE_COUNT_LONGLONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
break;
-#endif
default:
abort ();
}
@@ -2405,7 +2469,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
-#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
+#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
else if (dp->conversion == 's'
# if WIDE_CHAR_VERSION
&& a.arg[dp->arg_index].type != TYPE_WIDE_STRING
@@ -2680,11 +2744,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg_end == 0)
/* Found the terminating null wide character. */
break;
-# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
- count = wcrtomb (cbuf, *arg_end, &state);
-# else
- count = wctomb (cbuf, *arg_end);
-# endif
+ count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
{
/* Cannot convert. */
@@ -2725,11 +2785,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg_end == 0)
/* Found the terminating null wide character. */
break;
-# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
- count = wcrtomb (cbuf, *arg_end, &state);
-# else
- count = wctomb (cbuf, *arg_end);
-# endif
+ count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
{
/* Cannot convert. */
@@ -2774,11 +2830,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
-# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
- count = wcrtomb (cbuf, *arg, &state);
-# else
- count = wctomb (cbuf, *arg);
-# endif
+ count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
@@ -2855,11 +2907,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
-# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
- count = wcrtomb (cbuf, *arg, &state);
-# else
- count = wctomb (cbuf, *arg);
-# endif
+ count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
@@ -2884,11 +2932,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
-# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
- count = wcrtomb (cbuf, *arg, &state);
-# else
- count = wctomb (cbuf, *arg);
-# endif
+ count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
{
/* Cannot convert. */
@@ -2924,6 +2968,210 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
# endif
}
#endif
+#if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION
+ else if (dp->conversion == 'c'
+ && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
+ {
+ /* Implement the 'lc' directive ourselves, in order to provide
+ the fallback that avoids EILSEQ. */
+ int flags = dp->flags;
+ int has_width;
+ size_t width;
+
+ has_width = 0;
+ width = 0;
+ if (dp->width_start != dp->width_end)
+ {
+ if (dp->width_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->width_arg_index].a.a_int;
+ width = arg;
+ if (arg < 0)
+ {
+ /* "A negative field width is taken as a '-' flag
+ followed by a positive field width." */
+ flags |= FLAG_LEFT;
+ width = -width;
+ }
+ }
+ else
+ {
+ const FCHAR_T *digitp = dp->width_start;
+
+ do
+ width = xsum (xtimes (width, 10), *digitp++ - '0');
+ while (digitp != dp->width_end);
+ }
+ has_width = 1;
+ }
+
+ /* %lc in vasnprintf. See the specification of fprintf. */
+ {
+ wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
+ size_t characters;
+# if !DCHAR_IS_TCHAR
+ /* This code assumes that TCHAR_T is 'char'. */
+ verify (sizeof (TCHAR_T) == 1);
+ TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */
+ DCHAR_T *tmpdst;
+ size_t tmpdst_len;
+# endif
+ size_t w;
+
+# if DCHAR_IS_TCHAR
+ if (has_width)
+# endif
+ {
+ /* Count the number of bytes. */
+ characters = 0;
+ if (arg != 0)
+ {
+ char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
+ int count;
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+ mbstate_t state;
+ memset (&state, '\0', sizeof (mbstate_t));
+# endif
+
+ count = local_wcrtomb (cbuf, arg, &state);
+ if (count < 0)
+ /* Inconsistency. */
+ abort ();
+ characters = count;
+ }
+ }
+# if DCHAR_IS_TCHAR
+ else
+ {
+ /* The number of bytes doesn't matter. */
+ characters = 0;
+ }
+# endif
+
+# if !DCHAR_IS_TCHAR
+ /* Convert the string into a piece of temporary memory. */
+ if (characters > 0) /* implies arg != 0 */
+ {
+ char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
+ int count;
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+ mbstate_t state;
+ memset (&state, '\0', sizeof (mbstate_t));
+# endif
+
+ count = local_wcrtomb (cbuf, arg, &state);
+ if (count <= 0)
+ /* Inconsistency. */
+ abort ();
+ memcpy (tmpsrc, cbuf, count);
+ }
+
+ /* Convert from TCHAR_T[] to DCHAR_T[]. */
+ tmpdst =
+ DCHAR_CONV_FROM_ENCODING (locale_charset (),
+ iconveh_question_mark,
+ tmpsrc, characters,
+ NULL,
+ NULL, &tmpdst_len);
+ if (tmpdst == NULL)
+ {
+ int saved_errno = errno;
+ if (!(result == resultbuf || result == NULL))
+ free (result);
+ if (buf_malloced != NULL)
+ free (buf_malloced);
+ CLEANUP ();
+ errno = saved_errno;
+ return NULL;
+ }
+# endif
+
+ if (has_width)
+ {
+# if ENABLE_UNISTDIO
+ /* Outside POSIX, it's preferable to compare the width
+ against the number of _characters_ of the converted
+ value. */
+ w = DCHAR_MBSNLEN (result + length, characters);
+# else
+ /* The width is compared against the number of _bytes_
+ of the converted value, says POSIX. */
+ w = characters;
+# endif
+ }
+ else
+ /* w doesn't matter. */
+ w = 0;
+
+ if (w < width && !(dp->flags & FLAG_LEFT))
+ {
+ size_t n = width - w;
+ ENSURE_ALLOCATION (xsum (length, n));
+ DCHAR_SET (result + length, ' ', n);
+ length += n;
+ }
+
+# if DCHAR_IS_TCHAR
+ if (has_width)
+ {
+ /* We know the number of bytes in advance. */
+ ENSURE_ALLOCATION (xsum (length, characters));
+ if (characters > 0) /* implies arg != 0 */
+ {
+ int count;
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+ mbstate_t state;
+ memset (&state, '\0', sizeof (mbstate_t));
+# endif
+
+ count = local_wcrtomb (result + length, arg, &state);
+ if (count <= 0)
+ /* Inconsistency. */
+ abort ();
+ length += count;
+ }
+ }
+ else
+ {
+ if (arg != 0)
+ {
+ char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
+ int count;
+# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
+ mbstate_t state;
+ memset (&state, '\0', sizeof (mbstate_t));
+# endif
+
+ count = local_wcrtomb (cbuf, arg, &state);
+ if (count <= 0)
+ /* Inconsistency. */
+ abort ();
+ ENSURE_ALLOCATION (xsum (length, count));
+ memcpy (result + length, cbuf, count);
+ length += count;
+ }
+ }
+# else
+ ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+ DCHAR_CPY (result + length, tmpdst, tmpdst_len);
+ free (tmpdst);
+ length += tmpdst_len;
+# endif
+
+ if (w < width && (dp->flags & FLAG_LEFT))
+ {
+ size_t n = width - w;
+ ENSURE_ALLOCATION (xsum (length, n));
+ DCHAR_SET (result + length, ' ', n);
+ length += n;
+ }
+ }
+ }
+#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
else if ((dp->conversion == 'a' || dp->conversion == 'A')
# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
@@ -4835,17 +5083,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
switch (type)
{
-#if HAVE_LONG_LONG_INT
case TYPE_LONGLONGINT:
case TYPE_ULONGLONGINT:
-# if defined _WIN32 && ! defined __CYGWIN__
+#if defined _WIN32 && ! defined __CYGWIN__
*fbp++ = 'I';
*fbp++ = '6';
*fbp++ = '4';
break;
-# else
+#else
*fbp++ = 'l';
-# endif
#endif
FALLTHROUGH;
case TYPE_LONGINT:
@@ -4871,39 +5117,32 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#endif
*fbp = dp->conversion;
#if USE_SNPRINTF
-# if ! (((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
- && !defined __UCLIBC__) \
- || (defined __APPLE__ && defined __MACH__) \
- || defined __ANDROID__ \
- || (defined _WIN32 && ! defined __CYGWIN__))
- fbp[1] = '%';
- fbp[2] = 'n';
- fbp[3] = '\0';
-# else
- /* On glibc2 systems from glibc >= 2.3 - probably also older
- ones - we know that snprintf's return value conforms to
- ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
- gl_SNPRINTF_TRUNCATION_C99 pass.
- Therefore we can avoid using %n in this situation.
- On glibc2 systems from 2004-10-18 or newer, the use of %n
- in format strings in writable memory may crash the program
- (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
- in this situation. */
- /* On Mac OS X 10.3 or newer, we know that snprintf's return
- value conforms to ISO C 99: the tests gl_SNPRINTF_RETVAL_C99
- and gl_SNPRINTF_TRUNCATION_C99 pass.
- Therefore we can avoid using %n in this situation.
- On Mac OS X 10.13 or newer, the use of %n in format strings
- in writable memory by default crashes the program, so we
- should avoid it in this situation. */
- /* On Android, we know that snprintf's return value conforms to
- ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
- gl_SNPRINTF_TRUNCATION_C99 pass.
- Therefore we can avoid using %n in this situation.
- Starting on 2018-03-07, the use of %n in format strings
- produces a fatal error (see
- <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>),
- so we should avoid it. */
+# if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99) \
+ || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
+ && !defined __UCLIBC__) \
+ || (defined __APPLE__ && defined __MACH__) \
+ || defined __ANDROID__ \
+ || (defined _WIN32 && ! defined __CYGWIN__))
+ /* On systems where we know that snprintf's return value
+ conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that
+ snprintf always produces NUL-terminated strings
+ (HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid
+ using %n. And it is desirable to do so, because more and
+ more platforms no longer support %n, for "security reasons".
+ In particular, the following platforms:
+ - On glibc2 systems from 2004-10-18 or newer, the use of
+ %n in format strings in writable memory may crash the
+ program (if compiled with _FORTIFY_SOURCE=2).
+ - On Mac OS X 10.13 or newer, the use of %n in format
+ strings in writable memory by default crashes the
+ program.
+ - On Android, starting on 2018-03-07, the use of %n in
+ format strings produces a fatal error (see
+ <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
+ On these platforms, HAVE_SNPRINTF_RETVAL_C99 and
+ HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them
+ explicitly in the condition above, in case of cross-
+ compilation (just to be sure). */
/* On native Windows systems (such as mingw), we can avoid using
%n because:
- Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
@@ -4920,6 +5159,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
<https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
So we should avoid %n in this situation. */
fbp[1] = '\0';
+# else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
+ fbp[1] = '%';
+ fbp[2] = 'n';
+ fbp[3] = '\0';
# endif
#else
fbp[1] = '\0';
@@ -5063,7 +5306,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
SNPRINTF_BUF (arg);
}
break;
-#if HAVE_LONG_LONG_INT
case TYPE_LONGLONGINT:
{
long long int arg = a.arg[dp->arg_index].a.a_longlongint;
@@ -5076,7 +5318,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
SNPRINTF_BUF (arg);
}
break;
-#endif
case TYPE_DOUBLE:
{
double arg = a.arg[dp->arg_index].a.a_double;