[Feature Request] Add validation in zic for invalid DST intervals
Hello tzdata maintainers, I would like to propose a feature enhancement for the zic compiler. Currently, the NOS time zone rules are defined as: Rule NOS 1970 2037 - Jan 27 23:43:01 2:0 SDST Rule NOS 1970 2037 - Jan 28 0:51:01 0 S Zone OS/NOS +7:0:0 NOS NO%s Issue: - The first rule enters DST at 23:43:01 with a +2 hour offset, moving local time to 01:43:01. - The second rule is intended to revert to standard time at 00:51:01. - Due to the offset, 00:51:01 local time never occurs, so the second rule will never trigger. - This creates unreachable local times and may cause incorrect results in time calculations. Proposal: - Add validation in the zic command to detect DST rules where the offset causes the subsequent rule's local time to be unreachable. - The validation could issue a warning or error to alert the author of potentially invalid rules. - This would improve the robustness of time zone definitions and prevent subtle bugs in downstream applications. Thank you for your consideration. Best regards
On 2025-10-10 05:34, 任春辉 via tz wrote:
Proposal:
- Add validation in the zic command to detect DST rules where the offset causes the subsequent rule's local time to be unreachable.
Something like that could be useful, yes. It might be a bit tricky, though. If someone proposed code changes along those lines I'd be happy to review the changes.
Hi, Thank you for the earlier discussion and guidance. I would like to clarify my current thinking and ask specifically about the feasibility of a possible approach. Rather than treating zdump as a separate “strict validator” while keeping zic intentionally permissive, my idea is to explore whether zic itself could optionally reuse the same tzfile loading path that zdump uses, purely as a post-generation sanity check. Concretely, the idea would be: - zic generates a tzfile as it does today. - Immediately after generation, zic invokes the same internal loading logic used by zdump (e.g., tzset/localtime paths) on that file. - If loading fails catastrophically (e.g., assertion failures or aborts that would later be triggered by zdump or runtime loaders), zic could report an error or warning and avoid installing the file. The motivation here is not to make zic stricter in terms of rule semantics, nor to add rule-specific validation (such as DST-only checks), but simply to catch tzfiles that are internally inconsistent enough to cause runtime aborts when loaded. From an engineering perspective, this would act as a sanity check using existing code paths, rather than introducing new semantic validation rules. My questions are therefore: - Would reusing zdump-style loading logic inside zic as an optional or internal post-generation check be acceptable from the tzdata design perspective? - Are there architectural, portability, or policy reasons why zic should not invoke such runtime loading logic, even in a limited and optional way? - If this approach is not appropriate, is the preferred expectation that downstream users run tools like zdump separately to detect such failures? I would appreciate any guidance on whether this direction makes sense before exploring a concrete implementation. Best regards, Chunhui Ren
On 2025-12-16 18:45, renchunhui2025--- via tz wrote:
Rather than treating zdump as a separate “strict validator” while keeping zic intentionally permissive, my idea is to explore whether zic itself could optionally reuse the same tzfile loading path that zdump uses, purely as a post-generation sanity check.
There would be licensing issues, as zic.c is public domain whereas glibc tzfile.c is distributed under the GNU Lesser General Public License.
the idea would be:
- zic generates a tzfile as it does today. - Immediately after generation, zic invokes the same internal loading logic used by zdump (e.g., tzset/localtime paths) on that file.
This internal loading logic is different in each OS, and we sometimes lack access to the source code (even aside from licensing issues), so doing this well would be a tricky business.
The motivation here is not to make zic stricter in terms of rule semantics, nor to add rule-specific validation (such as DST-only checks), but simply to catch tzfiles that are internally inconsistent enough to cause runtime aborts when loaded.
Simpler, I think, would be for whatever procedure that runs zic, to run zdump afterwards. This avoids the licensing issues, and no change to zic's or zdump's source code or build procedure is needed. It would be helpful to test zic's output with other TZif readers as well; please see <https://data.iana.org/time-zones/tz-link.html#TZif> for a list. TZDB already does this sort of thing when you run commands like 'make check', which uses the main TZDB data to test zdump on zic's output. I hope these comments help, and thanks for the test case and questions.
Hello tzdata maintainers, Following up on the issue I reported earlier, I would like to share some additional findings and ask for your guidance on a possible approach. After further investigation, we found that zdump is actually able to comprehensively detect invalid tzfiles, including cases that may later trigger aborts at runtime. In particular, when zdump loads certain malformed tzfiles, it can hit assertions in tzfile.c and abort with exit code 134, effectively acting as a strict validator for tzfile correctness. For example, with the following rules: Rule NOS 1970 2037 - Jan 27 23:43:01 2:0 SDST Rule NOS 1970 2037 - Jan 28 0:51:01 0 S Zone OS/NOS +7:0:0 NOS NO%s Although zic successfully generates a tzfile, loading this file via zdump can result in an abort due to unreachable local times created by the DST offset transition. This indicates that zdump already exercises a more complete validation path than zic itself. Based on this, we are considering whether it would be reasonable to: Reuse the zdump loading path (or equivalent internal logic) to validate tzfiles immediately after zic generates them. Detect invalid tzfiles early, before they are installed or used by applications. Avoid adding rule-specific checks (e.g. DST-only validation), since zdump appears capable of catching a broader class of invalid timezone data. Before proceeding further, I would like to ask for your opinion: Do you think it makes sense to add an optional or internal validation step in zic based on zdump-style loading? Is this approach acceptable from the tzdata design perspective, or is zic intentionally permissive while zdump is expected to catch such issues? Are there any existing constraints or concerns (performance, portability, semantics) that would argue against this approach? Any guidance or feedback would be greatly appreciated before we explore a concrete implementation. Thank you for your time and for maintaining tzdata. Best regards, Renchunhui
On 2025-12-16 00:10, renchunhui2025--- via tz wrote:
After further investigation, we found that zdump is actually able to comprehensively detect invalid tzfiles, including cases that may later trigger aborts at runtime.
Thanks for looking into this. However, I doubt whether any zdump implementation does a comprehensive test, in the sense of checking for strict conformance to every requirement specified by Internet RFC 9636. More likely, each zdump implementation checks only for problems of concern to it.
when zdump loads certain malformed tzfiles, it can hit assertions in tzfile.c and abort with exit code 134
tzfile.c is not part of tzcode so I assume you're talking about the GNU C Library's tzfile.c, which is a TZif file reader. I could not reproduce the problem that you mentioned: when I built TZDB zdump like this: make clean make CFLAGS='-DUSE_LTZ=0' TZDOBJS=zdump.o zdump on Fedora 42 x86-64, which has glibc-2.41-11.fc42.x86_64, zdump did not hit any assertions with the test case you provided, namely:
Rule NOS 1970 2037 - Jan 27 23:43:01 2:0 SDST Rule NOS 1970 2037 - Jan 28 0:51:01 0 S Zone OS/NOS +7:0:0 NOS NO%s
Perhaps you are using a different version of glibc, or perhaps you are not running on x86-64, or perhaps you have an old version of zdump.c; any of these could explain why you see a problem but I do not. That being said, I looked at the TZif file generated by that test case, and it's clearly incorrect. I installed into the development repository the attached patch to fix the problem that I found; please give it a try. Perhaps this fix will be enough to address the problem you observed.
participants (3)
-
Paul Eggert -
renchunhui2025@outlook.com -
任春辉