Commit 43b70680 authored by Nicolas George's avatar Nicolas George

parseutils: make av_parse_time() check for failure.

Until now, av_parse_time() would accept "1:00" as "1"
and silently ignore ":00".

This patch also includes a few cosmetic changes.
parent 9246896f
...@@ -522,9 +522,11 @@ time_t av_timegm(struct tm *tm) ...@@ -522,9 +522,11 @@ time_t av_timegm(struct tm *tm)
int av_parse_time(int64_t *timeval, const char *timestr, int duration) int av_parse_time(int64_t *timeval, const char *timestr, int duration)
{ {
const char *p; const char *p, *q;
int64_t t; int64_t t;
time_t now;
struct tm dt = { 0 }; struct tm dt = { 0 };
int today = 0, negative = 0, microseconds = 0;
int i; int i;
static const char * const date_fmt[] = { static const char * const date_fmt[] = {
"%Y-%m-%d", "%Y-%m-%d",
...@@ -534,25 +536,15 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) ...@@ -534,25 +536,15 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
"%H:%M:%S", "%H:%M:%S",
"%H%M%S", "%H%M%S",
}; };
const char *q;
int is_utc, len;
char lastch;
int negative = 0;
#undef time
time_t now = time(0);
len = strlen(timestr);
if (len > 0)
lastch = timestr[len - 1];
else
lastch = '\0';
is_utc = (lastch == 'z' || lastch == 'Z');
p = timestr; p = timestr;
q = NULL; q = NULL;
*timeval = INT64_MIN;
if (!duration) { if (!duration) {
if (!av_strncasecmp(timestr, "now", len)) { #undef time
now = time(0);
if (!av_strcasecmp(timestr, "now")) {
*timeval = (int64_t) now * 1000000; *timeval = (int64_t) now * 1000000;
return 0; return 0;
} }
...@@ -560,23 +552,17 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) ...@@ -560,23 +552,17 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
/* parse the year-month-day part */ /* parse the year-month-day part */
for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) { for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
q = small_strptime(p, date_fmt[i], &dt); q = small_strptime(p, date_fmt[i], &dt);
if (q) { if (q)
break; break;
}
} }
/* if the year-month-day part is missing, then take the /* if the year-month-day part is missing, then take the
* current year-month-day time */ * current year-month-day time */
if (!q) { if (!q) {
if (is_utc) { today = 1;
dt = *gmtime(&now); q = p;
} else {
dt = *localtime(&now);
}
dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
} else {
p = q;
} }
p = q;
if (*p == 'T' || *p == 't' || *p == ' ') if (*p == 'T' || *p == 't' || *p == ' ')
p++; p++;
...@@ -584,9 +570,8 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) ...@@ -584,9 +570,8 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
/* parse the hour-minute-second part */ /* parse the hour-minute-second part */
for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) { for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
q = small_strptime(p, time_fmt[i], &dt); q = small_strptime(p, time_fmt[i], &dt);
if (q) { if (q)
break; break;
}
} }
} else { } else {
/* parse timestr as a duration */ /* parse timestr as a duration */
...@@ -599,46 +584,49 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) ...@@ -599,46 +584,49 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
if (!q) { if (!q) {
/* parse timestr as S+ */ /* parse timestr as S+ */
dt.tm_sec = strtol(p, (void *)&q, 10); dt.tm_sec = strtol(p, (void *)&q, 10);
if (q == p) { if (q == p) /* the parsing didn't succeed */
/* the parsing didn't succeed */
*timeval = INT64_MIN;
return AVERROR(EINVAL); return AVERROR(EINVAL);
}
dt.tm_min = 0; dt.tm_min = 0;
dt.tm_hour = 0; dt.tm_hour = 0;
} }
} }
/* Now we have all the fields that we can get */ /* Now we have all the fields that we can get */
if (!q) { if (!q)
*timeval = INT64_MIN;
return AVERROR(EINVAL); return AVERROR(EINVAL);
/* parse the .m... part */
if (*q == '.') {
int n;
q++;
for (n = 100000; n >= 1; n /= 10, q++) {
if (!isdigit(*q))
break;
microseconds += n * (*q - '0');
}
} }
if (duration) { if (duration) {
t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
} else { } else {
dt.tm_isdst = -1; /* unknown */ int is_utc = *q == 'Z' || *q == 'z';
if (is_utc) { q += is_utc;
t = av_timegm(&dt); if (today) { /* fill in today's date */
} else { struct tm dt2 = is_utc ? *gmtime(&now) : *localtime(&now);
t = mktime(&dt); dt2.tm_hour = dt.tm_hour;
dt2.tm_min = dt.tm_min;
dt2.tm_sec = dt.tm_sec;
dt = dt2;
} }
t = is_utc ? av_timegm(&dt) : mktime(&dt);
} }
t *= 1000000; /* Check that we are at the end of the string */
if (*q)
return AVERROR(EINVAL);
/* parse the .m... part */ t *= 1000000;
if (*q == '.') { t += microseconds;
int val, n;
q++;
for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
if (!isdigit(*q))
break;
val += n * (*q - '0');
}
t += val;
}
*timeval = negative ? -t : t; *timeval = negative ? -t : t;
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment