Also validate hours via strptime_l(3)

Simplify the code, by only using one parser, ensure the dates (hours and dates)
are valid
This commit is contained in:
Baptiste Daroussin 2015-07-05 10:11:35 +00:00
parent 330e423084
commit f6eae381a5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285157
2 changed files with 46 additions and 51 deletions

View File

@ -98,21 +98,7 @@ weekday(char const ** str)
}
static void
parse_time(char const * str, int *hour, int *min, int *sec)
{
*hour = a2i(&str);
if ((str = strchr(str, ':')) == NULL)
*min = *sec = 0;
else {
++str;
*min = a2i(&str);
*sec = ((str = strchr(str, ':')) == NULL) ? 0 : atoi(++str);
}
}
static void
parse_datesub(char const * str, int *day, int *mon, int *year)
parse_datesub(char const * str, struct tm *t)
{
struct tm tm;
locale_t l;
@ -123,6 +109,38 @@ parse_datesub(char const * str, int *day, int *mon, int *year)
"%d-%b-%Y",
"%d-%m-%y",
"%d-%m-%Y",
"%H:%M %d-%b-%y",
"%H:%M %d-%b-%Y",
"%H:%M %d-%m-%y",
"%H:%M %d-%m-%Y",
"%H:%M:%S %d-%b-%y",
"%H:%M:%S %d-%b-%Y",
"%H:%M:%S %d-%m-%y",
"%H:%M:%S %d-%m-%Y",
"%d-%b-%y %H:%M",
"%d-%b-%Y %H:%M",
"%d-%m-%y %H:%M",
"%d-%m-%Y %H:%M",
"%d-%b-%y %H:%M:%S",
"%d-%b-%Y %H:%M:%S",
"%d-%m-%y %H:%M:%S",
"%d-%m-%Y %H:%M:%S",
"%H:%M\t%d-%b-%y",
"%H:%M\t%d-%b-%Y",
"%H:%M\t%d-%m-%y",
"%H:%M\t%d-%m-%Y",
"%H:%M\t%S %d-%b-%y",
"%H:%M\t%S %d-%b-%Y",
"%H:%M\t%S %d-%m-%y",
"%H:%M\t%S %d-%m-%Y",
"%d-%b-%y\t%H:%M",
"%d-%b-%Y\t%H:%M",
"%d-%m-%y\t%H:%M",
"%d-%m-%Y\t%H:%M",
"%d-%b-%y\t%H:%M:%S",
"%d-%b-%Y\t%H:%M:%S",
"%d-%m-%y\t%H:%M:%S",
"%d-%m-%Y\t%H:%M:%S",
NULL,
};
@ -132,9 +150,12 @@ parse_datesub(char const * str, int *day, int *mon, int *year)
for (i=0; valid_formats[i] != NULL; i++) {
ret = strptime_l(str, valid_formats[i], &tm, l);
if (ret && *ret == '\0') {
*day = tm.tm_mday;
*mon = tm.tm_mon;
*year = tm.tm_year;
t->tm_mday = tm.tm_mday;
t->tm_mon = tm.tm_mon;
t->tm_year = tm.tm_year;
t->tm_hour = tm.tm_hour;
t->tm_min = tm.tm_min;
t->tm_sec = tm.tm_sec;
freelocale(l);
return;
}
@ -249,39 +270,7 @@ parse_date(time_t dt, char const * str)
}
}
/*
* See if there is a time hh:mm[:ss]
*/
if ((p = strchr(tmp, ':')) == NULL) {
/*
* No time string involved
*/
T->tm_hour = T->tm_min = T->tm_sec = 0;
parse_datesub(tmp, &T->tm_mday, &T->tm_mon, &T->tm_year);
} else {
char datestr[64], timestr[64];
/*
* Let's chip off the time string
*/
if ((q = strpbrk(p, " \t")) != NULL) { /* Time first? */
int l = q - str;
strlcpy(timestr, str, l + 1);
strlcpy(datestr, q + 1, sizeof(datestr));
parse_time(timestr, &T->tm_hour, &T->tm_min, &T->tm_sec);
parse_datesub(datestr, &T->tm_mday, &T->tm_mon, &T->tm_year);
} else if ((q = strrchr(tmp, ' ')) != NULL) { /* Time last */
int l = q - tmp;
strlcpy(timestr, q + 1, sizeof(timestr));
strlcpy(datestr, tmp, l + 1);
} else /* Bail out */
return dt;
parse_time(timestr, &T->tm_hour, &T->tm_min, &T->tm_sec);
parse_datesub(datestr, &T->tm_mday, &T->tm_mon, &T->tm_year);
}
parse_datesub(tmp, T);
dt = mktime(T);
}
return dt;

View File

@ -199,6 +199,12 @@ user_add_expiration_body() {
${PW} useradd foo -e 20-Foo-2043
atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
${PW} useradd foo -e 20-13-2043
atf_check -s exit:0 ${PW} useradd foo -e "12:00 20-03-2043"
atf_check -s exit:0 ${PW} userdel foo
atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
${PW} useradd foo -e "12 20-03-2043"
atf_check -s exit:0 ${PW} useradd foo -e "20-03-2043 12:00"
atf_check -s exit:0 ${PW} userdel foo
}
atf_init_test_cases() {