Date: Wed, 17 Oct 2018 14:51:43 +0000 (UTC) From: Yuri Pankov <yuripv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r339408 - head/lib/libc/stdtime Message-ID: <201810171451.w9HEph96089642@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yuripv Date: Wed Oct 17 14:51:43 2018 New Revision: 339408 URL: https://svnweb.freebsd.org/changeset/base/339408 Log: 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 Modified: head/lib/libc/stdtime/strptime.c Modified: head/lib/libc/stdtime/strptime.c ============================================================================== --- head/lib/libc/stdtime/strptime.c Wed Oct 17 10:31:08 2018 (r339407) +++ head/lib/libc/stdtime/strptime.c Wed Oct 17 14:51:43 2018 (r339408) @@ -95,6 +95,7 @@ _strptime(const char *buf, const char *fmt, struct tm 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 }; flags = FLAG_NONE; + century = -1; + year = -1; ptr = fmt; while (*ptr != 0) { @@ -146,10 +149,8 @@ label: 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 @@ label: 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; @@ -609,6 +606,17 @@ label: default: return (NULL); } + } + + 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)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810171451.w9HEph96089642>