From: Markus Wichmann <nullplan@gmx.net>
To: musl@lists.openwall.com
Cc: Michal Terepeta <michalt@google.com>,
t5y-external <t5y-external@google.com>
Subject: Re: [musl] Wrong formatting of doubles?
Date: Tue, 1 Jul 2025 19:22:20 +0200 [thread overview]
Message-ID: <aGQZTCr_HtSIofwP@voyager> (raw)
In-Reply-To: <20250701163758.GD1827@brightrain.aerifal.cx>
Am Tue, Jul 01, 2025 at 12:37:58PM -0400 schrieb Rich Felker:
> On Tue, Jul 01, 2025 at 12:19:57PM -0400, Rich Felker wrote:
> > On Tue, Jul 01, 2025 at 10:22:25AM -0400, Rich Felker wrote:
> > > static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps)
> > > {
> > > - int bufsize = (ps==BIGLPRE)
> > > - ? (LDBL_MANT_DIG+28)/29 + 1 + // mantissa expansion
> > > - (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9 // exponent expansion
> > > - : (DBL_MANT_DIG+28)/29 + 1 +
> > > - (DBL_MAX_EXP+DBL_MANT_DIG+28+8)/9;
> > > + int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG;
> > > + int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP;
> > > + int bufsize = (max_mant_dig+28)/29 + 1 // mantissa expansion
> > > + + (max_exp+max_mant_dig+28+8)/9; // exponent expansion
> > > uint32_t big[bufsize];
> > > uint32_t *a, *d, *r, *z;
> > > int e2=0, e, i, j, l;
> > > @@ -266,7 +265,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps)
> > > if (y) y *= 0x1p28, e2-=28;
> > >
> > > if (e2<0) a=r=z=big;
> > > - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
> > > + else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_dig - 1;
> > >
> > > do {
> > > *z = y;
I am wondering how this is causing wrong digits instead of a crash. The
only thing the above changes could prevent is an out-of-bounds access.
Well, OK, let's do some math:
DBL_MANT_DIG = 53
LDBL_MANT_DIG = 113
DBL_MAX_EXP = 1024
bufsize = 126
That only leaves 13 blocks for the exponent expansion, which is enough
for 117 decimal digits in front of the radix before a buffer overflow
occurs. Regrettably, DBL_MAX has 308 digits in front of the radix. But
that should mean that some return address gets overwritten and a crash
occurs on return, right?
With the corrected calculation, more than double the required digits can
be saved.
> > I think the correct code would be something like:
> >
> > + else a=r=z=big+sizeof(big)/sizeof(*big) - (max_mant_dig+28)/29 - 1;
>
> An additional -1 (+1 to the # of slots for mantissa expansion, as in
> the commented expression) is needed here because the do/while loop
> emits a final zero slot for the mantissa. I'm not sure this is
> actually needed later, but as long as it's there it needs to be
> accounted for.
>
> And indeed, with some debug instrumentation, empirically
> z==buf+bufsize after the initial mantissa expansion loop finishes.
>
I am also wondering if there is any need for the calculation to be exact
in this case. The buffer size is as big as it is for negative exponents,
and for positive ones it really doesn't matter, since the decimal
expansion can never be big enough to fill the whole buffer. So the only
thing this changes is where exactly the data is inside the buffer, which
doesn't seem like a worthwhile change to me.
Ciao,
Markus
next prev parent reply other threads:[~2025-07-01 17:22 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-01 5:55 Wrong formatting of doubles? Michal Terepeta
2025-07-01 14:22 ` [musl] " Rich Felker
2025-07-01 16:19 ` Rich Felker
2025-07-01 16:37 ` Rich Felker
2025-07-01 17:02 ` Jeffrey Walton
2025-07-01 17:22 ` Markus Wichmann [this message]
2025-07-01 17:34 ` Rich Felker
2025-07-02 1:46 ` Rich Felker
2025-07-02 7:56 ` [musl] " Michal Terepeta
2025-07-08 7:43 ` Michal Terepeta
2025-07-08 16:22 ` [musl] " Rich Felker
2025-07-02 14:58 ` Rich Felker
2025-07-03 4:31 ` Markus Wichmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aGQZTCr_HtSIofwP@voyager \
--to=nullplan@gmx.net \
--cc=michalt@google.com \
--cc=musl@lists.openwall.com \
--cc=t5y-external@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).