]> Savannah Git Hosting - gnulib.git/commitdiff
vasnprintf-posix: Fix possible bug with negative width handling for %lc.
authorBruno Haible <bruno@clisp.org>
Sat, 28 Jan 2023 18:05:24 +0000 (19:05 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 28 Jan 2023 18:05:24 +0000 (19:05 +0100)
* lib/vasnprintf.c (VASNPRINTF): In the code for %lc in vasnprintf, test
for the FLAG_LEFT bit in the flags variable.
* tests/test-vasnprintf-posix.c (test_function): Add tests for width
given as argument for the directives %c, %lc.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* tests/test-snprintf-posix.h (test_function): Likewise.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-snprintf-posix.c: Include <wchar.h>, for wint_t.
* tests/test-sprintf-posix.c: Likewise.

ChangeLog
lib/vasnprintf.c
tests/test-snprintf-posix.c
tests/test-snprintf-posix.h
tests/test-sprintf-posix.c
tests/test-sprintf-posix.h
tests/test-vasnprintf-posix.c
tests/test-vasprintf-posix.c

index 8445c26c9fd94dd83155a7f57dfcca3a744354b8..e7cfe12ad4f161d76e51752c455efc7ac0604e44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-01-28  Bruno Haible  <bruno@clisp.org>
+
+       vasnprintf-posix: Fix possible bug with negative width handling for %lc.
+       * lib/vasnprintf.c (VASNPRINTF): In the code for %lc in vasnprintf, test
+       for the FLAG_LEFT bit in the flags variable.
+       * tests/test-vasnprintf-posix.c (test_function): Add tests for width
+       given as argument for the directives %c, %lc.
+       * tests/test-vasprintf-posix.c (test_function): Likewise.
+       * tests/test-snprintf-posix.h (test_function): Likewise.
+       * tests/test-sprintf-posix.h (test_function): Likewise.
+       * tests/test-snprintf-posix.c: Include <wchar.h>, for wint_t.
+       * tests/test-sprintf-posix.c: Likewise.
+
 2023-01-28  Bruno Haible  <bruno@clisp.org>
 
        vasnprintf-posix: Fix negative width handling for %ls directive.
index 5ab8edbab7a7dfc780ab9a57d7db662d5f845d0b..0e6220ae18c4d7021f3fe579248551eb2c593cd6 100644 (file)
@@ -2977,7 +2977,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                     /* w doesn't matter.  */
                     w = 0;
 
-                  if (w < width && !(dp->flags & FLAG_LEFT))
+                  if (w < width && !(flags & FLAG_LEFT))
                     {
                       size_t n = width - w;
                       ENSURE_ALLOCATION (xsum (length, n));
@@ -3033,7 +3033,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   length += tmpdst_len;
 # endif
 
-                  if (w < width && (dp->flags & FLAG_LEFT))
+                  if (w < width && (flags & FLAG_LEFT))
                     {
                       size_t n = width - w;
                       ENSURE_ALLOCATION (xsum (length, n));
index d8d89fcd058cf6fe98a3ea75054fab075ad8b049..3dec989d7bcf8953e4e30b8645b8ca9b3e5f852a 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
 
 #include "macros.h"
 
index e5c1d3f89d018ddbd6278490984d19f9b793f769..4db76deb7576528ba2580e2cc782414c5e7a8561 100644 (file)
@@ -2987,4 +2987,70 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
       }
   }
 #endif
+
+  /* Test the support of the %c format directive.  */
+
+  { /* Width.  */
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%*c %d", 10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%*c %d", -10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_snprintf (result, sizeof (result),
+                   "%-10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+#if HAVE_WCHAR_T
+  static wint_t L_x = (wchar_t) 'x';
+
+  { /* Width.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%10lc %d", L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%*lc %d", 10, L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%*lc %d", -10, L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_snprintf (result, sizeof (result), "%-10lc %d", L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 }
index 9404a6fc99a2bb7283904d5ab0f92f89d9b25746..54c951c72cb8476c96e69578d81f860cead5925b 100644 (file)
@@ -28,6 +28,7 @@ SIGNATURE_CHECK (sprintf, int, (char *, char const *, ...));
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
 
 #include "macros.h"
 
index 011df3b46af7c4503bed9c849adc0485bb7a9099..979254acc740194ffedf672a302b20ecc8b5bdc3 100644 (file)
@@ -2973,4 +2973,66 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
       }
   }
 #endif
+
+  /* Test the support of the %c format directive.  */
+
+  { /* Width.  */
+    int retval =
+      my_sprintf (result, "%10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_sprintf (result, "%*c %d", 10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_sprintf (result, "%*c %d", -10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_sprintf (result, "%-10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+#if HAVE_WCHAR_T
+  static wint_t L_x = (wchar_t) 'x';
+
+  { /* Width.  */
+    int retval =
+      my_sprintf (result, "%10lc %d", L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Width given as argument.  */
+    int retval =
+      my_sprintf (result, "%*lc %d", 10, L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    int retval =
+      my_sprintf (result, "%*lc %d", -10, L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+
+  { /* FLAG_LEFT.  */
+    int retval =
+      my_sprintf (result, "%-10lc %d", L_x, 33, 44, 55);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 }
index 93d2bc5a386e6d5913ae3a851974e177f30b4a35..4a83f6d243339d34aa4d25b288461eea007e49b8 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
 
 #include "macros.h"
 #include "minus-zero.h"
@@ -3883,6 +3884,96 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
   }
 #endif
 
+  /* Test the support of the %c format directive.  */
+
+  { /* Width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length,
+                    "%10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length,
+                    "%*c %d", 10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length,
+                    "%*c %d", -10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length,
+                    "%-10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+#if HAVE_WCHAR_T
+  static wint_t L_x = (wchar_t) 'x';
+
+  { /* Width.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%10lc %d", L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%*lc %d", 10, L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%*lc %d", -10, L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%-10lc %d", L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+#endif
+
 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
   /* Test that the 'I' flag is supported.  */
   {
index 3bfc18bb75a0222ef9fd116a2dfb2fec50ccde88..8563502c472543c87b06ac6dcaffc8f6ab9b59c8 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
 
 #include "macros.h"
 #include "minus-zero.h"
@@ -3827,6 +3828,92 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       }
   }
 #endif
+
+  /* Test the support of the %c format directive.  */
+
+  { /* Width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*c %d", 10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*c %d", -10, (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%-10c %d", (unsigned char) 'x', 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+#if HAVE_WCHAR_T
+  static wint_t L_x = (wchar_t) 'x';
+
+  { /* Width.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%10lc %d", L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Width given as argument.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*lc %d", 10, L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "         x 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* Negative width given as argument (cf. FLAG_LEFT below).  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%*lc %d", -10, L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+
+  { /* FLAG_LEFT.  */
+    char *result;
+    int retval =
+      my_asprintf (&result, "%-10lc %d", L_x, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "x          33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+#endif
 }
 
 static int