[pulseaudio-discuss] [PATCH] echo-cancel: make webrtc beamforming parameter parsing locale independent

Tanu Kaskinen tanuk at iki.fi
Sun Oct 1 17:00:41 UTC 2017


sscanf() uses the current locale, and on some locales comma is used as
the decimal point. This patch rewrites parse_point() to avoid sscanf()
at the cost of more manual parsing work.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=96819
---
 src/modules/echo-cancel/webrtc.cc | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/src/modules/echo-cancel/webrtc.cc b/src/modules/echo-cancel/webrtc.cc
index aadb1af26..0349ab268 100644
--- a/src/modules/echo-cancel/webrtc.cc
+++ b/src/modules/echo-cancel/webrtc.cc
@@ -150,14 +150,36 @@ static void webrtc_ec_fixate_spec(pa_sample_spec *rec_ss, pa_channel_map *rec_ma
 }
 
 static bool parse_point(const char **point, float (&f)[3]) {
-    int ret, length;
-
-    ret = sscanf(*point, "%g,%g,%g%n", &f[0], &f[1], &f[2], &length);
-    if (ret != 3)
-        return false;
+    unsigned i;
+    size_t length;
+    char buf[20];
+    double d[3];
+
+    for (i = 0; i < 3; i++) {
+        length = strcspn(*point, ",");
+        if (length == 0 || length >= sizeof(buf))
+            return false; /* No number found, or it's too long. */
+
+        memcpy(buf, *point, length);
+        buf[length] = 0;
+
+        if (pa_atod(buf, &d[i]) < 0)
+            return false; /* Couldn't parse the number as a double. */
+
+        *point += length;
+
+        /* After the first two numbers there should be a comma. */
+        if (i != 2) {
+            if (**point == ',')
+                *point += 1;
+            else
+                return false; /* Comma expected but not found. */
+        }
+    }
 
-    /* Consume the bytes we've read so far */
-    *point += length;
+    f[0] = d[0];
+    f[1] = d[1];
+    f[2] = d[2];
 
     return true;
 }
-- 
2.14.1



More information about the pulseaudio-discuss mailing list