ldtoa: don't restrict outbuf size to ndigits
https://cygwin.com/pipermail/cygwin/2021-November/249930.html
reported a regression introduce by using a dynamically sized local
char array in favor of a statically sized array.
Fix this by reverting to a statically sized array, using a small
buffer on the stack for a reasonable number of requested digits, a
big mallocated buffer otherwise. This should work for small targets
as well, given that malloc is used in printf anyway right now.
This is *still* hopefully just a temporary measure, unless somebody
actually provides a new ldtoa.
Fixes: 4d90e53359
("ldtoa: fix dropping too many digits from output")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
4889390c3f
commit
dda1874380
|
@ -33,10 +33,10 @@ void _IO_ldtostr (long double *, char *, int, int, char);
|
|||
/* Number of bits of precision */
|
||||
#define NBITS ((NI-4)*16)
|
||||
|
||||
/* Maximum number of decimal digits in ASCII conversion
|
||||
* Take full possible size of output into account
|
||||
*/
|
||||
/* Maximum number of decimal digits in ASCII conversion */
|
||||
#define NDEC 1023
|
||||
/* Use static stack buffer for up to 44 digits */
|
||||
#define NDEC_SML 44
|
||||
|
||||
/* The exponent of 1.0 */
|
||||
#define EXONE (0x3fff)
|
||||
|
@ -2794,6 +2794,8 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
|
|||
LDPARMS rnd;
|
||||
LDPARMS *ldp = &rnd;
|
||||
char *outstr;
|
||||
char outbuf_sml[NDEC_SML + MAX_EXP_DIGITS + 10];
|
||||
char *outbuf = outbuf_sml;
|
||||
union uconv du;
|
||||
du.d = d;
|
||||
|
||||
|
@ -2836,11 +2838,22 @@ _ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits,
|
|||
ndigits = 20;
|
||||
|
||||
/* This sanity limit must agree with the corresponding one in etoasc, to
|
||||
keep straight the returned value of outexpon. */
|
||||
keep straight the returned value of outexpon. Note that we use a dynamic
|
||||
limit now, either NDEC or NDEC_SML, depending on ndigits. See the usage
|
||||
of "my_NDEC" in etoasc. */
|
||||
if (ndigits > NDEC)
|
||||
ndigits = NDEC;
|
||||
|
||||
char outbuf[ndigits + MAX_EXP_DIGITS + 10];
|
||||
/* Allocate buffer if more than NDEC_SML digits are requested. */
|
||||
if (ndigits > NDEC_SML)
|
||||
{
|
||||
outbuf = (char *) _malloc_r (ptr, NDEC + MAX_EXP_DIGITS + 10);
|
||||
if (!outbuf)
|
||||
{
|
||||
ndigits = NDEC_SML;
|
||||
outbuf = outbuf_sml;
|
||||
}
|
||||
}
|
||||
|
||||
etoasc (e, outbuf, ndigits, mode, ldp);
|
||||
s = outbuf;
|
||||
|
@ -2933,6 +2946,9 @@ stripspaces:
|
|||
if (rve)
|
||||
*rve = outstr + (s - outbuf);
|
||||
|
||||
if (outbuf != outbuf_sml)
|
||||
_free_r (ptr, outbuf);
|
||||
|
||||
return outstr;
|
||||
}
|
||||
|
||||
|
@ -2987,6 +3003,7 @@ etoasc (short unsigned int *x, char *string, int ndigits, int outformat,
|
|||
char *s, *ss;
|
||||
unsigned short m;
|
||||
unsigned short *equot = ldp->equot;
|
||||
int my_NDEC = (ndigits > NDEC_SML) ? NDEC : NDEC_SML;
|
||||
|
||||
ndigs = ndigits;
|
||||
rndsav = ldp->rndprc;
|
||||
|
@ -3112,9 +3129,7 @@ tnzro:
|
|||
else
|
||||
{
|
||||
emovi (y, w);
|
||||
/* Note that this loop does not access the incoming string array,
|
||||
* which may be shorter than NDEC + 1 bytes! */
|
||||
for (i = 0; i < NDEC + 1; i++)
|
||||
for (i = 0; i < my_NDEC + 1; i++)
|
||||
{
|
||||
if ((w[NI - 1] & 0x7) != 0)
|
||||
break;
|
||||
|
@ -3190,8 +3205,8 @@ isone:
|
|||
else if( ndigs < 0 )
|
||||
ndigs = 0;
|
||||
*/
|
||||
if (ndigs > NDEC)
|
||||
ndigs = NDEC;
|
||||
if (ndigs > my_NDEC)
|
||||
ndigs = my_NDEC;
|
||||
if (digit == 10)
|
||||
{
|
||||
*s++ = '1';
|
||||
|
|
|
@ -34,3 +34,6 @@ Bug Fixes
|
|||
|
||||
- Fix two bugs in raise(2).
|
||||
Addresses: https://cygwin.com/pipermail/cygwin/2021-November/249973.html
|
||||
|
||||
- Fix regression in printf introduced with Cygwin 3.3.2.
|
||||
Addresses: https://cygwin.com/pipermail/cygwin/2021-November/249930.html
|
||||
|
|
Loading…
Reference in New Issue