Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libutil When computing relative months, use mktime() dir...



details:   https://anonhg.NetBSD.org/src/rev/7a6d8e2ce693
branches:  trunk
changeset: 342604:7a6d8e2ce693
user:      dholland <dholland%NetBSD.org@localhost>
date:      Thu Dec 31 10:52:06 2015 +0000

description:
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:

 lib/libutil/parsedate.y |  28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)

diffs (51 lines):

diff -r 7003287e0477 -r 7a6d8e2ce693 lib/libutil/parsedate.y
--- a/lib/libutil/parsedate.y   Thu Dec 31 10:31:07 2015 +0000
+++ b/lib/libutil/parsedate.y   Thu Dec 31 10:52:06 2015 +0000
@@ -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 @@
 {
     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);
 }
 
 



Home | Main Index | Thread Index | Old Index