ICU: overlay current IANA tzdata (2026c) onto the data package - #358
ICU: overlay current IANA tzdata (2026c) onto the data package#358robobun wants to merge 1 commit into
Conversation
ICU 75.1 ships tzdata 2024a. IANA has published several releases since, and shipping the stale one means Bun returns wrong offsets for every zone whose rules changed: America/Asuncion (Paraguay abolished DST in 2024b) is reported as UTC-4 for half the year when real Paraguay has been permanent UTC-3 since October 2024, and America/Coyhaique (new in 2025b) is rejected outright. ICU supports hot-replacing tzdata via four resource bundles that are binary-compatible back to ICU 4.4. Vendor the current (2026c) little-endian builds of those bundles in icu/tzdata/, and add a single `icupkg -a` step after the existing filter step in each ICU build to inject them into the data package before it is linked into libicudata.a / sicudt.lib. macOS is untouched: it links Apple's system libicucore, whose tzdata follows macOS updates.
|
Warning Review limit reached
Next review available in: 10 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (12)
Comment |
There was a problem hiding this comment.
I didn't find any bugs, but this vendors ~234 KB of binary .res blobs and establishes a new ongoing maintenance step for tzdata, so it's worth a human sign-off on the approach and provenance.
What was reviewed:
- Confirmed each of the six build scripts has the tzdata directory available at the referenced path (
/icu-bun/tzdata,/icu-tzdata, or$ICU_TZDATA_DIR) before theicupkg -acall. - The
mv filtered → original→icupkg -a filtered originalswap preserves the output filename that downstreammake/compress-data.tssteps read. - All four overlaid bundles are already listed in
icu/keep-raw.txt, socompress-data.tscontinues to leave them uncompressed.
Extended reasoning...
Overview
The PR overlays a newer IANA tzdata (2026c) onto ICU 75.1's bundled 2024a by vendoring four little-endian .res bundles from unicode-org/icu-data into icu/tzdata/ and injecting them into the ICU data package via icupkg --auto_toc_prefix -a immediately after the existing filter step. The same one-line change is applied consistently across Dockerfile, Dockerfile.musl, Dockerfile.android, Dockerfile.freebsd, Dockerfile.windows, and build-icu.ps1. A README and a 4-line tz.lst are added.
Security risks
The main consideration is that four opaque binary resource bundles (~234 KB) are being checked into the repo. They are stated to come from unicode-org/icu-data at a pinned commit and are pure ICU resource-bundle data (not executable code), which is the same pattern Node.js uses in deps/icu-small. I cannot independently verify the binary contents match upstream, which is one reason a human should look.
Level of scrutiny
Moderate. The build-script edits themselves are mechanical and identical across all six files, and the change is fail-fast (a bad icupkg -a aborts the build). But it touches the ICU data pipeline for every shipped platform and introduces a recurring maintenance obligation (bump on each IANA release), which is a project-level decision a maintainer should acknowledge.
Other factors
- Paths check out:
Dockerfile/.musl/.windowsalreadyCOPY icu/ /icu-bun/;.android/.freebsdaddCOPY icu/tzdata /icu-tzdata;build-icu.ps1derives$ICU_TZDATA_DIRfrom the script location. - The four bundles were already in
icu/keep-raw.txt, so the zstd repack step is unaffected. - Author reports end-to-end verification (
process.versions.tz→ 2026c, Asunción/Coyhaique correct, intl tests pass) and item count unchanged at 3775. - macOS is intentionally untouched (uses system libicucore).
Preview Builds
|
ICU 75.1 ships tzdata 2024a. IANA has published several releases since, and shipping the stale one means Bun returns wrong offsets for every zone whose rules changed:
America/Asuncion(Paraguay abolished DST in tzdata 2024b) is reported as UTC-4 for half the year when real Paraguay has been permanent UTC-3 since October 2024.America/Coyhaique(new zone in tzdata 2025b) is rejected withRangeError: invalid time zone.Fix
ICU supports hot-replacing tzdata via four resource bundles (
zoneinfo64.res,metaZones.res,timezoneTypes.res,windowsZones.res) that are binary-compatible back to ICU 4.4. This is the documented update path and what Node vendors indeps/icu-small.This PR:
icu/tzdata/(234 KB total, from unicode-org/icu-data@1c3d36e), with a README describing the three-step update;icupkg --auto_toc_prefix -acall after the existing filter step in each ICU build (Dockerfile,.musl,.android,.freebsd,.windows,build-icu.ps1) to inject them into the data package before it is repacked intolibicudata.a/sicudt.lib.macOS is untouched: it links Apple's system
libicucore, whose tzdata follows macOS updates.Verification
Built ICU 75.1 locally, ran the exact Dockerfile
icupkg -r/icupkg -asequence, repacked withicu/compress-data.ts, and relinked the resultinglibicudata.ainto a debug Bun:Item count is unchanged (3775 before and after the overlay; the four bundles replace existing entries in place). Package size delta is <4 KB.
The bun-side companion (adding
process.versions.tzviaucal_getTZDataVersion, plus the regression test andWEBKIT_VERSIONbump) is in oven-sh/bun#36042.