Module Name:    src
Committed By:   christos
Date:           Sat Oct 27 22:29:24 UTC 2018

Modified Files:
        src/lib/libc/time: NEWS theory.html tz-how-to.html tz-link.html
            tzfile.5 version zdump.8 zic.8 zic.c

Log Message:
Welcome tzcode-2018g

  Changes to code

    When generating TZif files with leap seconds, zic no longer uses a
    format that trips up older 32-bit clients, fixing a bug introduced
    in 2018f.  (Reported by Daniel Fischer.)  Also, the zic workaround
    for QTBUG-53071 now also works for TZif files with leap seconds.

    The translator to rearguard format now rewrites the line
    "Rule Japan 1948 1951 - Sep Sat>=8 25:00 0 S" to
    "Rule Japan 1948 1951 - Sep Sun>=9  1:00 0 S".
    This caters to zic before 2007 and to Oracle TZUpdater 2.2.0
    and earlier.  (Reported by Christos Zoulas.)

  Changes to documentation

    tzfile.5 has new sections on interoperability issues.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/lib/libc/time/NEWS
cvs rdiff -u -r1.4 -r1.5 src/lib/libc/time/theory.html
cvs rdiff -u -r1.5 -r1.6 src/lib/libc/time/tz-how-to.html
cvs rdiff -u -r1.2 -r1.3 src/lib/libc/time/tz-link.html
cvs rdiff -u -r1.26 -r1.27 src/lib/libc/time/tzfile.5
cvs rdiff -u -r1.8 -r1.9 src/lib/libc/time/version
cvs rdiff -u -r1.18 -r1.19 src/lib/libc/time/zdump.8
cvs rdiff -u -r1.30 -r1.31 src/lib/libc/time/zic.8
cvs rdiff -u -r1.71 -r1.72 src/lib/libc/time/zic.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/NEWS
diff -u src/lib/libc/time/NEWS:1.25 src/lib/libc/time/NEWS:1.26
--- src/lib/libc/time/NEWS:1.25	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/NEWS	Sat Oct 27 18:29:24 2018
@@ -1,5 +1,40 @@
 News for the tz database
 
+Release 2018g - 2018-10-26 22:22:45 -0700
+
+  Briefly:
+    Morocco switches to permanent +01 on 2018-10-27.
+
+  Changes to future timestamps
+
+    Morocco switches from +00/+01 to permanent +01 effective 2018-10-27,
+    so its clocks will not fall back on 2018-10-28 as previously scheduled.
+    (Thanks to Mohamed Essedik Najd and Brian Inglis.)
+
+  Changes to code
+
+    When generating TZif files with leap seconds, zic no longer uses a
+    format that trips up older 32-bit clients, fixing a bug introduced
+    in 2018f.  (Reported by Daniel Fischer.)  Also, the zic workaround
+    for QTBUG-53071 now also works for TZif files with leap seconds.
+
+    The translator to rearguard format now rewrites the line
+    "Rule Japan 1948 1951 - Sep Sat>=8 25:00 0 S" to
+    "Rule Japan 1948 1951 - Sep Sun>=9  1:00 0 S".
+    This caters to zic before 2007 and to Oracle TZUpdater 2.2.0
+    and earlier.  (Reported by Christos Zoulas.)
+
+  Changes to past time zone abbreviations
+
+    Change HDT to HWT/HPT for WWII-era abbreviations in Hawaii.
+    This reverts to 2011h, as the abbreviation change in 2011i was
+    likely inadvertent.
+
+  Changes to documentation
+
+    tzfile.5 has new sections on interoperability issues.
+
+
 Release 2018f - 2018-10-18 00:14:18 -0700
 
   Briefly:

Index: src/lib/libc/time/theory.html
diff -u src/lib/libc/time/theory.html:1.4 src/lib/libc/time/theory.html:1.5
--- src/lib/libc/time/theory.html:1.4	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/theory.html	Sat Oct 27 18:29:24 2018
@@ -407,7 +407,7 @@ in decreasing order of importance:
       EST/EDT/EWT/EPT/EDDT Eastern [North America],
       EET/EEST Eastern European,
       GST Guam,
-      HST/HDT Hawaii,
+      HST/HDT/HWT/HPT Hawaii,
       HKT/HKST Hong Kong,
       IST India,
       IST/GMT Irish,

