[pulseaudio-discuss] [PATCH] core-util: Make number parsing stricter
Peter Meerwald
pmeerw at pmeerw.net
Thu Feb 26 13:02:18 PST 2015
Hello,
> pa_atou(), pa_atol() and pa_atod() are stricter than the libc
> counterparts (the PA functions reject strings that have trailing extra
> stuff in them). I have been under the impression that the PA functions
> only accept "obviously valid numbers", that is, I have assumed that
> these would be rejected: " 42" (leading whitespace), "" (empty
> string) and "-18446744073709551615" in case of pa_atou().
>
> I noticed that empty strings are accepted, however, and on closer
> inspection I found that leading whitespace is accepted too, and even
> that pa_atou() thinks that "-18446744073709551615" is the same thing
> as "1"! This patch makes the parsing functions more strict, so that
> they indeed only accept "obviously valid numbers". In case of
> pa_atou() I decided to also disallow a leading plus sign, as it's
> redundant, and looks very strange (i.e. not obviously valid) in
> contexts where the number represents, for example, an array index.
looks good
pa_atol() and pa_atod() could reject a leading '+'
p.
> ---
> src/pulsecore/core-util.c | 41 ++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 38 insertions(+), 3 deletions(-)
>
> diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
> index 9b16936..e20ebcb 100644
> --- a/src/pulsecore/core-util.c
> +++ b/src/pulsecore/core-util.c
> @@ -2315,10 +2315,27 @@ int pa_atou(const char *s, uint32_t *ret_u) {
> pa_assert(s);
> pa_assert(ret_u);
>
> + /* strtoul() ignores leading spaces. We don't. */
> + if (isspace(*s)) {
> + errno = EINVAL;
> + return -1;
> + }
> +
> + /* strtoul() accepts strings that start with a minus sign. In that case the
> + * original negative number gets negated, and strtoul() returns the negated
> + * result. We don't want that kind of behaviour. strtoul() also allows a
> + * leading plus sign, which is also a thing that we don't want. */
> + if (*s == '-' || *s == '+') {
> + errno = EINVAL;
> + return -1;
> + }
> +
> errno = 0;
> l = strtoul(s, &x, 0);
>
> - if (!x || *x || errno) {
> + /* If x doesn't point to the end of s, there was some trailing garbage in
> + * the string. If x points to s, no conversion was done (empty string). */
> + if (!x || *x || x == s || errno) {
> if (!errno)
> errno = EINVAL;
> return -1;
> @@ -2342,10 +2359,19 @@ int pa_atol(const char *s, long *ret_l) {
> pa_assert(s);
> pa_assert(ret_l);
>
> + /* strtol() ignores leading spaces. We don't. */
> + if (isspace(*s)) {
> + errno = EINVAL;
> + return -1;
> + }
> +
> errno = 0;
> l = strtol(s, &x, 0);
>
> - if (!x || *x || errno) {
> + /* If x doesn't point to the end of s, there was some trailing garbage in
> + * the string. If x points to s, no conversion was done (at least an empty
> + * string can trigger this). */
> + if (!x || *x || x == s || errno) {
> if (!errno)
> errno = EINVAL;
> return -1;
> @@ -2371,6 +2397,12 @@ int pa_atod(const char *s, double *ret_d) {
> pa_assert(s);
> pa_assert(ret_d);
>
> + /* strtod() ignores leading spaces. We don't. */
> + if (isspace(*s)) {
> + errno = EINVAL;
> + return -1;
> + }
> +
> /* This should be locale independent */
>
> #ifdef HAVE_STRTOF_L
> @@ -2392,7 +2424,10 @@ int pa_atod(const char *s, double *ret_d) {
> f = strtod(s, &x);
> }
>
> - if (!x || *x || errno) {
> + /* If x doesn't point to the end of s, there was some trailing garbage in
> + * the string. If x points to s, no conversion was done (at least an empty
> + * string can trigger this). */
> + if (!x || *x || x == s || errno) {
> if (!errno)
> errno = EINVAL;
> return -1;
> --
> 1.9.3
>
> _______________________________________________
> pulseaudio-discuss mailing list
> pulseaudio-discuss at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>
--
Peter Meerwald
+43-664-2444418 (mobile)
More information about the pulseaudio-discuss
mailing list