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 | 
