[pulseaudio-commits] src/pulsecore

Tanu Kaskinen tanuk at kemper.freedesktop.org
Mon Mar 16 09:56:08 PDT 2015


 src/pulsecore/core-util.c |   55 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 3 deletions(-)

New commits:
commit c0ab9e6ce05c4cf34bec2e0be98923c7e5b09879
Author: Tanu Kaskinen <tanu.kaskinen at linux.intel.com>
Date:   Wed Feb 25 11:56:47 2015 +0200

    core-util: Make number parsing stricter
    
    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". I decided to also
    disallow leading plus signs, just because I don't like them.

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index b37e450..1dad507 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2316,10 +2316,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;
@@ -2343,10 +2360,26 @@ 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;
+    }
+
+    /* strtol() accepts leading plus signs, but that's ugly, so we don't allow
+     * that. */
+    if (*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;
@@ -2372,6 +2405,19 @@ 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;
+    }
+
+    /* strtod() accepts leading plus signs, but that's ugly, so we don't allow
+     * that. */
+    if (*s == '+') {
+        errno = EINVAL;
+        return -1;
+    }
+
     /* This should be locale independent */
 
 #ifdef HAVE_STRTOF_L
@@ -2393,7 +2439,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;



More information about the pulseaudio-commits mailing list