All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Matthew House <mattlloydhouse@gmail.com>
Cc: linux-man <linux-man@vger.kernel.org>,
	Zack Weinberg <zack@owlfolio.org>,
	Lee Griffiths <poddster@gmail.com>
Subject: Re: [PATCH] sscanf.3: Remove term 'deprecated', and expand BUGS
Date: Wed, 6 Dec 2023 22:12:50 +0100	[thread overview]
Message-ID: <ZXDj2cFZeIeeXII4@debian> (raw)
In-Reply-To: <20231206204522.756572-1-mattlloydhouse@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2436 bytes --]

Hi Matthew,

On Wed, Dec 06, 2023 at 03:45:19PM -0500, Matthew House wrote:
> On Wed, Dec 6, 2023 at 3:18 PM Alejandro Colomar <alx@kernel.org> wrote:
> > Hi Matthew,
> >
> > On Wed, Dec 06, 2023 at 01:33:50PM -0500, Matthew House wrote:
> > > I feel like this is rather overstating the difficulty. In practice, the
> > > no-conversion condition is very commonly detected by checking whether
> > > *endptr == nptr after the call. The usual idiom I see is something like:
> > >
> > >     char *end;
> > >     errno = 0;
> > >     value = strtol(ptr, &end, 10);
> > >     if (end == ptr || *end != '\0' || errno == ERANGE)
> >
> > That test could trigger UB, if you passed an unsupported base.  Of
> > course, in this case you pass 10, but what if the base was a
> > user-controlled variable?  In such a case, nothing says what happens to
> > 'end' (experimentally, I see it is not modified, so it would be left
> > uninitialized); so dereferencing it, or even comparing it, would be UB.
> >
> > >         goto err;
> >
> > Yeah, if you just don't care and want to handle all errors in the same
> > way, and you know the base is supported, this is correct.
> 
> The practical answer is that the base is never ultimately a user-controlled
> variable. Sometimes people define wrapper functions with a variable base,
> but that base is still ultimately fixed by all its callers. If you disagree
> with this, I challenge you to name a single example.

Agree.  But then the manual shouldn't suggest that it's fine to test for
EINVAL.  It would be fine to test beforehand, though:

	errno = 0;
	strtol("0", NULL, base);
	if (errno == EINVAL)
		goto bad;

	// Now we can work with that base.
	...
	
	errrno = 0;
	val = strtol(str, &end, base);
	if (end == ptr)
		goto nan;
	if (errno == ERANGE || val < min || val > max)
		goto bignum;
	if (*end != '\0')
		goto garbage;

I think this example would be an improvement over the current page.
Still, strtoi() is simpler to use in the general case:

	errno = 0;
	val1 = strtoi(str, &end, base, min, max, &err);
	if (err != 0 || err != ENOTSUP)
		goto err;
	val2 = strtoi(str, &end, base, min, max, &err);
	if (err != 0)
		goto err;

But yeah, this is something you can pull from libbsd, or write your own,
after taking into consideration the thing about EINVAL from above.

Cheers,
Alex

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

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

  parent reply	other threads:[~2023-12-06 21:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-06 14:52 [PATCH] sscanf.3: Remove term 'deprecated', and expand BUGS Alejandro Colomar
2023-12-06 16:36 ` Alejandro Colomar
2023-12-06 18:33   ` Matthew House
2023-12-06 20:17     ` Alejandro Colomar
2023-12-06 20:45       ` Matthew House
2023-12-06 20:54         ` Matthew House
2023-12-06 21:12         ` Alejandro Colomar [this message]
     [not found] ` <CAKXok1GQvKi2HiBU89CSd+KF_dd9+mOMVhHrMKAVLLwcyJDN2g@mail.gmail.com>
2023-12-07 21:50   ` Fwd: " Lee Griffiths
2023-12-09 11:55     ` Alejandro Colomar

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=ZXDj2cFZeIeeXII4@debian \
    --to=alx@kernel.org \
    --cc=linux-man@vger.kernel.org \
    --cc=mattlloydhouse@gmail.com \
    --cc=poddster@gmail.com \
    --cc=zack@owlfolio.org \
    /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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.