Index: src/lib/libc/time/tz-how-to.html
diff -u src/lib/libc/time/tz-how-to.html:1.5 src/lib/libc/time/tz-how-to.html:1.6
--- src/lib/libc/time/tz-how-to.html:1.5	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/tz-how-to.html	Sat Oct 27 18:29:24 2018
@@ -459,8 +459,8 @@ given alphabetic string.</li>
 <p>An example of a specific amount of time is:</p>
 <pre>
 #Zone NAME            GMTOFF RULES FORMAT [UNTIL]
-Zone Pacific/Honolulu ...                 1933 Apr 30 2:00
-                      -10:30 1:00  HDT    1933 May 21 2:00
+Zone Pacific/Honolulu ...                 1933 Apr 30  2:00
+                      -10:30 1:00  HDT    1933 May 21 12:00
                       ...
 </pre>
 
@@ -559,7 +559,7 @@ the true offset is undefined.
 Rule  US   1918 1919 -    Oct lastSun  2:00  0    S
 Rule  US   1942 only -    Feb  9       2:00  1:00 W # War
 Rule  US   1945 only -    Aug 14      23:00u 1:00 P # Peace
-Rule  US   1945 only -    Sep 30       2:00  0    S
+Rule  US   1945 only -    Sep lastSun  2:00  0    S
 </pre>
   </td></tr></table></td>
 </tr>
@@ -570,7 +570,7 @@ Rule  US   1945 only -    Sep 30       2
   <td colspan="6" align="center"><table><tr><td>
 <pre>
 #Zone NAME            GMTOFF    RULES FORMAT [UNTIL]
-Zone Pacific/Honolulu -10:31:26 -     LMT    1900 Jan  1 12:00
+Zone Pacific/Honolulu -10:31:26 -     LMT    1896 Jan 13 12:00
                       -10:30    -     HST    1933 Apr 30  2:00
                       -10:30    1:00  HDT    1933 May 21  2:00
                       -10:30    US    H%sT   1947 Jun  8  2:00
@@ -598,7 +598,7 @@ Zone Pacific/Honolulu -10:31:26 -     LM
   <td>&mdash;</td>
   <td>LMT</td>
   <td>local mean time</td>
-  <td>1900-01-01</td>
+  <td>1896-01-13</td>
   <td>12:00</td>
 </tr>
 <tr align="center">
@@ -607,7 +607,7 @@ Zone Pacific/Honolulu -10:31:26 -     LM
   <td>HST</td>
   <td>Hawaii standard time</td>
   <td>1933-04-30</td>
-  <td rowspan="3">02:00</td>
+  <td>02:00</td>
 </tr>
 <tr align="center">
   <td>&minus;9:30</td>
@@ -615,6 +615,7 @@ Zone Pacific/Honolulu -10:31:26 -     LM
   <td>HDT</td>
   <td>Hawaii daylight time</td>
   <td>1933-05-21</td>
+  <td>12:00</td>
 </tr>
 <tr align="center">
   <td>&minus;10:30&sup1;</td>
@@ -622,6 +623,7 @@ Zone Pacific/Honolulu -10:31:26 -     LM
   <td>HST&sup1;</td>
   <td>Hawaii standard time</td>
   <td>1942-02-09</td>
+  <td>02:00</td>
 </tr>
 <tr align="center">
   <td rowspan="2">&minus;9:30</td>

Index: src/lib/libc/time/tz-link.html
diff -u src/lib/libc/time/tz-link.html:1.2 src/lib/libc/time/tz-link.html:1.3
--- src/lib/libc/time/tz-link.html:1.2	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/tz-link.html	Sat Oct 27 18:29:24 2018
@@ -524,10 +524,11 @@ clock (intclock)</a> is a clock that dis
 under the <abbr>GPL</abbr>.</li>
 <li>Microsoft Windows 8.1
 and later has <code><abbr>tz</abbr></code> data and <abbr>CLDR</abbr>
