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.y...@nifty.ne.jp> -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple