Re: [PATCH] scanf.3: Do not mention the ERANGE error

Alejandro Colomar
2022-12-29T10:47:33Z

[-- Attachment #1.1: Type: text/plain, Size: 5528 bytes --]

Hi Zack,

On 12/29/22 07:39, Zack Weinberg wrote:
>> Yeah, if you have plans to fix it, I'm fine removing the deprecation now. :)
>
> To be clear, I personally don’t have plans to do any of the actual
> programming or standard-changing work involved here. :-)

Ah, no, I meant more that the whole set of glibc maintainers had that in mind,
as a long term plan (like 10 years maybe?). If you don't think these functions
will be saved (even if we can) because it's not worth it, maybe we can just kill
them. But I'll defer that decission to after some fixes to the documentation.

>> Please clarify; do you consider [v][f]scanf something that "we think
>> we should never have added this in the first place, there’s no
>> plausible way to fix it, but we have to keep it around for backward
>> compatibility"?
>
> _I_ wouldn’t have added them in the first place, but I care more than
> the average about robustness in the face of unexpected input, even for
> “throwaway” programs. I doubt the C committee would be prepared to
> say the same thing.

I share your concerns about robustness of code, and am prepared to defend at
least some partial/unofficial deprecation. I'll clarify below.

> They _can_ be used legitimately, and they can
> even be used in ways that meet my robustness standards if you go
> to enough trouble.

That's not so clear to me.

> It’s just that (IMNSHO) there are better ways to
> reach those standards.
>
> In terms of text for the [v][f]scanf manpage, maybe something like
>
> [NOTES? BUGS?]
> When scanf() or fscanf() report a _matching failure_, all of the
> text that was matched successfully has still been read from
> _stdin_ or the _stream_ (respectively), and so have an
> unpredictable number of characters associated with the conversion
> that failed to match. The latter characters are lost. This may
> make it difficult to recover from invalid input.
>
> One way to make recovery easier is to separate reading from
> parsing: use fgets() or getline() to read an entire line of text
> into a string, then use sscanf() to parse the string. If a
> _matching failure_ occurs, you can try sscanf() again with a
> different _format_; the equivalent is not possible using fscanf().

This reads more or less as: "the only way to use scanf(3) is not to use it; use
fgets(3)/getline(3) + sscanf(3) instead".

>
> _Successful_ calls to scanf() and fscanf() frequently consume
> either more, or fewer, characters from the input than was
> expected. For example, assuming the next six characters readable
> from `stdin` are `"123\n a"‘, `scanf("%d", &val)` will consume the
> digits but _not_ the newline, and `scanf("%d\n", &val)‘ will
> consume the digits, the newline, _and_ the space. Either of these
> is likely to cause trouble when mixing calls to scanf() with calls
> to fgets() or fgetc(). As above, it helps to read entire lines of
> text with fgets() or getline() and then parse them with sscanf().

And this reads as "even \"successful\" calls to scanf(3) are doomed; really,
never use it". :)

>
>> In short:
>>
>> (1) Numeric conversion specifiers are broken but can be fixed…
>
> Yes.
>
>> …and you plan to fix them.
>
> No :)
>
>> (1.1) I'll revert the deprecation warning now; since they are
>> only broken because the _current_ standard and implementations are
>> broken, but not by inherent design problems.
>
> OK.
>
>> (1.2) When [someone fixes] the implementation to not be UB
>> anymore, it will also make sense to revert the patch that removed
>> the ERANGE error, since you'll need to report it.
>
> Yes.
>
>> (2) For the string conversion specifiers, there are ways to use them
>> safely.
>
> Yes.
>
>> and you plan to add a way to specify a size at runtime to the
>> function,
>
> No again :)
>
>> so it will be even better in the future. No action required.
>
> Concur.
>
>> (3) [v][f]scanf seem to be really broken by design. Please confirm.
>
> See above.

Before you start writing patches, I'm considering the following, which is my way
to say don't use these functions without deprecating them:

Split FILE and char* functions into separate manual pages. In the one for
[v]sscanf(3), I'd keep the current documentation. In the one for FILE
functions, I'd keep it very short, defering to sscanf(3) for documentation of
things like conversion specifiers, and that page would only cover the
bugs^Wdifferences that apply only to FILE functions.

I'll prepare some patches and show them for discussion in linux-man@.

>
> If you remind me where to find the git repo for the manpages, I _may_
> have time to write a patch for all this sometime next week.

man-pages' README:

Versions
Tarballs of releases starting from 2.00 are available at
<https://mirrors.edge.kernel.org/pub/linux/docs/man-pages/>.

The git(1) repository can be found at:
<git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git>

A secondary git(1) repository can be found at:
<git://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git>

See also
man-pages(7)

Website
<http://www.kernel.org/doc/man-pages/index.html>.

>
> zw

Cheers,

Alex

--
<http://www.alejandro-colomar.es/>

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]