summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-03-21 15:49:06 +0100
committerBruno Haible <bruno@clisp.org>2023-03-21 15:58:04 +0100
commit4928ebfa61978ee1d9b79d1173cb11bcaa6f1038 (patch)
tree960de39e0a9b030c3b86f4a2ba477640df924fec /tests
parent2ccec72dcddf09e855fc300f748b0cdf91269ae4 (diff)
downloadgnulib-4928ebfa61978ee1d9b79d1173cb11bcaa6f1038.tar.gz
*printf-posix: Work around bug with %lc of 0 on many platforms.
* lib/vasnprintf.c (local_wctomb): Define also for NEED_PRINTF_DIRECTIVE_LC. (VASNPRINTF): Implement %lc handling ourselves if NEED_PRINTF_DIRECTIVE_LC. * m4/printf.m4 (gl_PRINTF_DIRECTIVE_LC): New macro. * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_LC): New macro. (gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it. * m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require gl_PRINTF_DIRECTIVE_LC and test its result. Invoke gl_PREREQ_VASNPRINTF_DIRECTIVE_LC. * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise. * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise. * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise. * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise. * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise. * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise. * m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise. * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise. * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise. * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise. * tests/test-snprintf-posix.h (test_function): Add more tests for the %c and %lc directives. * tests/test-sprintf-posix.h (test_function): Likewise. * tests/test-vasnprintf-posix.c (test_function): Likewise. * tests/test-vasprintf-posix.c (test_function): Likewise. * doc/glibc-functions/asprintf.texi: Mention the %lc 0 bug. * doc/glibc-functions/obstack_printf.texi: Likewise. * doc/glibc-functions/obstack_vprintf.texi: Likewise. * doc/glibc-functions/vasprintf.texi: Likewise. * doc/posix-functions/dprintf.texi: Likewise. * doc/posix-functions/fprintf.texi: Likewise. * doc/posix-functions/printf.texi: Likewise. * doc/posix-functions/snprintf.texi: Likewise. * doc/posix-functions/sprintf.texi: Likewise. * doc/posix-functions/vdprintf.texi: Likewise. * doc/posix-functions/vfprintf.texi: Likewise. * doc/posix-functions/vprintf.texi: Likewise. * doc/posix-functions/vsnprintf.texi: Likewise. * doc/posix-functions/vsprintf.texi: Likewise.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-snprintf-posix.h35
-rw-r--r--tests/test-sprintf-posix.h31
-rw-r--r--tests/test-vasnprintf-posix.c41
-rw-r--r--tests/test-vasprintf-posix.c39
4 files changed, 146 insertions, 0 deletions
diff --git a/tests/test-snprintf-posix.h b/tests/test-snprintf-posix.h
index 579d34583d..05c7be8059 100644
--- a/tests/test-snprintf-posix.h
+++ b/tests/test-snprintf-posix.h
@@ -3024,6 +3024,22 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
ASSERT (retval == strlen (result));
}
+ { /* Precision is ignored. */
+ int retval =
+ my_snprintf (result, sizeof (result),
+ "%.0c %d", (unsigned char) 'x', 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NUL character. */
+ int retval =
+ my_snprintf (result, sizeof (result),
+ "a%cz %d", '\0', 33, 44, 55);
+ ASSERT (memcmp (result, "a\0z 33\0", 6 + 1) == 0);
+ ASSERT (retval == 6);
+ }
+
#if HAVE_WCHAR_T
static wint_t L_x = (wchar_t) 'x';
@@ -3054,6 +3070,25 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
ASSERT (strcmp (result, "x 33") == 0);
ASSERT (retval == strlen (result));
}
+
+ { /* Precision is ignored. */
+ int retval =
+ my_snprintf (result, sizeof (result),
+ "%.0lc %d", L_x, 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NUL character. */
+ int retval =
+ my_snprintf (result, sizeof (result),
+ "a%lcz %d", (wint_t) L'\0', 33, 44, 55);
+ /* No NUL byte between 'a' and 'z'. This is surprising, but is a
+ consequence of how POSIX:2018 and ISO C 23 specify the handling
+ of %lc. */
+ ASSERT (memcmp (result, "az 33\0", 5 + 1) == 0);
+ ASSERT (retval == 5);
+ }
#endif
/* Test the support of the 'b' conversion specifier for binary output of
diff --git a/tests/test-sprintf-posix.h b/tests/test-sprintf-posix.h
index 863d084b99..d745a1109b 100644
--- a/tests/test-sprintf-posix.h
+++ b/tests/test-sprintf-posix.h
@@ -3006,6 +3006,20 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
ASSERT (retval == strlen (result));
}
+ { /* Precision is ignored. */
+ int retval =
+ my_sprintf (result, "%.0c %d", (unsigned char) 'x', 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NUL character. */
+ int retval =
+ my_sprintf (result, "a%cz %d", '\0', 33, 44, 55);
+ ASSERT (memcmp (result, "a\0z 33\0", 6 + 1) == 0);
+ ASSERT (retval == 6);
+ }
+
#if HAVE_WCHAR_T
static wint_t L_x = (wchar_t) 'x';
@@ -3036,6 +3050,23 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
ASSERT (strcmp (result, "x 33") == 0);
ASSERT (retval == strlen (result));
}
+
+ { /* Precision is ignored. */
+ int retval =
+ my_sprintf (result, "%.0lc %d", L_x, 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* NUL character. */
+ int retval =
+ my_sprintf (result, "a%lcz %d", (wint_t) L'\0', 33, 44, 55);
+ /* No NUL byte between 'a' and 'z'. This is surprising, but is a
+ consequence of how POSIX:2018 and ISO C 23 specify the handling
+ of %lc. */
+ ASSERT (memcmp (result, "az 33\0", 5 + 1) == 0);
+ ASSERT (retval == 5);
+ }
#endif
/* Test the support of the 'b' conversion specifier for binary output of
diff --git a/tests/test-vasnprintf-posix.c b/tests/test-vasnprintf-posix.c
index c6e1e2f650..ecbb8bcda0 100644
--- a/tests/test-vasnprintf-posix.c
+++ b/tests/test-vasnprintf-posix.c
@@ -3932,6 +3932,26 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
free (result);
}
+ { /* Precision is ignored. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length,
+ "%.0c %d", (unsigned char) 'x', 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NUL character. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length,
+ "a%cz %d", '\0', 33, 44, 55);
+ ASSERT (memcmp (result, "a\0z 33\0", 6 + 1) == 0);
+ ASSERT (length == 6);
+ free (result);
+ }
+
#if HAVE_WCHAR_T
static wint_t L_x = (wchar_t) 'x';
@@ -3974,6 +3994,27 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
ASSERT (length == strlen (result));
free (result);
}
+
+ { /* Precision is ignored. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0lc %d", L_x, 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* NUL character. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "a%lcz %d", (wint_t) L'\0', 33, 44, 55);
+ /* No NUL byte between 'a' and 'z'. This is surprising, but is a
+ consequence of how POSIX:2018 and ISO C 23 specify the handling
+ of %lc. */
+ ASSERT (memcmp (result, "az 33\0", 5 + 1) == 0);
+ ASSERT (length == 5);
+ free (result);
+ }
#endif
/* Test the support of the 'b' conversion specifier for binary output of
diff --git a/tests/test-vasprintf-posix.c b/tests/test-vasprintf-posix.c
index 13b3a1bca9..46086ef251 100644
--- a/tests/test-vasprintf-posix.c
+++ b/tests/test-vasprintf-posix.c
@@ -3873,6 +3873,24 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
free (result);
}
+ { /* Precision is ignored. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0c %d", (unsigned char) 'x', 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NUL character. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "a%cz %d", '\0', 33, 44, 55);
+ ASSERT (memcmp (result, "a\0z 33\0", 6 + 1) == 0);
+ ASSERT (retval == 6);
+ free (result);
+ }
+
#if HAVE_WCHAR_T
static wint_t L_x = (wchar_t) 'x';
@@ -3915,6 +3933,27 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
ASSERT (retval == strlen (result));
free (result);
}
+
+ { /* Precision is ignored. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0lc %d", L_x, 33, 44, 55);
+ ASSERT (strcmp (result, "x 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* NUL character. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "a%lcz %d", (wint_t) L'\0', 33, 44, 55);
+ /* No NUL byte between 'a' and 'z'. This is surprising, but is a
+ consequence of how POSIX:2018 and ISO C 23 specify the handling
+ of %lc. */
+ ASSERT (memcmp (result, "az 33\0", 5 + 1) == 0);
+ ASSERT (retval == 5);
+ free (result);
+ }
#endif
/* Test the support of the 'b' conversion specifier for binary output of