[newlib-cygwin/cygwin-3_3-branch] ldtoa: don't restrict outbuf size to ndigits
Corinna Vinschen
corinna@sourceware.org
Mon Nov 22 12:59:20 GMT 2021
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=dda1874380312b440b613343ed032eb5f7db964e
commit dda1874380312b440b613343ed032eb5f7db964e
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Mon Nov 22 13:57:16 2021 +0100
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: 4d90e53359145 ("ldtoa: fix dropping too many digits from output")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
newlib/libc/stdlib/ldtoa.c | 35 +++++++++++++++++++++++++----------
winsup/cygwin/release/3.3.3 | 3 +++
2 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c
index 7da61457b..1b32e801c 100644
--- a/newlib/libc/stdlib/ldtoa.c
+++ b/newlib/libc/stdlib/ldtoa.c
@@ -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';
diff --git a/winsup/cygwin/release/3.3.3 b/winsup/cygwin/release/3.3.3
index a35c88b97..908ebe402 100644
--- a/winsup/cygwin/release/3.3.3
+++ b/winsup/cygwin/release/3.3.3
@@ -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
More information about the Cygwin-cvs
mailing list