Re: [PATCH v1] xstrtol: Remove dead code
Alejandro Colomar <[email protected]> Fri, 19 Jul 2024 00:14:14 +0200
| Newsgroups | dev.linux.lists.liba2i |
|---|---|
| Message-ID | <2licxuxsw37hpyss5izkqu6x4lfwcduxwbrgw7a4fqaibydwlx@o6y73xqtyrnx> |
--fzbrwa7e37dq4tly Content-Type: text/plain; protected-headers=v1; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable From: Alejandro Colomar <[email protected]> To: Bruno Haible <[email protected]> Cc: [email protected], Paul Eggert <[email protected]>, =?utf-8?B?xJBvw6BuIFRy4bqnbiBDw7RuZw==?= Danh <[email protected]>, Eli Schwartz <[email protected]>, Sam James <[email protected]>, Serge Hallyn <[email protected]>, Iker Pedrosa <[email protected]>, Michael Vetter <[email protected]>, [email protected] Subject: Re: [PATCH v1] xstrtol: Remove dead code References: <[email protected]> <8009158.qOBuL9xsDt@nimes> <kul6qwyrvq2xdevjjkkblsalg7ycwg6x7ey725kans5myqjcai@3jm56c5famlt> MIME-Version: 1.0 In-Reply-To: <kul6qwyrvq2xdevjjkkblsalg7ycwg6x7ey725kans5myqjcai@3jm56c5famlt> [CC -=3D Andrew, per explicit request] On Thu, Jul 18, 2024 at 11:25:11PM GMT, Alejandro Colomar wrote: > On Thu, Jul 18, 2024 at 11:09:40PM GMT, Bruno Haible wrote: > > Hi Alejandro, Hi Bruno, > > > strtol(3) has a limited set of possible states: > > > ... > > > The condition '*endp !=3D s && errno !=3D 0 && errno !=3D ERANGE' is > > > unreachable. The only errno possible if '*endp !=3D s' is ERANGE. > >=20 > > Such a statement can be true if you look at the standards (ISO C, POSIX= ). > >=20 > > However, there's a difference between what the standards say and what t= he > > systems actually do. The Gnulib documentation contains thousands of exa= mples > > of such differences. > >=20 > > Gnulib therefore (almost) never assumes that there are no possible errno > > values besides the ones listed in the standards. > > - Some systems return "wrong" errno values. Example: [1] > > - Some systems fail with ENOMEM when memory is tight. Who says that > > an implementation of strtol() cannot use malloc() ? Some implementa= tions > > of strtod() do use malloc(). > >=20 > > So, what you call "dead code", I call "defensive programming". I would = not > > like to apply this patch. On the other hand, I'm not sure that defensive programming is valid in this case. I already discussed this topic with Serge (but we didn't have in mind any specific implementation) some time ago, and, We'd need to know the precise specification of that system that can set errno =3D ENOMEM. Is *endp guaranteed to be set? Or may it be unset (as happens with EINVAL)? If it is allowed to keep *endp unset, then the first `if (*p =3D=3D s)` would already be UB. And for truly being defensive, we'd need to assume that it may leave *endp unset. Thus we cannot read that until we know that no errno has been set. But then comes the problem that some systems set EINVAL on what strtoi(3) calls ECANCELED. To work with all of those systems, we'd probably need to pass a dummy NULL to make sure we can inspect *endp regardless of strtol(3) having set it or not: intmax_t strtoi(char *s, char **restrict endp, int base, intmax_t min, intmax_t max, int *restrict status) { int errno_saved, st; char *e; char **ep; intmax_t n; e =3D NULL; ep =3D &e; if (status =3D=3D NULL) status =3D &st; if (base !=3D 0 && (base < 2 || base > 36)) { *status =3D EINVAL; return MAX(min, MIN(max, 0)); } errno_saved =3D errno; errno =3D 0; n =3D strtoimax(s, ep, base); if (errno =3D=3D ERANGE || n < min || n > max) *status =3D ERANGE; else if (e =3D=3D s && (errno =3D=3D 0 || errno =3D=3D EINVAL)) *status =3D ECANCELED; else if (errno !=3D 0) *status =3D errno; else if (*e !=3D '\0') *status =3D ENOTSUP; else *status =3D 0; errno =3D errno_saved; if (endp !=3D NULL) *endp =3D e; return MAX(min, MIN(max, n)); } Does this make sense? Have a lovely night! Alex >=20 > Makes sense. I think we should document that possibility in the manual > page. Maybe say that other errno values are possible in some systems? > Otherwise, it's already a hell of a function to take care of, and most > uses don't handle that possibility at the moment. (Yet more reasons to > use a wrapper that returns -1 & sets errno on error, as the rest of > libc.) >=20 > Would you send a patch? (I'd write it myself, but you probably can > provide more info in the commit message.) >=20 > Have a lovely night! > Alex >=20 > >=20 > > Bruno > >=20 > > [1] https://www.gnu.org/software/gnulib/manual/html_node/getlogin_005fr= =2Ehtml > >=20 > >=20 > >=20 >=20 > --=20 > <https://www.alejandro-colomar.es/> --=20 <https://www.alejandro-colomar.es/> --fzbrwa7e37dq4tly Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmaZk7AACgkQnowa+77/ 2zKWHxAAljv8KWAeVntrtFM2wX4GryxIz39kpN1DurTKzAPKjRMrCFQXiDf2ZMf/ ExVpkAHFMKjLlD2ENhfaLcDXr8W5nLuHYwzeySgG+rH7Q6QC8uqR0UNyq+nKID0j RvQiEH6KItp9MaxkHtUUHIu5B436FBE3czqgOTdfVwt9GqwjL9lbjCOEBBtHshYK 8QGcDZmnktcPVHEB4bJnsLvEHphIrevt/o7d1aj5G3maN1kIOiSiK8TKfo3MalA6 +lz8T3TeRHDm/gDTRiXmGHZtB4KBHw+/5zcGBO8W2jvilVm6rgvwQgHdxUkpZgve 0x32k0rbKBOY+nQtAnO1dwgl7/rrv9BU2gY/+tlN86RyMMUCcFwVss02JayreyhK qwl2gULtR60sk8ckASIeyg1K9lZvRmQHrYhAx2htdI0WjSeJU2SAUNxVdWK8hEyX M068SZ0WwZO0rjIoS4SDE8JSWlBzc92R+exTqzx0A7IQ2ZA4WQQ0baB5VNH4caIL IgvsBSvA2tpZeU79PnmUUHJP+W++blhOmg1bCasRPoSu4ih6652QHSJROp4XaXsz ZJdm9x6VNVv9FQFJBwjW/mAR4Ygn7T+a/8hyrnkcgGLxUoRuZ5ojifpwgKPdfn3d FX+PfbAawZY4tE4VzZ+jahs+RQOClTQiJi1s3a2RTv/FlSSGGag= =amSz -----END PGP SIGNATURE----- --fzbrwa7e37dq4tly--