[tz] [PROPOSED] Fix zic bug with -r @X where X is deduced from TZ
Paul Eggert
eggert at cs.ucla.edu
Mon Nov 27 19:55:04 UTC 2023
Problem reported by Ken Murchison for ‘zic -b slim -r @2145916800 asia’,
which generated an Asia/Jerusalem TZif file with a single
transition from -00 to IDT at 2145916800 (2038-01-01 00:00:00 UTC).
The transition should be to IST.
* NEWS: Mention this.
* zic.c (main): Don’t let redundant_time be lower than lo_time.
(outzone): Fix code for omitting trailing transitions when -R is
specified, which was inadvertently messed up by the 2023-10-15 fix
for Palestine after 2075.
---
NEWS | 3 ++-
zic.c | 15 +++++++++++----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/NEWS b/NEWS
index 0d7fde80..c07cc7ad 100644
--- a/NEWS
+++ b/NEWS
@@ -37,7 +37,8 @@ Unreleased, experimental changes
zic no longer mishandles data for Palestine after the year 2075.
Previously, it incorrectly omitted post-2075 transitions that are
- predicted for just before and just after Ramadan.
+ predicted for just before and just after Ramadan. (Thanks to Ken
+ Murchison for debugging help.)
zic now works again on Linux 2.6.16 and 2.6.17 (2006).
(Problem reported by Rune Torgersen.)
diff --git a/zic.c b/zic.c
index e10cb21b..b260851f 100644
--- a/zic.c
+++ b/zic.c
@@ -897,7 +897,8 @@ static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
-/* The time specified by the -R option, defaulting to MIN_TIME. */
+/* The time specified by the -R option, defaulting to MIN_TIME;
+ or lo_time, whichever is greater. */
static zic_t redundant_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
/* The time specified by an Expires line, or negative if no such line. */
@@ -1109,6 +1110,8 @@ main(int argc, char **argv)
fprintf(stderr, _("%s: -R time exceeds -r cutoff\n"), progname);
return EXIT_FAILURE;
}
+ if (redundant_time < lo_time)
+ redundant_time = lo_time;
if (bloat == 0) {
static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
if (strcmp(bloat_default, "slim") == 0)
@@ -3442,6 +3445,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (defaulttype < 0)
defaulttype = 0;
if (!do_extend && !want_bloat()) {
+ /* Keep trailing transitions that are no greater than this. */
+ zic_t keep_at_max;
+
/* The earliest transition into a time governed by the TZ string. */
zic_t TZstarttime = ZIC_MAX;
for (i = 0; i < timecnt; i++) {
@@ -3452,10 +3458,11 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
if (TZstarttime == ZIC_MAX)
TZstarttime = nonTZlimtime;
- /* Omit trailing transitions deducible from the TZ string. */
+ /* Omit trailing transitions deducible from the TZ string,
+ and not needed for -r or -R. */
+ keep_at_max = max(TZstarttime, redundant_time);
for (i = j = 0; i < timecnt; i++)
- if (redundant_time <= attypes[i].at
- && attypes[i].at <= TZstarttime) {
+ if (attypes[i].at <= keep_at_max) {
attypes[j].at = attypes[i].at;
attypes[j].dontmerge = (attypes[i].at == TZstarttime
&& (nonTZlimtype != attypes[i].type
--
2.40.1
More information about the tz
mailing list