-data (mentioned <a href="#CLDR">below</a>) used by
-<a href="https://en.wikipedia.org/wiki/Windows_Runtime";>Windows Runtime</a>
-classes such as <a
-href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.globalization.datetimeformatting.datetimeformatter.aspx";><code>DateTimeFormatter</code></a>.
+data (mentioned <a href="#CLDR">below</a>) used by the
+<a href="https://en.wikipedia.org/wiki/Windows_Runtime";>Windows Runtime</a> /
+<a href="https://en.wikipedia.org/wiki/Universal_Windows_Platform";>Universal Windows Platform</a> classes
+<a href="https://docs.microsoft.com/uwp/api/Windows.Globalization.DateTimeFormatting.DateTimeFormatter";><code>DateTimeFormatter</code></a> and
+<a href="https://docs.microsoft.com/uwp/api/windows.globalization.calendar";><code>Calendar</code></a>.
 <a id="System.TimeZoneInfo"
 href="https://blogs.msdn.microsoft.com/bclteam/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free/";>Exploring
 Windows Time Zones with <code>System.TimeZoneInfo</code></a> describes
@@ -540,6 +541,8 @@ Tzid table</a> or <a
 href="https://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml";><abbr>XML</abbr>
 file</a> of the <abbr>CLDR</abbr> data maps proprietary zone IDs
 to <code><abbr>tz</abbr></code> names.
+These mappings can be performed programmatically via the <a href="https://github.com/mj1856/TimeZoneConverter";>TimeZoneConverter</a> .NET library,
+or the ICU Java and C++ libraries mentioned <a href="#ICU">above</a>.
 <li><a
 href="https://www.oracle.com/java/index.html";>Oracle
 Java</a> contains a copy of a subset of a recent
@@ -742,6 +745,14 @@ zones &amp; daylight saving time</a>.</d
 <dd>The Hydrographic and Oceanographic Service of the Chilean Navy publishes a
 <a href="http://www.horaoficial.cl/historia_hora.html"; hreflang="es">history of
 Chile's official time (in Spanish)</a>.</dd>
+<dt>China</dt>
+<dd>The Hong Kong Observatory maintains a
+<a href="https://www.hko.gov.hk/gts/time/Summertime.htm";>history of
+ summer time in Hong Kong</a>,
+and Macau's Meteorological and Geophysical Bureau maintains a <a
+href="http://www.smg.gov.mo/smg/geophysics/e_t_Summer%20Time.htm";>similar
+history for Macau</a>.
+Unfortunately the latter is incomplete and has errors.</dd>
 <dt>Czech Republic</dt>
 <dd><a href="https://kalendar.beda.cz/kdy-zacina-a-konci-letni-cas";
 hreflang="cs">When daylight saving time starts and ends (in Czech)</a>
@@ -758,10 +769,6 @@ hreflang="he">announcements (in Hebrew)<
 <dd>The National Institute of Metrological Research maintains a
 <a href="http://oldsite.inrim.it/res/tf/ora_legale_i.shtml";>table of civil time
 (in Italian)</a>.</dd>
-<dt>Macau</dt>
-<dd>The Meteorological and Geophysical Bureau maintains a
-<a href="http://www.smg.gov.mo/smg/geophysics/e_t_Summer%20Time.htm";>history
-of summer time</a>. Unfortunately it is incomplete and has errors.</dd>
 <dt>Malaysia</dt>
 <dd>See Singapore <a href="#Singapore">below</a>.</dd>
 <dt>Mexico</dt>

Index: src/lib/libc/time/tzfile.5
diff -u src/lib/libc/time/tzfile.5:1.26 src/lib/libc/time/tzfile.5:1.27
--- src/lib/libc/time/tzfile.5:1.26	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/tzfile.5	Sat Oct 27 18:29:24 2018
@@ -1,8 +1,8 @@
-.\"	$NetBSD: tzfile.5,v 1.26 2018/10/19 23:05:35 christos Exp $
+.\"	$NetBSD: tzfile.5,v 1.27 2018/10/27 22:29:24 christos Exp $
 .\"
 .\" This file is in the public domain, so clarified as of
 .\" 1996-06-05 by Arthur David Olson ([email protected]).
-.Dd October 19, 2018
+.Dd October 27, 2018
 .Dt TZFILE 5
 .Os
 .Sh NAME
@@ -174,8 +174,202 @@ from 0 through 24.
 Second, DST is in effect all year if it starts
 January 1 at 00:00 and ends December 31 at 24:00 plus the difference
 between daylight saving and standard time.
+.Ss Interoperability considerations
 .Pp
