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