possible snprintf() regression in 3.3.2
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
@@ -2794,6 +2794,7 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
LDPARMS *ldp = &rnd;
+ 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 <firstname.lastname@example.org>
More information about the Cygwin