+Version 1 files are considered a legacy format and
+should be avoided, as they do not support transition
+times after the year 2038.
+Readers that only understand Version 1 must ignore
+any data that extends beyond the calculated end of the version
+1 data block.
+.PP
+Writers should generate a version 3 file if
+TZ string extensions are necessary to accurately
+model transition times.
+Otherwise, version 2 files should be generated.
+.Pp
+The sequence of time changes defined by the version 1
+header and data block should be a contiguous subsequence
+of the time changes defined by the version 2+ header and data
+block, and by the footer.
+This guideline helps obsolescent version 1 readers
+agree with current readers about timestamps within the
+contiguous subsequence.  It also lets writers not
+supporting obsolescent readers use a
+.Dv tzh_timecnt
+of zero
+in the version 1 data block to save space.
+.Pp
+Time zone designations should consist of at least three (3)
+and no more than six (6) ASCII characters from the set of
+alphanumerics,
+.Dq \&- ,
+and
+.Dq + .
+This is for compatibility with POSIX requirements for
+time zone abbreviations.
+.Pp
+When reading a version 2 or 3 file, readers
+should ignore the version 1 header and data block except for
+the purpose of skipping over them.
+.Pp
+Readers should calculate the total lengths of the
+headers and data blocks and check that they all fit within
+the actual file size, as part of a validity check for the file.
+.Ss Common interoperability issues
+This section documents common problems in reading or writing TZif files.
+Most of these are problems in generating TZif files for use by
+older readers.
+The goals of this section are:
+.Bl -bullet
+.It
+to help TZif writers output files that avoid common
+pitfalls in older or buggy TZif readers,
+.It
+to help TZif readers avoid common pitfalls when reading
+files generated by future TZif writers, and
+.It
+to help any future specification authors see what sort of
+problems arise when the TZif format is changed.
+.El
+.Pp
++When new versions of the TZif format have been defined, a
+design goal has been that a reader can successfully use a TZif
+file even if the file is of a later TZif version than what the
+reader was designed for.
+When complete compatibility was not achieved, an attempt was
+made to limit glitches to rarely-used timestamps, and to allow
+simple partial workarounds in writers designed to generate
+new-version data useful even for older-version readers.
+This section attempts to document these compatibility issues and
+workarounds, as well as to document other common bugs in
+readers.
+.Pp
+Interoperability problems with TZif include the following:
+.Bl -bullet
+.It
+Some readers examine only version 1 data.
+As a partial workaround, a writer can output as much version 1
+data as possible.
+However, a reader should ignore version 1 data, and should use
+version 2+ data even if the reader's native timestamps have only
+32 bits.
+.It
+Some readers designed for version 2 might mishandle
+timestamps after a version 3 file's last transition, because
+they cannot parse extensions to POSIX in the TZ-like string.
+As a partial workaround, a writer can output more transitions
+than necessary, so that only far-future timestamps are
+mishandled by version 2 readers.
+.It
+Some readers designed for version 2 do not support
+permanent daylight saving time, e.g., a TZ string
+.Dq EST5EDT,0/0,J365/25
+denoting permanent Eastern Daylight Time (\&-04).
+As a partial workaround, a writer can substitute standard time
+for the next time zone east, e.g.,
+.Dq AST4
++for permanent Atlantic Standard Time (\&-04).
+.It
+Some readers ignore the footer, and instead predict future
+timestamps from the time type of the last transition.
+As a partial workaround, a writer can output more transitions
+than necessary.
+.It
+Some readers do not use time type 0 for timestamps before
+the first transition, in that they infer a time type using a
+heuristic that does not always select time type 0.
+As a partial workaround, a writer can output a dummy (no-op)
+first transition at an early time.
+.It
+Some readers mishandle timestamps before the first
+transition that has a timestamp not less than -2**31.
+Readers that support only 32-bit timestamps are likely to be
+more prone to this problem, for example, when they process
+64-bit transitions only some of which are representable in 32
+bits.
+As a partial workaround, a writer can output a dummy
+transition at timestamp \&-2**31.
+.It
+Some readers mishandle a transition if its timestamp has
+the minimum possible signed 64-bit value.
+Timestamps less than \&-2**59 are not recommended.
+.It
+Some readers mishandle POSIX-style TZ strings that
+contain
+.Dq <
+or
+.Dq > .
+As a partial workaround, a writer can avoid using
+.Dq <
+or
+.Dq >
+for time zone abbreviations containing only alphabetic
+characters.
+.Pp
+Many readers mishandle time zone abbreviations that contain
+non-ASCII characters.
+These characters are not recommended.
+.Pp
+Some readers may mishandle time zone abbreviations that
+contain fewer than 3 or more than 6 characters, or that
+contain ASCII characters other than alphanumerics,
+.Dq \&- .
+and
+.Dq + .
+These abbreviations are not recommended.
+.It
+Some readers mishandle TZif files that specify
+daylight-saving time UT offsets that are less than the UT
+offsets for the corresponding standard time.
+These readers do not support locations like Ireland, which
+uses the equivalent of the POSIX TZ string
+.Dq IST\&-1GMT0,M10.5.0,M3.5.0/1 ,
+observing standard time
+(IST, +01) in summer and daylight saving time (GMT, +00) in winter.
+As a partial workaround, a writer can output data for the
+equivalent of the POSIX TZ string
+.Dq GMT0IST,M3.5.0/1,M10.5.0 ,
+thus swapping standard and daylight saving time.
+Although this workaround misidentifies which part of the year
+uses daylight saving time, it records UT offsets and time zone
+abbreviations correctly.
+.El
+.Pp
+Some interoperability problems are reader bugs that
+are listed here mostly as warnings to developers of readers.
+.Bl -bullet
+.It
+Some readers do not support negative timestamps.
+Developers of distributed applications should keep this
+in mind if they need to deal with pre-1970 data.
+.It
+Some readers mishandle timestamps before the first
+transition that has a nonnegative timestamp.
+Readers that do not support negative timestamps are likely to
+be more prone to this problem.
+.It
++Some readers mishandle time zone abbreviations like
+.Dq \&-08
+that contain
+.Dq + ,
+.Dq \&- ,
+or digits.
+.It
+Some readers mishandle UT offsets that are out of the
+traditional range of \*-12 through +12 hours, and so do not
+support locations like Kiritimati that are outside this
+range.
+.It
+Some readers mishandle UT offsets in the range [\*-3599, \*-1]
+seconds from UT, because they integer-divide the offset by
+3600 to get 0 and then display the hour part as
+.Dq +00 .
+.It
+Some readers mishandle UT offsets that are not a multiple
+of one hour, or of 15 minutes, or of 1 minute.
 Future changes to the format may append more data.
