Ciao Vincent,

15 dic 2023, 13:26 da vinc...@vinc17.net:

> Note that there are similar issues in printf/repl-vsnprintf.c, and I
>

I finally had the time to examine the code and test it. I attach a proposed 
patch.

I changed the 3 files: printf/doprntf.c, printf/repl-vsnprintf.c, 
printf/sprintffuns.c, to use the returned value of the called functions, 
instead of calling strlen on the string.

I also slightly changed the tests, to check at least one case with "%c", 0.
For this to work I also had to change a
-  (*__gmp_free_func) (got, strlen(got)+1);
+  (*__gmp_free_func) (got, got_len+1);
When the string comes from a generic print, it is safer to relay on the return 
value than on the length computed by strlen()...


> think that this is the cause of the MPFR failure with MS Visual C++
> (vsnprintf is used by gmp_vasprintf).
>
If you can also test on that side, let me know. Thanks!

Gis,
m

diff -r 1c566525476a printf/doprntf.c
--- a/printf/doprntf.c	Wed Dec 27 19:35:36 2023 +0100
+++ b/printf/doprntf.c	Sun Feb 18 12:17:18 2024 +0100
@@ -267,8 +267,7 @@
 	 mean truncation */
       ASSERT (explen >= 0 && explen < sizeof(exponent)-1);
 #else
-      sprintf (exponent, p->expfmt, expsign, expval);
-      explen = strlen (exponent);
+      explen = sprintf (exponent, p->expfmt, expsign, expval);
       ASSERT (explen < sizeof(exponent));
 #endif
       TRACE (printf ("  expfmt %s gives %s\n", p->expfmt, exponent));
