+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.
/* 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));
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));
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
#include "macros.h"
}
}
#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
}
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
#include "macros.h"
}
}
#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
}
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
#include "macros.h"
#include "minus-zero.h"
}
#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. */
{
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
#include "macros.h"
#include "minus-zero.h"
}
}
#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