+.El
 .Sh SEE ALSO
 .Xr ctime 3 ,
 .Xr localtime 3 ,

Index: src/lib/libc/time/version
diff -u src/lib/libc/time/version:1.8 src/lib/libc/time/version:1.9
--- src/lib/libc/time/version:1.8	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/version	Sat Oct 27 18:29:24 2018
@@ -1 +1 @@
-2018f
+2018g

Index: src/lib/libc/time/zdump.8
diff -u src/lib/libc/time/zdump.8:1.18 src/lib/libc/time/zdump.8:1.19
--- src/lib/libc/time/zdump.8:1.18	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/zdump.8	Sat Oct 27 18:29:24 2018
@@ -1,5 +1,5 @@
-.\"	$NetBSD: zdump.8,v 1.18 2018/10/19 23:05:35 christos Exp $
-.Dd October 19, 2018
+.\"	$NetBSD: zdump.8,v 1.19 2018/10/27 22:29:24 christos Exp $
+.Dd October 27, 2018
 .Dt ZDUMP 8
 .Os
 .Sh NAME
@@ -147,13 +147,14 @@ tabbed columns line up.)
 .Bd -literal
 TZ="Pacific/Honolulu"
 .Ed
-.Bl -column "XXXX-XX-XX" "HH:MM:SS" "-HH:MM:SS" "TZT" "X" -compact
-.It - Ta - Ta -10:31:26 Ta LMT Ta
-.It 1896-01-13 Ta 12:01:26 Ta -10:30 Ta HST Ta
-.It 1933-04-30 Ta 03 Ta -09:30 Ta HDT Ta 1
-.It 1933-05-21 Ta 11 Ta -10:30 Ta HST Ta
-.It 1942-02-09 Ta 03 Ta -09:30 Ta HDT Ta 1
-.It 1945-09-30 Ta 01 Ta -10:30 Ta HST Ta
+.Bl -column "XXXX-XX-XX" "HH:MM:SS" "-HHMMSS" "TZT" "X" -compact
+.It - Ta - Ta -103126 Ta LMT Ta
+.It 1896-01-13 Ta 12:01:26 Ta -1030 Ta HST Ta
+.It 1933-04-30 Ta 03 Ta -0930 Ta HDT Ta 1
+.It 1933-05-21 Ta 11 Ta -1030 Ta HST Ta
+.It 1942-02-09 Ta 03 Ta -0930 Ta HDT Ta 1
+.It 1945-08-14 Ta 13:30 Ta -0930 Ta HPT Ta 1
+.It 1945-09-30 Ta 01 Ta -1030 Ta HST Ta
 .It 1947-06-08 Ta 02:30 Ta -10 Ta HST Ta
 .El
 .Pp
