Re: [PATCH v1 1/2] xstrtol: Correctly handle an invalid base

Alejandro Colomar <[email protected]> Fri, 19 Jul 2024 15:09:48 +0200
Newsgroups dev.linux.lists.liba2i
Message-ID <4tfcv4btjdbtp2dyekncwnw5flcgwq7rxftx3gleciehyxtbos@bix5rqzxrek2>
--ghuoygcsxf4lpbxo
Content-Type: text/plain; protected-headers=v1; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
From: Alejandro Colomar <[email protected]>
To: [email protected]
Cc: Paul Eggert <[email protected]>, Bruno Haible <[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 1/2] xstrtol: Correctly handle an invalid base
References: <[email protected]>
 <[email protected]>
MIME-Version: 1.0
In-Reply-To: <[email protected]>

Hi Paul,

On Fri, Jul 19, 2024 at 02:53:38PM GMT, Alejandro Colomar wrote:
> strtol(3) doesn't set the end pointer if the base is invalid.  This
> allows a caller to differentiate between "invalid base" (what
> strtoi(3bsd) calls EINVAL) and an "no digits seen" (what strtoi(3bsd)
> calls ECANCELED) in systems that report EINVAL on no digits seen (POSIX
> allows this).
>=20
> 	strtol("foo", &e, 0);
> 	strtol("0", &e, -1);
>=20
> The former call will set e =3D nptr.
> The latter will leave e untouched.
>=20
> The caller has no other way to portably differentiate the calls.
>=20
> The way to differentiate those, thus, is to initialize e =3D NULL, to
> allow reading it after the call.
>=20
> While doing this, change the behavior of this function to only set
> *endptr if strtol(3) has set it, leaving it untouched otherwise.
>=20
> Fixes: 034a18049cbc (2014-12-20, "assure: new module")

Self-correction: I had a typo while running git-blame(1), which led me
to not find that the assure() call already existed --as assert()--
before your commit, Paul.

It was actually introduced in 3af47ca3f67 (1994-12-20, ".").

