From c0119027b1f3b8caeab8db6f90edfc096725333f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Sat, 24 Oct 2020 08:20:24 +0200 Subject: Improve the MPD time parser - reject negative values, which strtoul() happily accepts - deal with an arbitrary number of decimal digits - don't return milliseconds when we fail to parse seconds --- nncmpp.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/nncmpp.c b/nncmpp.c index 7cddc83..895667b 100644 --- a/nncmpp.c +++ b/nncmpp.c @@ -3358,18 +3358,27 @@ mpd_read_time (const char *value, int *sec, int *optional_msec) if (!value) return; - char *end, *period = strchr (value, '.'); - if (optional_msec && period) + char *end = NULL; + long n = strtol (value, &end, 10); + if (n < 0 || (*end && *end != '.')) + return; + + int msec = 0; + if (*end == '.') { - unsigned long n = strtoul (period + 1, &end, 10); - if (*end) + // In practice, MPD always uses three decimal digits + size_t digits = strspn (++end, "0123456789"); + if (end[digits]) return; - // XXX: this relies on three decimal places - *optional_msec = MIN (INT_MAX, n); + + if (digits--) msec += (*end++ - '0') * 100; + if (digits--) msec += (*end++ - '0') * 10; + if (digits--) msec += *end++ - '0'; } - unsigned long n = strtoul (value, &end, 10); - if (end == period || !*end) - *sec = MIN (INT_MAX, n); + + *sec = MIN (INT_MAX, n); + if (optional_msec) + *optional_msec = msec; } static void -- cgit v1.2.3