Paul Eggert wrote:
> The simplest fix was to use snprintf only if it handles
> sizes like INT_MAX + 1u, and to fall back on sprintf otherwise.

This causes a test failure on Solaris 11 OmniOS:

FAIL: test-vasnprintf-posix2.sh

The failing test case is at test-vasnprintf-posix2.c:448. It causes
an abort() here:

#if !USE_SNPRINTF
                    if (count >= tmp_length)
                      /* tmp_length was incorrectly calculated - fix the
                         code above!  */
                      abort ();
#endif

This patch fixes it.


2026-07-13  Bruno Haible  <[email protected]>

        vasnprintf: Fix test failure on Solaris 11 OmniOS (regr. 2026-07-06).
        * lib/vasnprintf.c (THOUSEP_MAXLEN): New macro.
        (MAX_ROOM_NEEDED, VASNPRINTF): Use it for the estimate for FLAG_GROUP.

diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 60d3c8bda1..1b5b5b4764 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1892,6 +1892,13 @@ is_borderline (const char *digits, size_t precision)
 #  define MAX_ROOM_NEEDED max_room_needed
 # endif
 
+/* Maximum number of units needed for a thousands separator.  */
+# if WIDE_CHAR_VERSION
+#  define THOUSEP_MAXLEN THOUSEP_WCHAR_MAXLEN
+# else
+#  define THOUSEP_MAXLEN THOUSEP_CHAR_MAXLEN
+# endif
+
 /* Returns the number of TCHAR_T units needed as temporary space for the result
    of sprintf or SNPRINTF of a single conversion directive.  */
 static size_t
@@ -2061,11 +2068,7 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
         {
           /* A thousands separator needs to be inserted at most every 2 digits.
              This is the case in the ta_IN locale.  */
-# if WIDE_CHAR_VERSION
-          tmp_length = xsum (tmp_length, tmp_length / 2 * 
THOUSEP_WCHAR_MAXLEN);
-# else
-          tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN);
-# endif
+          tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_MAXLEN);
         }
       /* Add 1, to account for a leading sign.  */
       tmp_length = xsum (tmp_length, 1);
@@ -2325,7 +2328,8 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
         tmp_length =
           (unsigned int) (LDBL_MAX_EXP
                           * 0.30103 /* binary -> decimal */
-                          * 0.5 * 3 /* estimate for FLAG_GROUP */
+                          /* estimate for FLAG_GROUP */
+                          * (1.0 + 0.5 * THOUSEP_MAXLEN)
                          )
           + 1 /* turn floor into ceil */
           + 10; /* sign, decimal point etc. */
@@ -2333,7 +2337,8 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
         tmp_length =
           (unsigned int) (DBL_MAX_EXP
                           * 0.30103 /* binary -> decimal */
-                          * 0.5 * 3 /* estimate for FLAG_GROUP */
+                          /* estimate for FLAG_GROUP */
+                          * (1.0 + 0.5 * THOUSEP_MAXLEN)
                          )
           + 1 /* turn floor into ceil */
           + 10; /* sign, decimal point etc. */
@@ -2345,7 +2350,8 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, 
FCHAR_T conversion,
         12; /* sign, decimal point, exponent etc. */
       tmp_length = xsum (tmp_length,
                          precision
-                         * 0.5 * 3 /* estimate for FLAG_GROUP */
+                         /* estimate for FLAG_GROUP */
+                         * (1.0 + 0.5 * THOUSEP_MAXLEN)
                         );
       break;
 
@@ -5005,11 +5011,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   {
                     /* A thousands separator needs to be inserted at most 
every 2 digits.
                        This is the case in the ta_IN locale.  */
-# if WIDE_CHAR_VERSION
-                    tmp_length = xsum (tmp_length, tmp_length / 2 * 
THOUSEP_WCHAR_MAXLEN);
-# else
-                    tmp_length = xsum (tmp_length, tmp_length / 2 * 
THOUSEP_CHAR_MAXLEN);
-# endif
+                    tmp_length = xsum (tmp_length, tmp_length / 2 * 
THOUSEP_MAXLEN);
                   }
                 /* Account for sign, decimal point etc. */
                 tmp_length = xsum (tmp_length, 12);




Reply via email to