[tz] [PROPOSED 1/3] Don’t reject TZif TZ strings that lack DST

Paul Eggert eggert at cs.ucla.edu
Tue Jun 5 00:28:31 UTC 2018


* NEWS: Mention this.
* localtime.c (tzloadbody): Don’t require a TZif file’s POSIX TZ
string to specify DST.  That way, the TZ string consistently
overrides the type of the TZif file’s last transition, instead of
overriding only when specifying DST.  Although this currently
matters only for invalid TZif files where the TZ string disagrees
with the last transition’s time type, it will become more
important if we stop requiring at least one time type in the
binary data, as the TZ string will then be the only source for
time types.
---
 NEWS        |  6 ++++++
 localtime.c | 11 +++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index ce009e7..2e9bf99 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,12 @@ Unreleased, experimental changes
     legacy zones EST5EDT, CST6CDT, MST7MDT, PST8PDT, CET, MET, and
     EET, which previously used nonzero types for these timestamps.
 
+    localtime.c no longer ignores TZif POSIX-style TZ strings that
+    specify only standard time.  Instead, these TZ strings now
+    override the default time type for timestamps after the last
+    transition (or for all time stamps if there are no transitions),
+    just as DST strings specifying DST have always done.
+
   Changes to documentation
 
     New restrictions: A Rule name must start with a character that
diff --git a/localtime.c b/localtime.c
index 21160c0..5a3fe91 100644
--- a/localtime.c
+++ b/localtime.c
@@ -587,8 +587,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 			struct state	*ts = &lsp->u.st;
 
 			up->buf[nread - 1] = '\0';
-			if (tzparse(&up->buf[1], ts, false)
-			    && ts->typecnt == 2) {
+			if (tzparse(&up->buf[1], ts, false)) {
 
 			  /* Attempt to reuse existing abbreviations.
 			     Without this, America/Anchorage would be right on
@@ -599,7 +598,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 			     stay 40 in this example.  */
 			  int gotabbr = 0;
 			  int charcnt = sp->charcnt;
-			  for (i = 0; i < 2; i++) {
+			  for (i = 0; i < ts->typecnt; i++) {
 			    char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
 			    int j;
 			    for (j = 0; j < charcnt; j++)
@@ -618,7 +617,7 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 			      }
 			    }
 			  }
-			  if (gotabbr == 2) {
+			  if (gotabbr == ts->typecnt) {
 			    sp->charcnt = charcnt;
 
 			    /* Ignore any trailing, no-op transitions generated
@@ -640,8 +639,8 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 			      sp->timecnt++;
 			      i++;
 			    }
-			    sp->ttis[sp->typecnt++] = ts->ttis[0];
-			    sp->ttis[sp->typecnt++] = ts->ttis[1];
+			    for (i = 0; i < ts->typecnt; i++)
+			      sp->ttis[sp->typecnt++] = ts->ttis[i];
 			  }
 			}
 	}
-- 
2.17.1



More information about the tz mailing list