[PATCH v1 1/2] xstrtol: Correctly handle an invalid base
Alejandro Colomar <[email protected]> Fri, 19 Jul 2024 14:53:34 +0200
| Newsgroups | dev.linux.lists.liba2i |
|---|---|
| Message-ID | <[email protected]> |
--os5zt5xuey5fttuk 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: Alejandro Colomar <[email protected]>, 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: [PATCH v1 1/2] xstrtol: Correctly handle an invalid base References: <[email protected]> MIME-Version: 1.0 In-Reply-To: <[email protected]> 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). strtol("foo", &e, 0); strtol("0", &e, -1); The former call will set e =3D nptr. The latter will leave e untouched. The caller has no other way to portably differentiate the calls. The way to differentiate those, thus, is to initialize e =3D NULL, to allow reading it after the call. While doing this, change the behavior of this function to only set *endptr if strtol(3) has set it, leaving it untouched otherwise. Fixes: 034a18049cbc (2014-12-20, "assure: new module") Fixes: 64ddc975e72c (2024-07-18, "xstrtol: document and stray less from str= tol") 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(-) 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 base, 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 base, 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 --os5zt5xuey5fttuk Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmaaYc4ACgkQnowa+77/ 2zLvdg/7BpL+T18Odma2CpBhuL/vwdQFyy2UMkWz7gnBjNCxoO/1/2KYxnI/tebu FoaQCN/xdL5rQBg9UATQTV3fco7sw0+CxcIteW5Iu5FGivQMv9Nbs/YTyrX3E84x k16LfkrSi5ZYEBJkjxnY8EqASNVhTisW9/Pcx5tkDwvp1lgiYS6rd08O8Kd3Qo0f fMKW2ZDNMfu5aZJu/3e/WN6B7pfaJxMyTmK4KCRGp7AT5OT6JdVPlmtYxxgt1Tf1 cNDesdHB+yZPXsR28cM2jlyx8/kqqRvaBwt81Iw5/Nb8L1EdAIpjKEBy9NwU2Lh3 kgo9LkvFSFLCO+J3psLdaR4yd6fmZOu3np6Y79/E4r51EWg6W/uKjIvVLU67dW0d t1XfHclx7iBq0bqkSZo3hwrnz58QHT9XfkK81j+uaKTS7KFRYtAcHcZfVpm+JUH9 Gt9rN0/D/tr0T+BHgXLlT2z4HHFE47qWDu3QMmks5JE5HLjFMs2Zpuoxm9TWWq2s surtB9rWWUe3TeTmxFv77GWb0D3h4sfFsXyga1YuR1Tg6qkCOLeJp1k5hR4kKXNu kcRx6EKXqDMbROA1GeoM8kWLlUtVywt04qSTjDHI3I/aGj5/nLn1KiEboDujm9ZP x5jCDyOSJcbQ3TGqIEAeBGQZPlY8a6r1ZZ74rRVvf80Mg1HeoO0= =Sb8Q -----END PGP SIGNATURE----- --os5zt5xuey5fttuk--