[PROPOSED] Fix zic bug with -r @X where X is deduced from TZ

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
participants (1)
-
Paul Eggert