Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 6 Sep 2022 10:17:36 -0400
From: Rich Felker <dalias@...c.org>
To: Gabriel Ravier <gabravier@...il.com>
Cc: musl@...ts.openwall.com, Joakim Sindholt <opensource@...sha.com>
Subject: Re: ecvt(0, 0, ...) is broken

On Tue, Sep 06, 2022 at 02:21:52PM +0200, Gabriel Ravier wrote:
> On 9/6/22 14:13, Joakim Sindholt wrote:
> >On Tue, 6 Sep 2022 12:12:48 +0200, Gabriel Ravier <gabravier@...il.com> wrote:
> >>Executing ecvt(0, 0, &decpt, &sign) results in musl returning
> >>"000000000000000".
> >>
> >>This seems highly likely to be a bug considering that glibc returns ""
> >>and I see no plausible reasoning for musl's behavior that could be
> >>justified by the standard.
> >POSIX.1-2001 said:
> >>The ecvt() function shall convert value to a null-terminated string of
> >>ndigit digits (where ndigit is reduced to an unspecified limit
> >>determined by the precision of a double) and return a pointer to the
> >>string. The high-order digit shall be non-zero, unless the value is 0.
> >The first part would imply that ndigit=0 should return the string "" but
> >the second part makes no provision for a zero-digit-long string.
> >I would say ndigit=0 is UB.
> Wouldn't that then mean that any request call of fcvt with a small
> ndigits but very small value that isn't 0, as in my previous email,
> would also be UB (since if my logic is correct, the string cannot
> start with a 0 but it also cannot start with any other value, which
> forces it to be empty) ? That seems rather excessive...

These functions are highly underspecified but have been obsolete and
deprecated for decades and there is really no plausible motivation for
using them. So I don't see much value in language-lawyering over them.

I don't see how the condition on ecvt implies ndigit==0 is UB.

    "The high-order digit shall be non-zero, unless the value is 0"

arguably is undefined in the case where there is no high-order digit,
but imposes no requirements if the value is zero. However this reading
depends a lot on phrasing and how the phrasing interacts with vacuous
conditions, which was probably not the intent.

I think it would be perfectly fine to fix ecvt to return "" when
ndigit==0. I don't see any way the fcvt case is well-defined though.
There are just conflicting requirements. The number of characters in
the resulting string is not allowed to be fewer than specified just
because it conflicts with the leading digit condition.

We're not going to get an interpretation on this because the functions
were removed from POSIX over a decade ago. I guess someone who really
cares about it could research the original Unix implementations and
what they did and if there was any rhyme or reason to it, and make a
proposal to align with that. But these are garbage functions. The
right answer is to fix whatever is using them to use snprintf and move
on.

Rich


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.