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