possible snprintf() regression in 3.3.2

Takashi Yano takashi.yano@nifty.ne.jp
Thu Nov 18 11:35:38 GMT 2021


On Thu, 18 Nov 2021 11:06:49 +1100
Tony Cook wrote:
> On Wed, Nov 17, 2021 at 01:27:55PM +0100, Corinna Vinschen via Cygwin wrote:
> > I don't have a good solution.  The old ldtoa code is lacking, for
> > switching newlib to gdtoa I simply don't have the time.  On the newlib
> > list was a short discussion starting at
> > https://sourceware.org/pipermail/newlib/2021/018626.html but nothing
> > came out of it yet.
> > 
> > Patches gratefully accepted (except just reverting the above change).
> 
> From what I can tell the problem has nothing to do with the extra
> precision, but has to do with misusing ndigits for the buffer size
> with a %f format string, leading to a buffer overflow.
> 
> At entry to _ldtoa_r() ndigits is 9, but for a %f format with a large
> number the number of digits is more closely related to the magnitude
> of the number, not ndigits.
> 
> With the input number (9e99) and the supplied format I'd expect 109
> characters output, but outbuf is only:
> 
>    ndigits + MAX_EXP_DIGITS + 10 = 9 + 5 + 10 = 24
> 
> characters in length.

Then, isn't the following the right thing?

diff --git a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c
index 7da61457b..826a1b2ed 100644
--- a/newlib/libc/stdlib/ldtoa.c
+++ b/newlib/libc/stdlib/ldtoa.c
@@ -2794,6 +2794,7 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
   LDPARMS rnd;
   LDPARMS *ldp = &rnd;
   char *outstr;
+  char outbuf[NDEC + MAX_EXP_DIGITS + 10];
   union uconv du;
   du.d = d;
 
@@ -2840,8 +2841,6 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
   if (ndigits > NDEC)
     ndigits = NDEC;
 
-  char outbuf[ndigits + MAX_EXP_DIGITS + 10];
-
   etoasc (e, outbuf, ndigits, mode, ldp);
   s = outbuf;
   if (eisinf (e) || eisnan (e))


-- 
Takashi Yano <takashi.yano@nifty.ne.jp>


More information about the Cygwin mailing list