tech-misc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD



On 2025-03-19 18:15, Alejandro Colomar wrote:

I think that you'd
benefit from range checks, actually.  (See my response to his email.)
<https://lore.kernel.org/liba2i/6oyljvsenypqnrmgjbcwskqpdsag677h2dzay6hvfoosju4224@3j7iczm4d7nw/T/#m38066e6eec63a8906e3cbfea275c9d7940d8df98>

That's a long email and I'm not sure I'm looking at the right place in it, but if I understand correctly it says that Gnulib code like this:

  port = strtoul (servname, &c, 10);
  if (port > 0xffff)
    return EAI_NONAME;

would be clearer if worded this way:

  port = strtou (servname, &c, 10, 0, 0xffff, &err);
  if (err == ERANGE)
    return EAI_NONAME;

If so, I disagree. The strtou API is more complicated, and the reader is likely to forget what each of its arguments means, e.g., that the 0 is a minimum and the 0xffff is a maximum. The strtoul API is simpler and it's more obvious what is intended.


Do you mean that the implementation of strspn(3) was temporarily broken?
Or that the specification is bad?

No, strspn itself is fine. It's that call to strspn that is broken. The call assumes that only ' ', '\t', and '\n' satisfy c_isspace, which is incorrect. This is an area where c_isspace is simpler and easier to follow than strspn.


For this particular resource, a limit of ULONG_MAX has the same practical
effect as a limit of ULONG_MAX + 1. Since the user can't tell the difference
in behavior, it's fine to implement the larger limit as the smaller one,
with no diagnostic.

According to Bruno, that limit is later clamped at a much lower value,
so I think that clamping could be moved up to the strtou(3) call.

Yes, it could be moved into strtou, but there's a cost in simplicity and easy of understanding.


How do you get a uintmax_t?

With a different function a2u that comes with a different struct (just like strtoi/strtou).

Also, how do I perform range checks in that call?  I need to specify
min and max limits.

The caller should do the range checks, as this makes C code easier to follow, both by the human programmer and the compiler, which can more easily use the range information to generate better code.

For cases like these having a function do the range checks is often a mistake - it doesn't significantly increase reliability (on the contrary, it can reduce it). But if you prefer a function with range checks, it's easy to add bounds arguments.

How do you know how much has been parsed on error?

Good point. I guess we'll need three elements to the structure, then.

At this point we're bikeshedding but you can have the last word if you like.



Home | Main Index | Thread Index | Old Index