diff --git a/ZoneTest.java b/ZoneTest.java new file mode 100644 index 0000000..d217105 --- /dev/null +++ b/ZoneTest.java @@ -0,0 +1,26 @@ +/* Smoke test to ensure that tzdb.data can be loaded. */ + +import java.time.zone.ZoneRulesProvider; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.Set; +import java.util.TimeZone; + +public class ZoneTest { + public static void main(String[] args) { + // This is what failed in OpenJDK's build.tools.cldrconverter. + new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"), + Locale.US).get(Calendar.YEAR); + + // In some OpenJDK versions, this exercises a different parser. + Set available = ZoneRulesProvider.getAvailableZoneIds(); + boolean errors = false; + if (available.contains("ROC")) + System.out.println("error: ROC zone is present"); + if (!available.contains("America/New_York")) + System.out.println("error: America/New_York is missing"); + if (errors) + System.exit(1); + } +} diff --git a/javazic-harden-links.patch b/javazic-harden-links.patch new file mode 100644 index 0000000..83827f1 --- /dev/null +++ b/javazic-harden-links.patch @@ -0,0 +1,76 @@ +diff -ur tzdata-2024b.orig/javazic-1.8/build/tools/tzdb/TzdbZoneRulesCompiler.java tzdata-2024b/javazic-1.8/build/tools/tzdb/TzdbZoneRulesCompiler.java +--- tzdata-2024b.orig/javazic-1.8/build/tools/tzdb/TzdbZoneRulesCompiler.java 2014-04-22 19:46:49.000000000 +0200 ++++ tzdata-2024b/javazic-1.8/build/tools/tzdb/TzdbZoneRulesCompiler.java 2024-09-20 21:10:12.748483767 +0200 +@@ -248,7 +248,7 @@ + // link version-region-rules + out.writeShort(builtZones.size()); + for (Map.Entry entry : builtZones.entrySet()) { +- int regionIndex = Arrays.binarySearch(regionArray, entry.getKey()); ++ int regionIndex = findRegionIndex(regionArray, entry.getKey()); + int rulesIndex = rulesList.indexOf(entry.getValue()); + out.writeShort(regionIndex); + out.writeShort(rulesIndex); +@@ -256,8 +256,8 @@ + // alias-region + out.writeShort(links.size()); + for (Map.Entry entry : links.entrySet()) { +- int aliasIndex = Arrays.binarySearch(regionArray, entry.getKey()); +- int regionIndex = Arrays.binarySearch(regionArray, entry.getValue()); ++ int aliasIndex = findRegionIndex(regionArray, entry.getKey()); ++ int regionIndex = findRegionIndex(regionArray, entry.getValue()); + out.writeShort(aliasIndex); + out.writeShort(regionIndex); + } +@@ -269,6 +269,14 @@ + } + } + ++ private static int findRegionIndex(String[] regionArray, String region) { ++ int index = Arrays.binarySearch(regionArray, region); ++ if (index < 0) { ++ throw new IllegalArgumentException("Unknown region: " + region); ++ } ++ return index; ++ } ++ + private static final Pattern YEAR = Pattern.compile("(?i)(?min)|(?max)|(?only)|(?[0-9]+)"); + private static final Pattern MONTH = Pattern.compile("(?i)(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec)"); + private static final Matcher DOW = Pattern.compile("(?i)(mon)|(tue)|(wed)|(thu)|(fri)|(sat)|(sun)").matcher(""); +@@ -607,22 +615,20 @@ + } + builtZones.put(aliasId, realRules); + } +- // remove UTC and GMT +- // builtZones.remove("UTC"); +- // builtZones.remove("GMT"); +- // builtZones.remove("GMT0"); +- builtZones.remove("GMT+0"); +- builtZones.remove("GMT-0"); +- links.remove("GMT+0"); +- links.remove("GMT-0"); +- // remove ROC, which is not supported in j.u.tz +- builtZones.remove("ROC"); +- links.remove("ROC"); +- // remove EST, HST and MST. They are supported via +- // the short-id mapping +- builtZones.remove("EST"); +- builtZones.remove("HST"); +- builtZones.remove("MST"); ++ ++ List zonesToRemove = Arrays.asList( ++ // remove UTC and GMT ++ "GMT+0", ++ "GMT-0", ++ // remove ROC, which is not supported in j.u.tz ++ "ROC", ++ // remove EST, HST and MST. They are supported via ++ // the short-id mapping ++ "EST", ++ "HST", ++ "MST"); ++ builtZones.keySet().removeAll(zonesToRemove); ++ links.keySet().removeAll(zonesToRemove); + } + + /** + diff --git a/tzdata.spec b/tzdata.spec index c1aba2d..8a7729f 100644 --- a/tzdata.spec +++ b/tzdata.spec @@ -3,7 +3,7 @@ Name: tzdata Version: 2024b %define tzdata_version 2024b %define tzcode_version 2024b -Release: 1%{?dist} +Release: 2%{?dist} License: Public Domain Group: System Environment/Base URL: https://www.iana.org/time-zones @@ -30,12 +30,14 @@ Summary: Timezone data for Java Group: System Environment/Base Source3: javazic.tar.gz Source4: javazic-1.8-37392f2f5d59.tar.xz +Source5: ZoneTest.java Patch100: javazic-fixup.patch Patch101: rebase-01.patch Patch102: rebase-02.patch Patch103: 7090844.patch Patch104: 7133138.patch Patch105: 8051641.patch +Patch106: javazic-harden-links.patch %description java This package contains timezone information for use by Java runtimes. @@ -90,6 +92,7 @@ popd tar xf %{SOURCE4} %patch105 +%patch106 -p1 echo "%{name}%{tzdata_version}" >> VERSION @@ -136,6 +139,20 @@ install -p -m 644 tzdb.dat $RPM_BUILD_ROOT%{_datadir}/javazi-1.8/ %check echo ============TESTING=============== /usr/bin/env LANG=C make -k VALIDATE=':' check && true + +# Create a custom JAVA_HOME, where we can replace tzdb.dat with the +# one just built, for testing. +system_java_home=$(dirname $(readlink -f $(which java)))/.. +mkdir -p java_home +cp -Lr $system_java_home/* java_home/. +for tzdb in $(find java_home -name tzdb.dat) ; do + rm $tzdb + cp $RPM_BUILD_ROOT%{_datadir}/javazi-1.8/tzdb.dat $tzdb +done +# Compile the smoke test and run it. +cp %{SOURCE5} . +javac ZoneTest.java +java_home/bin/java ZoneTest echo ============END TESTING=========== %files @@ -153,6 +170,9 @@ echo ============END TESTING=========== %{_datadir}/javazi-1.8 %changelog +* Fri Sep 20 2024 Florian Weimer - 2024b-2 +- Harden against links to removed zones (RHEL-59542) + * Wed Sep 11 2024 Patsy Griffin - 2024b-1 - Update to tzdata-2024b - Improve historical data for Mexico, Mongolia, and Portugal.