diff options
| author | dholland <dholland@NetBSD.org> | 2015-12-31 10:52:06 +0000 |
|---|---|---|
| committer | dholland <dholland@NetBSD.org> | 2015-12-31 10:52:06 +0000 |
| commit | f6559439593b404e953bb657c19d341c71ad8213 (patch) | |
| tree | bfdaad430dcbbe89dbd8b6b073f8721be53e7f7f /lib/libutil | |
| parent | cbfd5769f63571cf97e14983a861295326374887 (diff) | |
When computing relative months, use mktime() directly and don't call
our Convert(). And check it for failure. This fixes three sets of
problems:
(1) depending on the passed-in value of Timezone it might
disassemble the time in one timezone and reassemble it in
another, causing mysterious offsets of a few hours;
(2) with the previous set of changes to this file, Convert() fails
if it ends up normalizing a date, so e.g. going three months
forward from March 31 would fail;
(3) previously if Convert() failed we passed -1 on to DSTcorrect(),
which made a mess.
PR 50574.
Diffstat (limited to 'lib/libutil')
| -rw-r--r-- | lib/libutil/parsedate.y | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/libutil/parsedate.y b/lib/libutil/parsedate.y index dd0335e1ebf..2ae41c7b147 100644 --- a/lib/libutil/parsedate.y +++ b/lib/libutil/parsedate.y @@ -14,7 +14,7 @@ #include <sys/cdefs.h> #ifdef __RCSID -__RCSID("$NetBSD: parsedate.y,v 1.26 2015/12/31 10:31:07 dholland Exp $"); +__RCSID("$NetBSD: parsedate.y,v 1.27 2015/12/31 10:52:06 dholland Exp $"); #endif #include <stdio.h> @@ -728,19 +728,31 @@ RelativeMonth( { struct tm tm; time_t Month; - time_t Year; + time_t Then; if (RelMonth == 0) return 0; + /* + * It doesn't matter what timezone we use to do this computation, + * as long as we use the same one to reassemble the time that we + * used to disassemble it. So always use localtime and mktime. In + * particular, don't use Convert() to reassemble, because it will + * not only reassemble with the wrong timezone but it will also + * fail if we do e.g. three months from March 31 yielding July 1. + */ + (void)Timezone; + if (localtime_r(&Start, &tm) == NULL) return -1; + Month = 12 * (tm.tm_year + 1900) + tm.tm_mon + RelMonth; - Year = Month / 12; - Month = Month % 12 + 1; - return DSTcorrect(Start, - Convert(Month, (time_t)tm.tm_mday, Year, - (time_t)tm.tm_hour, (time_t)tm.tm_min, (time_t)tm.tm_sec, - Timezone, MER24, DSTmaybe)); + tm.tm_year = (Month / 12) - 1900; + tm.tm_mon = Month % 12; + errno = 0; + Then = mktime(&tm); + if (Then == -1 && errno != 0) + return -1; + return DSTcorrect(Start, Then); } |