Please amend the Fixes tags to:

	Fixes: 3af47ca3f67 (1994-12-20, ".")
	Fixes: 64ddc975e72c (2024-07-18, "xstrtol: document and stray less from st=
rtol")

Sorry for the confusion!

Cheers,
Alex

> Fixes: 64ddc975e72c (2024-07-18, "xstrtol: document and stray less from s=
trtol")
> Cc: Paul Eggert <[email protected]>
> Cc: Bruno Haible <[email protected]>
> Cc: =C4=90o=C3=A0n Tr=E1=BA=A7n C=C3=B4ng Danh <[email protected]>
> Cc: Eli Schwartz <[email protected]>
> Cc: Sam James <[email protected]>
> Cc: Serge Hallyn <[email protected]>
> Cc: Iker Pedrosa <[email protected]>
> Cc: Michael Vetter <[email protected]>
> Cc: <[email protected]>
> Signed-off-by: Alejandro Colomar <[email protected]>
> ---
>  lib/xstrtol.c | 35 +++++++++++++++++++++--------------
>  1 file changed, 21 insertions(+), 14 deletions(-)
>=20
> diff --git a/lib/xstrtol.c b/lib/xstrtol.c
> index c3145171f3..592673557f 100644
> --- a/lib/xstrtol.c
> +++ b/lib/xstrtol.c
> @@ -71,9 +71,7 @@ strtol_error
>  __xstrtol (char const *nptr, char **endptr, int base,
>             __strtol_t *val, char const *valid_suffixes)
>  {
> -  char *t_ptr;
> -  char **p =3D endptr ? endptr : &t_ptr;
> -  *p =3D (char *) nptr;
> +  char *e =3D NULL;
> =20
>    if (! TYPE_SIGNED (__strtol_t))
>      {
> @@ -82,14 +80,21 @@ __xstrtol (char const *nptr, char **endptr, int base,
>        while (isspace (ch))
>          ch =3D *++q;
>        if (ch =3D=3D '-')
> -        return LONGINT_INVALID;
> +        {
> +          if (endptr)
> +            *endptr =3D (char *) nptr;
> +          return LONGINT_INVALID;
> +        }
>      }
> =20
>    errno =3D 0;
> -  __strtol_t tmp =3D __strtol (nptr, p, base);
> +  __strtol_t tmp =3D __strtol (nptr, &e, base);
>    strtol_error err =3D LONGINT_OK;
> =20
> -  if (*p =3D=3D nptr)
> +  if (endptr && e)
> +    *endptr =3D e;
> +
> +  if (e =3D=3D nptr)
>      {
>        /* If there is no number but there is a valid suffix, assume the
>           number is 1.  The string is invalid otherwise.  */
> @@ -113,19 +118,19 @@ __xstrtol (char const *nptr, char **endptr, int bas=
e,
>        return err;
>      }
> =20
> -  if (**p !=3D '\0')
> +  if (*e !=3D '\0')
>      {
>        int xbase =3D 1024;
>        int suffixes =3D 1;
>        strtol_error overflow;
> =20
> -      if (!strchr (valid_suffixes, **p))
> +      if (!strchr (valid_suffixes, *e))
>          {
>            *val =3D tmp;
>            return err | LONGINT_INVALID_SUFFIX_CHAR;
>          }
> =20
> -      switch (**p)
> +      switch (*e)
>          {
>          case 'E': case 'G': case 'g': case 'k': case 'K': case 'M': case=
 'm':
>          case 'P': case 'Q': case 'R': case 'T': case 't': case 'Y': case=
 'Z':
> @@ -138,10 +143,10 @@ __xstrtol (char const *nptr, char **endptr, int bas=
e,
>               power-of-1024.  */
> =20
>            if (strchr (valid_suffixes, '0'))
> -            switch (p[0][1])
> +            switch (e[1])
>                {
>                case 'i':
> -                if (p[0][2] =3D=3D 'B')
> +                if (e[2] =3D=3D 'B')
>                    suffixes +=3D 2;
>                  break;
> =20
> @@ -153,7 +158,7 @@ __xstrtol (char const *nptr, char **endptr, int base,
>                }
>          }
> =20
> -      switch (**p)
> +      switch (*e)
>          {
>          case 'b':
>            overflow =3D bkm_scale (&tmp, 512);
> @@ -224,8 +229,10 @@ __xstrtol (char const *nptr, char **endptr, int base,
>          }
> =20
>        err |=3D overflow;
> -      *p +=3D suffixes;
> -      if (**p)
> +      e +=3D suffixes;
> +      if (endptr)
> +        *endptr =3D e;
> +      if (*e)
>          err |=3D LONGINT_INVALID_SUFFIX_CHAR;
>      }
> =20
> --=20
> 2.45.2
>=20



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

--ghuoygcsxf4lpbxo
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmaaZZwACgkQnowa+77/
2zJthhAAonsWS3gYgNHn43kCn1rFLydGkx2JxahPYqoZG62WsOom/X4WpMrNIP4E
RmH1h0mWO+tyyCtHYzDubTmUvjvgKzvJYt+i4vLgNcz5+AWsXSBzpczU4qAwxHf+
tpeT9X2SN/fcsF/rQYelfOZQvL1K2Z/sUUWHc3XpSqycrJmow3JnssYcE0AhRBC4
cfoeUJ3zgLyjpgSPPLG85KIjzAthcOrNTad0vrqDoVmIsJamkBl74cY1F6vrVXSH
pVtVlb0Z9m1CH6NjzDHgqr6o7oLmqtdc+SWgzqbr+pkw9S+mE7y+eQwhLAXMj3LR
07YMQakOTfh/uuFjG5OIB1lO6zSZzKSyG+QowUqriU9QukUObTgJITSB0y43cbLp
8+Y0pbMRdbuWSF+l/6hFe9ycGeo4e3h+NsHm90XJEwWA7uBvp+UQJ0xMkjkKPhTJ
CBs1ebxA8UH785/NCMm+VQ5uc/z/OpxpPXIX8GoH/sel6jk1BwkJJKE7Hfxl+ukv
UF2hVlEi0egfn158233/mbnhy2e81kqMqbUq19y4s8jbBGhY9gLg9Y+8T4ihE2je
qLwB21SmOL0ln9r/dddGEplFcJ8zB+k3Euzy0w2eTPGUxfn+n/8CNCzLCkHIfR4f
+zLRxTuuJCJ4IXu7fSSKdEOY2SgXej8THtkwbcR+/3SG34fyHys=
=53s+
-----END PGP SIGNATURE-----

--ghuoygcsxf4lpbxo--