@@ -174,7 +175,7 @@ Here are excerpts from another example:
 TZ="Europe/Astrakhan"
 .Ed
 .Bl -column "XXXX-XX-XX" "HH:MM:SS" "-HH:MM:SS" "TZT" "X" -compact
-.It - Ta - Ta +03:12:12 Ta LMT Ta
+.It - Ta - Ta +031212 Ta LMT Ta
 .It 1924-04-30 Ta 23:47:48 Ta +03 Ta Ta
 .It 1930-06-21 Ta 01 Ta +04 Ta Ta
 .It 1981-04-01 Ta 01 Ta +05 Ta Ta 1

Index: src/lib/libc/time/zic.8
diff -u src/lib/libc/time/zic.8:1.30 src/lib/libc/time/zic.8:1.31
--- src/lib/libc/time/zic.8:1.30	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/zic.8	Sat Oct 27 18:29:24 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: zic.8,v 1.30 2018/10/19 23:05:35 christos Exp $
+.\"	$NetBSD: zic.8,v 1.31 2018/10/27 22:29:24 christos Exp $
 .Dd October 19, 2018
 .Dt ZIC 8
 .Os
@@ -295,6 +295,10 @@ or
 if the given time is universal time;
 in the absence of an indicator,
 wall clock time is assumed.
+These forms ignore leap seconds; for example,
+if a leap second occurs at 00:59:60 local time,
+.q "1:00"
+stands for 3601 seconds after local midnight instead of the usual 3600 seconds.
 The intent is that a rule line describes the instants when a
 clock/calendar set to the type of time specified in the
 .Em AT

Index: src/lib/libc/time/zic.c
diff -u src/lib/libc/time/zic.c:1.71 src/lib/libc/time/zic.c:1.72
--- src/lib/libc/time/zic.c:1.71	Fri May  4 11:51:00 2018
+++ src/lib/libc/time/zic.c	Sat Oct 27 18:29:24 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: zic.c,v 1.71 2018/05/04 15:51:00 christos Exp $	*/
+/*	$NetBSD: zic.c,v 1.72 2018/10/27 22:29:24 christos Exp $	*/
 /*
 ** This file is in the public domain, so clarified as of
 ** 2006-07-17 by Arthur David Olson.
@@ -10,7 +10,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: zic.c,v 1.71 2018/05/04 15:51:00 christos Exp $");
+__RCSID("$NetBSD: zic.c,v 1.72 2018/10/27 22:29:24 christos Exp $");
 #endif /* !defined lint */
 
 #include "private.h"
@@ -73,6 +73,11 @@ typedef int_fast64_t	zic_t;
 static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t));
 #endif
 
+/* The minimum alignment of a type, for pre-C11 platforms.  */
+#if __STDC_VERSION__ < 201112
+# define _Alignof(type) offsetof(struct { char a; type b; }, b)
+#endif
+
 /* The type for line numbers.  Use PRIdMAX to format them; formerly
    there was also "#define PRIdLINENO PRIdMAX" and formats used
    PRIdLINENO, but xgettext cannot grok that.  */
@@ -199,7 +204,9 @@ enum { PERCENT_Z_LEN_BOUND = sizeof "+99
    QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>.  This
    workaround will no longer be needed when Qt 5.6.1 and earlier are
    obsolete, say in the year 2021.  */
+#ifndef WORK_AROUND_QTBUG_53071
 enum { WORK_AROUND_QTBUG_53071 = 1 };
+#endif
 
 static int		charcnt;
 static bool		errors;
@@ -441,6 +448,16 @@ size_product(size_t nitems, size_t items
 	return nitems * itemsize;
 }
 
+static ATTRIBUTE_PURE size_t
+align_to(size_t size, size_t alignment)
+{
+  size_t aligned_size = size + alignment - 1;
+  aligned_size -= aligned_size % alignment;
+  if (aligned_size < size)
+    memory_exhausted(_("alignment overflow"));
+  return aligned_size;
+}
+
 #if !HAVE_STRDUP
 static char *
 strdup(char const *str)
@@ -1761,12 +1778,6 @@ atcomp(const void *avp, const void *bvp)
 	return (a < b) ? -1 : (a > b);
 }
 
