Messages in this thread | | | Date | Thu, 8 May 2008 00:09:09 +0400 | From | Alexey Dobriyan <> | Subject | Re: [PATCH 2/2] lib: vsprintf.c remove macros defining strict string functions |
| |
On Wed, May 07, 2008 at 11:25:29AM -0700, Harvey Harrison wrote: > Directly code the strict string conversion functions rather than using > defining macros. Pull out a small helper to check the strict conditions > required at the end of a string (nul-terminated or newline).
> Add additional checks in strict_strtol and strict_strtoll for numeric > overflow of the signed types.
C interer ranges are asymmetric.
These "strict_" functions are a farce. No amount of afterchecking will save you if there is trivial wraparound in core function.
Alexey "kstrtonum" Dobriyan
> --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -128,6 +128,18 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base) > return simple_strtoull(cp, endp, base); > } > > +/* > + * Strictly check that the string is nul terminated or has a newline > + * immediately following len chars. > + */ > +static int strict_checktail(size_t len, const char *cp, const char *tail)
Name simply sucks.
> +{ > + if ((*tail == '\0') || > + ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) > + return 1; > + else > + return 0; > +}
> @@ -165,7 +196,29 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); > * It returns 0 if conversion is successful and *res is set to the converted > * value, otherwise it returns -EINVAL and *res is set to 0. > */ > -int strict_strtol(const char *cp, unsigned int base, long *res); > +int strict_strtol(const char *cp, unsigned int base, long *res) > +{ > + int ret; > + unsigned long tmp; > + > + if (*cp == '-') > + ret = strict_strtoul(cp + 1, base, &tmp); > + else > + ret = strict_strtoul(cp, base, &tmp); > + > + if (!ret || tmp > LONG_MAX) { > + *res = 0; > + return -EINVAL; > + } > + > + if (*cp == '-') > + *res = -tmp; > + else > + *res = tmp; > + > + return 0; > +} > +EXPORT_SYMBOL(strict_strtol); > > /** > * strict_strtoull - convert a string to an unsigned long long strictly
| |