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