diff -r 1c566525476a printf/repl-vsnprintf.c
--- a/printf/repl-vsnprintf.c	Wed Dec 27 19:35:36 2023 +0100
+++ b/printf/repl-vsnprintf.c	Sun Feb 18 12:17:18 2024 +0100
@@ -364,16 +364,14 @@
 
   if (total_width <= buf_size)
     {
-      vsprintf (buf, orig_fmt, orig_ap);
-      len = strlen (buf);
+      len = vsprintf (buf, orig_fmt, orig_ap);
     }
   else
     {
       char  *s;
 
       s = __GMP_ALLOCATE_FUNC_TYPE (total_width, char);
-      vsprintf (s, orig_fmt, orig_ap);
-      len = strlen (s);
+      len = vsprintf (s, orig_fmt, orig_ap);
       if (buf_size != 0)
 	{
 	  size_t  copylen = MIN (len, buf_size-1);
diff -r 1c566525476a printf/sprintffuns.c
--- a/printf/sprintffuns.c	Wed Dec 27 19:35:36 2023 +0100
+++ b/printf/sprintffuns.c	Sun Feb 18 12:17:18 2024 +0100
@@ -53,9 +53,9 @@
 {
   char  *buf = *bufp;
   int   ret;
-  vsprintf (buf, fmt, ap);
-  ret = strlen (buf);
-  *bufp = buf + ret;
+  ret = vsprintf (buf, fmt, ap);
+  if (ret > 0)
+    *bufp = buf + ret;
   return ret;
 }
 
diff -r 1c566525476a tests/misc/t-printf.c
--- a/tests/misc/t-printf.c	Wed Dec 27 19:35:36 2023 +0100
+++ b/tests/misc/t-printf.c	Sun Feb 18 12:17:18 2024 +0100
@@ -128,12 +128,11 @@
 }
 
 void
-check_vsprintf (const char *want, const char *fmt, va_list ap)
+check_vsprintf (const char *want, int want_len, const char *fmt, va_list ap)
 {
   char  got[MAX_OUTPUT];
-  int   got_len, want_len;
+  int   got_len;
 
-  want_len = strlen (want);
   got_len = gmp_vsprintf (got, fmt, ap);
 
   if (got_len != want_len || strcmp (got, want) != 0)
@@ -149,14 +148,12 @@
 }
 
 void
-check_vfprintf (const char *want, const char *fmt, va_list ap)
+check_vfprintf (const char *want, int want_len, const char *fmt, va_list ap)
 {
   char  got[MAX_OUTPUT];
-  int   got_len, want_len, fread_len;
+  int   got_len, fread_len;
   long  ftell_len;
 
-  want_len = strlen (want);
-
   rewind (check_vfprintf_fp);
   got_len = gmp_vfprintf (check_vfprintf_fp, fmt, ap);
   ASSERT_ALWAYS (got_len != -1);
@@ -187,14 +184,12 @@
 }
 
 void
-check_vsnprintf (const char *want, const char *fmt, va_list ap)
+check_vsnprintf (const char *want, int want_len, const char *fmt, va_list ap)
 {
   char    got[MAX_OUTPUT+1];
-  int     ret, got_len, want_len;
+  int     ret, got_len;
   size_t  bufsize;
 
-  want_len = strlen (want);
-
   bufsize = -1;
   for (;;)
     {
@@ -243,12 +238,11 @@
 }
 
 void
-check_vasprintf (const char *want, const char *fmt, va_list ap)
+check_vasprintf (const char *want, int want_len, const char *fmt, va_list ap)
 {
   char  *got;
-  int   got_len, want_len;
+  int   got_len;
 
-  want_len = strlen (want);
   got_len = gmp_vasprintf (&got, fmt, ap);
 
   if (got_len != want_len || strcmp (got, want) != 0)
@@ -261,19 +255,17 @@
       printf ("  want_len %d\n", want_len);
       abort ();
     }
-  (*__gmp_free_func) (got, strlen(got)+1);
+  (*__gmp_free_func) (got, got_len+1);
 }
 
 void
-check_obstack_vprintf (const char *want, const char *fmt, va_list ap)
+check_obstack_vprintf (const char *want, int want_len, const char *fmt, va_list ap)
 {
 #if HAVE_OBSTACK_VPRINTF
   struct obstack  ob;
-  int   got_len, want_len, ob_len;
+  int   got_len, ob_len;
   char  *got;
 
-  want_len = strlen (want);
-
   obstack_init (&ob);
   got_len = gmp_obstack_vprintf (&ob, fmt, ap);
   got = (char *) obstack_base (&ob);
@@ -300,15 +292,30 @@
 void
 check_one (const char *want, const char *fmt, ...)
 {
+  int want_len = strlen (want);
   va_list ap;
   va_start (ap, fmt);
 
   /* simplest first */
-  check_vsprintf (want, fmt, ap);
-  check_vfprintf (want, fmt, ap);
-  check_vsnprintf (want, fmt, ap);
-  check_vasprintf (want, fmt, ap);
-  check_obstack_vprintf (want, fmt, ap);
+  check_vsprintf (want, want_len, fmt, ap);
+  check_vfprintf (want, want_len, fmt, ap);
+  check_vsnprintf (want, want_len, fmt, ap);
+  check_vasprintf (want, want_len, fmt, ap);
+  check_obstack_vprintf (want, want_len, fmt, ap);
+}
+
+void
+check_one_len (const char *want, int want_len, const char *fmt, ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+
+  /* simplest first */
+  check_vsprintf (want, want_len, fmt, ap);
+  check_vfprintf (want, want_len, fmt, ap);
+  check_vsnprintf (want, want_len, fmt, ap);
+  check_vasprintf (want, want_len, fmt, ap);
+  check_obstack_vprintf (want, want_len, fmt, ap);
 }
 
 
@@ -854,17 +861,16 @@
 check_misc (void)
 {
   mpz_t  z;
-  mpf_t  f;
 
   mpz_init (z);
-  mpf_init2 (f, 128L);
 
   check_one ("!", "%c", '!');
 
   check_one ("hello world", "hello %s", "world");
   check_one ("hello:", "%s:", "hello");
   mpz_set_ui (z, 0L);
-  check_one ("hello0", "%s%Zd", "hello", z, z);
+  check_one ("hello0", "%s%Zd", "hello", z);
+  check_one_len ("!0\0.", 4, "%c%Zd%c.", '!', z, 0);
 
   {
     static char  xs[801];
@@ -927,7 +933,6 @@
 #endif
 
   mpz_clear (z);
-  mpf_clear (f);
 }
 
 
_______________________________________________
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs

Reply via email to