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)