Re: major formatted output function bug with %c and the value 0

2023-12-13 Thread marco . bodrato
Ciao,

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

> On 2023-12-03 20:19:10 +0100, Vincent Lefevre wrote:
>
>> With GMP 6.3.0, the formatted output functions do not handle %c
>> with the value 0 correctly. For gmp_sprintf, the return value is
>> incorrect.
>>
> In printf/sprintffuns.c, function gmp_sprintf_format(), I suppose that
>
>  vsprintf (buf, fmt, ap);
>  ret = strlen (buf);
>
> should actually be something like
>
>  ret = vsprintf (buf, fmt, ap);
>  if (ret < 0)
>  ret = 0;
>
> to avoid issues due to non-terminating null characters (not tested).
>
It was changed in 2001, probably a workaround, because the comment was
"Don't use sprintf return   value (it's a pointer on SunOS 4)"
https://gmplib.org/repo/gmp/rev/0889877bb94a

Maybe we should simply "revert" that change, and use the return value both from 
sprintf (in printf/doprntf.c) and from vsprintf (in printf/sprintffuns.c)?

Or, if we care not to modify the pointer bufp, we can use something like the 
following:
diff -r f6073853d16a printf/sprintffuns.c
--- a/printf/sprintffuns.c  Mon Oct 16 08:16:06 2023 +0200
+++ b/printf/sprintffuns.c  Wed Dec 13 19:53:50 2023 +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;
}
 
It passes the test suite, but I didn't really think about what it does.

Ĝis,
mb
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs


Re: major formatted output function bug with %c and the value 0

2023-12-13 Thread Vincent Lefevre
On 2023-12-03 20:19:10 +0100, Vincent Lefevre wrote:
> With GMP 6.3.0, the formatted output functions do not handle %c
> with the value 0 correctly. For gmp_sprintf, the return value is
> incorrect.

In printf/sprintffuns.c, function gmp_sprintf_format(), I suppose that

  vsprintf (buf, fmt, ap);
  ret = strlen (buf);

should actually be something like

  ret = vsprintf (buf, fmt, ap);
  if (ret < 0)
ret = 0;

to avoid issues due to non-terminating null characters (not tested).

But I'm wondering how an error is possibly detected. The comment is:

/* If vsprintf returns -1 then pass it upwards.  It doesn't matter that
   "*bufp" is ruined in this case, since gmp_doprint will bail out
   immediately anyway.  */

> For gmp_asprintf and gmp_vasprintf, this is either a buffer overflow
> (according to the GMP manual: "The block will be the size of the
> string and null-terminator.") or, in case this is an error in the
> GMP manual, possible memory corruption when freeing the allocated
> memory, if the custom memory allocation function cares about the
> size parameter.

This should be checked and the GMP manual should be fixed.

> 
> Testcase for gmp_sprintf:
> 
> 
> #include 
> #include 
> 
> static void test (int flag)
> {
>   char s[3] = { 1, 1, 1 };
>   int r;
> 
>   r = (flag ? sprintf : gmp_sprintf) (s, "%c", 0);
>   printf ("%4s: r = %d, s = { %d %d %d }\n",
>   flag ? "libc" : "gmp", r, s[0], s[1], s[2]);
> }
> 
> int main (void)
> {
>   test (0);
>   test (1);
>   return 0;
> }
> 
> 
> which currently gives:
> 
>  gmp: r = 0, s = { 0 0 1 }
> libc: r = 1, s = { 0 0 1 }
> 
> MPFR has various issues concerning %c with the value 0, but an
> attempt to fix them fails due to
> 
>   length = gmp_vasprintf (...);
> [...]
>   mpfr_free_str (s);
> 
> which is similar to GMP's tests/misc/t-printf.c file, which contains
> 
>   got_len = gmp_vasprintf (, fmt, ap);
> [...]
>   (*__gmp_free_func) (got, strlen(got)+1);
> 
> But replacing
> 
>   mpfr_free_str (s);
> 
> by
> 
>   mpfr_free_func (s, length + 1);
> 
> i.e. using the return value length instead of strlen(s), also fails.
> I suppose that this is related to the incorrect return value.

Well, the failure was due to another mpfr_free_func, no longer this
one (I've now completely fixed MPFR, I think).

-- 
Vincent Lefèvre  - Web: 
100% accessible validated (X)HTML - Blog: 
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
___
gmp-bugs mailing list
gmp-bugs@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-bugs