-static bool
-is32(const zic_t x)
-{
-	return INT32_MIN <= x && x <= INT32_MAX;
-}
-
 static void
 writezone(const char *const name, const char *const string, char version)
 {
@@ -1781,7 +1792,11 @@ writezone(const char *const name, const 
 	zic_t one = 1;
 	zic_t y2038_boundary = one << 31;
 	ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
-	zic_t *ats = zic_malloc(size_product(nats, sizeof *ats + 1));
+
+	/* Allocate the ATS and TYPES arrays via a single malloc,
+	   as this is a bit faster.  */
+	zic_t *ats = zic_malloc(align_to(size_product(nats, sizeof *ats + 1),
+				_Alignof(zic_t)));
 	void *typesptr = ats + nats;
 	unsigned char *types = typesptr;
 
@@ -1834,18 +1849,6 @@ writezone(const char *const name, const 
 		types[i] = attypes[i].type;
 	}
 
-	/* Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
-	   by inserting a no-op transition at time y2038_boundary - 1.
-	   This works only for timestamps before the boundary, which
-	   should be good enough in practice as QTBUG-53071 should be
-	   long-dead by 2038.  */
-	if (WORK_AROUND_QTBUG_53071 && timecnt != 0
-	    && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
-	  ats[timecnt] = y2038_boundary - 1;
-	  types[timecnt] = types[timecnt - 1];
-	  timecnt++;
-	}
-
 	/*
 	** Correct for leap seconds.
 	*/
@@ -1857,6 +1860,22 @@ writezone(const char *const name, const 
 				break;
 			}
 	}
+
+	/* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1,
+	   by inserting a no-op transition at time y2038_boundary - 1.
+	   This works only for timestamps before the boundary, which
+	   should be good enough in practice as QTBUG-53071 should be
+	   long-dead by 2038.  Do this after correcting for leap
+	   seconds, as the idea is to insert a transition just before
+	   32-bit time_t rolls around, and this occurs at a slightly
+	   different moment if transitions are leap-second corrected.  */
+	if (WORK_AROUND_QTBUG_53071 && timecnt != 0
+	    && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
+	  ats[timecnt] = y2038_boundary - 1;
+	  types[timecnt] = types[timecnt - 1];
+	  timecnt++;
+	}
+
 	/*
 	** Figure out 32-bit-limited starts and counts.
 	*/
@@ -1864,22 +1883,22 @@ writezone(const char *const name, const 
 	timei32 = 0;
 	leapcnt32 = leapcnt;
 	leapi32 = 0;
-	while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
+	while (0 < timecnt32 && INT32_MAX < ats[timecnt32 - 1])
 		--timecnt32;
-	while (timecnt32 > 0 && !is32(ats[timei32])) {
+	while (1 < timecnt32 && ats[timei32] < INT32_MIN
+	       && ats[timei32 + 1] <= INT32_MIN) {
+		/* Discard too-low transitions, except keep any last too-low
+		   transition if no transition is exactly at INT32_MIN.
+		   The kept transition will be output as an INT32_MIN
+		   "transition" appropriate for buggy 32-bit clients that do
+		   not use time type 0 for timestamps before the first
+		   transition; see below.  */
 		--timecnt32;
 		++timei32;
 	}
-	/*
-	** Output an INT32_MIN "transition" if appropriate; see below.
-	*/
-	if (timei32 > 0 && ats[timei32] > INT32_MIN) {
-		--timei32;
-		++timecnt32;
-	}
-	while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
+	while (0 < leapcnt32 && INT32_MAX < trans[leapcnt32 - 1])
 		--leapcnt32;
-	while (leapcnt32 > 0 && !is32(trans[leapi32])) {
+	while (0 < leapcnt32 && trans[leapi32] < INT32_MIN) {
 		--leapcnt32;
 		++leapi32;
 	}

Reply via email to