strptime: fix parsing of tm_year when both %C and %y appear in the
format string in arbitrary order. This makes the related test cases in lib/libc/tests/time (not yet connected to the build) pass. While here, don't error on negative tm_year value based on the APPLICATION USAGE in http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html (glibc does the same): tm_year is a signed value; therefore, years before 1900 may be represented. Approved by: re (gjb), kib (mentor) Differential Revision: https://reviews.freebsd.org/D17550
This commit is contained in:
parent
ad5fefcc73
commit
a6e075a2c4
@ -95,6 +95,7 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
|
||||
int i, len;
|
||||
int flags;
|
||||
int Ealternative, Oalternative;
|
||||
int century, year;
|
||||
const struct lc_time_T *tptr = __get_current_time_locale(locale);
|
||||
static int start_of_month[2][13] = {
|
||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
|
||||
@ -102,6 +103,8 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
|
||||
};
|
||||
|
||||
flags = FLAG_NONE;
|
||||
century = -1;
|
||||
year = -1;
|
||||
|
||||
ptr = fmt;
|
||||
while (*ptr != 0) {
|
||||
@ -146,10 +149,8 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i < 19)
|
||||
return (NULL);
|
||||
|
||||
tm->tm_year = i * 100 - TM_YEAR_BASE;
|
||||
century = i;
|
||||
flags |= FLAG_YEAR;
|
||||
|
||||
break;
|
||||
@ -527,13 +528,9 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
|
||||
len--;
|
||||
}
|
||||
if (c == 'Y')
|
||||
i -= TM_YEAR_BASE;
|
||||
if (c == 'y' && i < 69)
|
||||
i += 100;
|
||||
if (i < 0)
|
||||
return (NULL);
|
||||
century = i / 100;
|
||||
year = i % 100;
|
||||
|
||||
tm->tm_year = i;
|
||||
flags |= FLAG_YEAR;
|
||||
|
||||
break;
|
||||
@ -611,6 +608,17 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp,
|
||||
}
|
||||
}
|
||||
|
||||
if (century != -1 || year != -1) {
|
||||
if (year == -1)
|
||||
year = 0;
|
||||
if (century == -1) {
|
||||
if (year < 69)
|
||||
year += 100;
|
||||
} else
|
||||
year += century * 100 - TM_YEAR_BASE;
|
||||
tm->tm_year = year;
|
||||
}
|
||||
|
||||
if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) {
|
||||
if ((flags & (FLAG_MONTH | FLAG_MDAY)) ==
|
||||
(FLAG_MONTH | FLAG_MDAY)) {
|
||||
|
Loading…
Reference in New Issue
Block a user