[tz] tzcode-2014c breaks applications that use the binary tz files

Paul Eggert eggert at cs.ucla.edu
Sun May 25 19:25:06 UTC 2014


lennox at cs.columbia.edu wrote:
> My only concern would be whether anything doing GNOME-style behavior then
> wants to pass the minimum timestamp to localtime() or the like, which will
> fail for timestamps repesenting years earlier than -2^31  - 1900.

Thanks, that is a possible bug that I hadn't considered.  Unfortunately 
that boundary's value is INT_MIN - 1900, and INT_MIN isn't necessarily 
-2**31.  For example, on Unisys ClearPath enterprise servers INT_MIN is 
1 - 2**39; because tz binary files are supposed to be usable even on 
these unusual platforms, hardwiring -2**31 - 1900 into them would cause 
an unwanted glitch at the 32-bit boundary on these platforms.

Conversely, if we used the conservative boundary -32767 - 1900 (which 
the C standard says should be representable on all platforms), we would 
insert an unwanted glitch on nearly every platform.  And even on the 
oddball platform where INT_MIN == -32767 there could be problems within 
a few hours of the boundary, due to software being confused about 
localtime succeeding but gmtime failing or vice versa.

I think this possible bug is less likely than the GNOME bug, so I'm 
inclined try the Big Bang and see whether it breaks anything compared to 
2014b.  If not, we can declare victory; otherwise, we can look into 
adjusting the boundary according to whatever other library bug we run into.

In private email, Arthur David Olson pointed out that zic would still 
let pre-Big-Bang leap seconds slip through; the attached further patch 
(which I've pushed to the experimental repository) fixes this.
-------------- next part --------------
From 0880e2fe56f4f6b1cd8423e555f17fd0f3ba636e Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Sun, 25 May 2014 12:20:29 -0700
Subject: [PATCH] zic: disallow leap seconds before the Big Bang

* zic.c (inleap): Reject leap seconds preceding big_bang_time.
(Thanks to Arthur David Olson.)  Also, remove redundant test and cast.
* NEWS: Document this.
---
 NEWS  |  2 ++
 zic.c | 13 +++++++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 95db5f9..413a4db 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Unreleased, experimental changes
     zic no longer generates files containing time stamps before the Big Bang.
     This works around GNOME bug 730332
     <https://bugzilla.gnome.org/show_bug.cgi?id=730332>.
+    (Thanks to Leonardo Chiquitto for reporting the bug, and to
+    Arthur David Olson for suggesting an improvement to the fix.)
 
 
 Release 2014c - 2014-05-13 07:44:13 -0700
diff --git a/zic.c b/zic.c
index 6112002..179e4f5 100644
--- a/zic.c
+++ b/zic.c
@@ -1202,10 +1202,6 @@ inleap(register char ** const fields, const int nfields)
 			return;
 	}
 	dayoff = oadd(dayoff, day - 1);
-	if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
-		error(_("time before zero"));
-		return;
-	}
 	if (dayoff < min_time / SECSPERDAY) {
 		error(_("time too small"));
 		return;
@@ -1214,7 +1210,7 @@ inleap(register char ** const fields, const int nfields)
 		error(_("time too large"));
 		return;
 	}
-	t = (zic_t) dayoff * SECSPERDAY;
+	t = dayoff * SECSPERDAY;
 	tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
 	cp = fields[LP_CORR];
 	{
@@ -1243,7 +1239,12 @@ inleap(register char ** const fields, const int nfields)
 				));
 			return;
 		}
-		leapadd(tadd(t, tod), positive, lp->l_value, count);
+		t = tadd(t, tod);
+		if (t < big_bang_time) {
+			error(_("leap second precedes Big Bang"));
+			return;
+		}
+		leapadd(t, positive, lp->l_value, count);
 	}
 }
 
-- 
1.9.1


More information about the tz mailing list