[tz] [PATCH 3/7] Fix unlikely Y2038 leap second bug

Paul Eggert eggert at cs.ucla.edu
Wed Mar 17 01:46:01 UTC 2021


* NEWS: Mention this.
* localtime.c (tzloadbody): Don’t misbehave if adding the
leap second correction overflows time_t.
---
 NEWS        |  4 ++++
 localtime.c | 19 +++++++++----------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index d8676e6..5b26bd2 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,10 @@ Unreleased, experimental changes
     set to a POSIX-conforming but unusual TZ string like
     "EST5EDT4,0/0,J365/0", where almost all the year is DST.
 
+    Fix an unlikely bug that caused 'localtime' etc. to misbehave if
+    civil time changes a few seconds before time_t wraps around, when
+    leap seconds are enabled.
+
     Fix bug in zic -r; in some cases, the dummy time type after the
     last time transition disagreed with the TZ string, contrary to
     Internet RFC 8563 section 3.3.
diff --git a/localtime.c b/localtime.c
index 5b8f278..0d34ead 100644
--- a/localtime.c
+++ b/localtime.c
@@ -639,19 +639,18 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 				       == sp->types[sp->timecnt - 2]))
 			      sp->timecnt--;
 
-			    for (i = 0; i < ts->timecnt; i++)
-			      if (sp->timecnt == 0
-				  || (sp->ats[sp->timecnt - 1]
-				      < ts->ats[i] + leapcorr(sp, ts->ats[i])))
-				break;
-			    while (i < ts->timecnt
-				   && sp->timecnt < TZ_MAX_TIMES) {
-			      sp->ats[sp->timecnt]
-				= ts->ats[i] + leapcorr(sp, ts->ats[i]);
+			    for (i = 0;
+				 i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES;
+				 i++) {
+			      time_t t = ts->ats[i];
+			      if (increment_overflow_time(&t, leapcorr(sp, t))
+				  || (0 < sp->timecnt
+				      && t <= sp->ats[sp->timecnt - 1]))
+				continue;
+			      sp->ats[sp->timecnt] = t;
 			      sp->types[sp->timecnt] = (sp->typecnt
 							+ ts->types[i]);
 			      sp->timecnt++;
-			      i++;
 			    }
 			    for (i = 0; i < ts->typecnt; i++)
 			      sp->ttis[sp->typecnt++] = ts->ttis[i];
-- 
2.27.0



More information about the tz mailing list