6c0556
commit c36f64aa6dff13b12a1e03a185e75a50fa9f6a4c
6c0556
Author: Hans-Peter Nilsson <hp@axis.com>
6c0556
Date:   Fri Dec 17 21:38:00 2021 +0100
6c0556
6c0556
    timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707)
6c0556
    
6c0556
    When using a timezone file with a truncated starting time,
6c0556
    generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d
6c0556
    (also in tzlib-2021e; current as of this writing), glibc
6c0556
    asserts in __tzfile_read (on e.g. tzset() for this file) and
6c0556
    you may find lines matching "tzfile.c:435: __tzfile_read:
6c0556
    Assertion `num_types == 1' failed" in your syslog.
6c0556
    
6c0556
    One example of such a file is the tzfile for Asuncion
6c0556
    generated by tzlib-2021e as follows, using the tzlib-2021e zic:
6c0556
    "zic -d DEST -r @1546300800 -L /dev/null -b slim
6c0556
    SOURCE/southamerica".  Note that in its type 2 header, it has
6c0556
    two entries in its "time-types" array (types), but only one
6c0556
    entry in its "transition types" array (type_idxs).
6c0556
    
6c0556
    This is valid and expected already in the published RFC8536, and
6c0556
    not even frowned upon: "Local time for timestamps before the
6c0556
    first transition is specified by the first time type (time type
6c0556
    0)" ... "every nonzero local time type index SHOULD appear at
6c0556
    least once in the transition type array".  Note the "nonzero ...
6c0556
    index".  Until the 2021d zic, index 0 has been shared by the
6c0556
    first valid transition but with 2021d it's separate, set apart
6c0556
    as a placeholder and only "implicitly" indexed.  (A draft update
6c0556
    of the RFC mandates that the entry at index 0 is a placeholder
6c0556
    in this case, hence can no longer be shared.)
6c0556
    
6c0556
            * time/tzfile.c (__tzfile_read): Don't assert when no transitions
6c0556
            are found.
6c0556
    
6c0556
    Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
6c0556
6c0556
diff --git a/time/tzfile.c b/time/tzfile.c
6c0556
index 190a777152..8668392ad3 100644
6c0556
--- a/time/tzfile.c
6c0556
+++ b/time/tzfile.c
6c0556
@@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
6c0556
   if (__tzname[0] == NULL)
6c0556
     {
6c0556
       /* This should only happen if there are no transition rules.
6c0556
-	 In this case there should be only one single type.  */
6c0556
-      assert (num_types == 1);
6c0556
+	 In this case there's usually only one single type, unless
6c0556
+	 e.g. the data file has a truncated time-range.  */
6c0556
       __tzname[0] = __tzstring (zone_names);
6c0556
     }
6c0556
   if (__tzname[1] == NULL)