diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2020-10-24 08:20:24 +0200 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2020-10-24 14:54:12 +0200 |
commit | c0119027b1f3b8caeab8db6f90edfc096725333f (patch) | |
tree | 57bc65ee74a2b6b3524d99a680e8f8890c6ec881 | |
parent | 3934d9b1f90b354aed7a072103ef1c58e581cd9d (diff) | |
download | nncmpp-c0119027b1f3b8caeab8db6f90edfc096725333f.tar.gz nncmpp-c0119027b1f3b8caeab8db6f90edfc096725333f.tar.xz nncmpp-c0119027b1f3b8caeab8db6f90edfc096725333f.zip |
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
-rw-r--r-- | nncmpp.c | 27 |
1 files changed, 18 insertions, 9 deletions
@@ -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 |