From nobody Sat Jul 25 17:09:31 2026
X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h6rv51w8sz6ll37
for ; Sat, 25 Jul 2026 17:09:37 +0000 (UTC)
(envelope-from git@FreeBSD.org)
Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
client-signature RSA-PSS (4096 bits) client-digest SHA256)
(Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified))
by mx1.freebsd.org (Postfix) with ESMTPS id 4h6rv50gbmz3KSL
for ; Sat, 25 Jul 2026 17:09:37 +0000 (UTC)
(envelope-from git@FreeBSD.org)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim;
t=1784999377;
h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
to:to:cc:mime-version:mime-version:content-type:content-type:
content-transfer-encoding:content-transfer-encoding;
bh=eq/8aUOkShqEesuCt6gUndQW5NtNZnmZfhKl3/VoiVE=;
b=n9GoisPlNai3IGgVvzQRzy4UbqK99R9aykGXr2Ei/UmLra8KCTcTqo6s8Tf0uZXjwa3ICm
ozPNHopQyN9rBKcnWwSgnbezuGYiAzpO2ZsmDRjTN6PG/Fqowg18H0hYhSJgeI9c57Ylux
7XK2XWiQ+tkIkmxc9xmgsFrQPSZtJWvLQPigboyIXN8jgg98pCBUgPrw8Zcan8yCgjXFi/
HK4zsUwZ1x25SDviKNjqKUM6aM5VlnYn27XFiUy6jMpjJp9dKKDm20gbiZ0p03DNES4DO+
w9uW2dUVngh6MNtU76ogSw/S7CPorIzwbaiQjPsH0L67maZHXOEg2anELwlzZA==
ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1784999377; a=rsa-sha256; cv=none;
b=N26wX+erlUCmIws4HclNLPIMUQeMY4LGcDxAi9GoAz+l0nTwePpcEHl2PPHSbTi2VJLUtX
qpzjW5OzRb/ypgLPo8f3ZyS1H+NdQvFcHA7OPJyTd8mo6QDxMjcLRS7cvZBWrgc8iNairq
tnvzYPh/PVWg+e2yZoD8zPB2/5r8lAq0U5xZVmcysj1waJN1tvw9cEkqwgSsTLpQjxX8Fi
SgK9bCAMZf8e17DEEIg1oMS2dP0O82abHmrUzTrYVZudSZIaVkLhetY5fbYdOa5fDXWWuD
EI2MSysB2ynR1BNec+ciegA7HZ+Z/9KpZS2OmW63r6eSqQQN/RA1Sy85gTwemA==
ARC-Authentication-Results: i=1;
mx1.freebsd.org;
none
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org;
s=dkim; t=1784999377;
h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
to:to:cc:mime-version:mime-version:content-type:content-type:
content-transfer-encoding:content-transfer-encoding;
bh=eq/8aUOkShqEesuCt6gUndQW5NtNZnmZfhKl3/VoiVE=;
b=gQ1D6DssgZMioFOieSJUJXv5X711QOzHqFxQ9+t1gPBM/4iJqfrz2cEFyEUY/GZTp84qwA
DeVzsYA5Ydna9HoQfn3njqdrOLnH8mkZtikiDsTxc5tLErpBAWX6dWEHNPithd3fbKW0gU
MgAMZFL9RyUQ528+ee/RKT0GE1wNpep+aVUWXREbvzyj1fOJQMztYT5UB3qi3GUtwyAFdW
BAw0sISunWMYZm/U0stfkJJCFveKflZKv/efgUHc+aQheVnBHlneSyG4v6lDMCl2RBmwjm
lVzXOfElyrI3M/2csc4zn7VpTujECtPpcQeUPSUWSY43QUSGxHLPv/3kOVAf+A==
Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5])
by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h6rv46jjnzlVs
for ; Sat, 25 Jul 2026 17:09:36 +0000 (UTC)
(envelope-from git@FreeBSD.org)
Received: from git (uid 1279)
(envelope-from git@FreeBSD.org)
id 20388
by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org);
Sat, 25 Jul 2026 17:09:31 +0000
To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav
Subject: git: 8c2e1dee383c - stable/15 - tzcode: Update to 2026c
List-Id: Commit messages for all branches of the src repository
List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all
List-Help:
List-Post:
List-Subscribe:
List-Unsubscribe:
X-BeenThere: dev-commits-src-all@freebsd.org
Sender: owner-dev-commits-src-all@FreeBSD.org
List-Id:
List-Post:
List-Help:
List-Subscribe:
List-Unsubscribe:
List-Owner:
Precedence: list
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Git-Committer: des
X-Git-Repository: src
X-Git-Refname: refs/heads/stable/15
X-Git-Reftype: branch
X-Git-Commit: 8c2e1dee383cd23d205b5eb3f591057b209e6ed1
Auto-Submitted: auto-generated
Date: Sat, 25 Jul 2026 17:09:31 +0000
Message-Id: <6a64edcb.20388.6a806873@gitrepo.freebsd.org>
The branch stable/15 has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=8c2e1dee383cd23d205b5eb3f591057b209e6ed1
commit 8c2e1dee383cd23d205b5eb3f591057b209e6ed1
Author: Dag-Erling Smørgrav
AuthorDate: 2026-07-09 08:22:09 +0000
Commit: Dag-Erling Smørgrav
CommitDate: 2026-07-25 17:09:23 +0000
tzcode: Update to 2026c
MFC after: 1 week
(cherry picked from commit 28f617de7d9b9c708eacb3c2c13e5287e1b7354d)
---
contrib/tzcode/Makefile | 45 ++----
contrib/tzcode/NEWS | 77 ++++++++-
contrib/tzcode/localtime.c | 78 ++++++----
contrib/tzcode/newctime.3 | 20 +--
contrib/tzcode/newstrftime.3 | 4 +-
contrib/tzcode/newtzset.3 | 16 +-
contrib/tzcode/private.h | 24 ++-
contrib/tzcode/theory.html | 18 +--
contrib/tzcode/tz-art.html | 32 ++--
contrib/tzcode/tz-how-to.html | 6 +-
contrib/tzcode/tz-link.html | 50 +++---
contrib/tzcode/version | 2 +-
contrib/tzcode/zdump.c | 66 ++------
contrib/tzcode/zic.8 | 4 +-
contrib/tzcode/zic.c | 351 ++++++++++++++++++++++--------------------
15 files changed, 414 insertions(+), 379 deletions(-)
diff --git a/contrib/tzcode/Makefile b/contrib/tzcode/Makefile
index 1e0a5903534d..f5a22f1896a4 100644
--- a/contrib/tzcode/Makefile
+++ b/contrib/tzcode/Makefile
@@ -114,7 +114,7 @@ ZDUMPDIR = $(BINDIR)
# The "zic" command goes in:
ZICDIR = $(TOPDIR)/$(USRDIR)/sbin
-# Manual pages go in subdirectories of. . .
+# Manual pages go in subdirectories of:
MANDIR = $(TOPDIR)/$(USRSHAREDIR)/man
# Library functions are put in an archive in LIBDIR.
@@ -145,7 +145,7 @@ TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \
# nonnegative TZ_CHANGE_INTERVAL also assumes this, so to be compatible with
# these, use "posix_only" or "posix_right". Use POSIX time on systems with
# leap smearing; this can work better than unsmeared "right" time with
-# applications that are not leap second aware, and is closer to unsmeared
+# applications that are not aware of leap seconds, and is closer to unsmeared
# "right" time than unsmeared POSIX time is (e.g., 0.5 vs 1.0 s max error).
REDO= posix_only
@@ -295,10 +295,10 @@ LDLIBS=
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
# not needed by the main-program tz code, which is single-threaded.
# Append other compiler flags as needed, e.g., -pthread on GNU/Linux.
-# The following options can also be used:
+# With -DTHREAD_SAFE the following options can also be used:
# -DTHREAD_PREFER_SINGLE to prefer speed in single-threaded apps,
# at some cost in CPU time and energy in multi-threaded apps.
-# The following options can also be used:
+# With -DTHREAD_PREFER_SINGLE the following options can also be used:
# -DHAVE___ISTHREADED=1 if there is an extern int __isthreaded
# variable, 0 otherwise (default is guessed)
# -DHAVE_SYS_SINGLE_THREADED_H=0 if works,
@@ -377,12 +377,13 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
-Wdeclaration-after-statement -Wdouble-promotion \
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
- -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op \
+ -Wfree-labels -Wimplicit-fallthrough=5 -Winit-self \
+ -Wkeyword-macro -Wlogical-op \
-Wmissing-declarations -Wmissing-prototypes \
-Wmissing-variable-declarations -Wnested-externs \
-Wnull-dereference \
-Wold-style-definition -Woverlength-strings -Wpointer-arith \
- -Wshadow -Wshift-overflow=2 -Wstrict-overflow \
+ -Wshadow -Wshift-overflow=2 \
-Wstrict-prototypes -Wstringop-overflow=4 \
-Wsuggest-attribute=cold \
-Wsuggest-attribute=const -Wsuggest-attribute=format \
@@ -533,7 +534,7 @@ ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)'
# mawk 1.3.3 and Solaris 10 /usr/bin/awk do not work.
# Also, it is better (though not essential) if 'awk' supports UTF-8,
# and unfortunately mawk and busybox awk do not support UTF-8.
-# Try AWK=gawk or AWK=nawk if your awk has the abovementioned problems.
+# Try AWK=gawk or AWK=nawk if your awk has the problems mentioned above.
AWK= awk
# The full path name of a POSIX-compliant shell, preferably one that supports
@@ -913,7 +914,7 @@ tzselect: tzselect.ksh version
check: check_mild back.ck now.ck
check_mild: check_web check_zishrink \
character-set.ck white-space.ck links.ck mainguard.ck \
- name-lengths.ck slashed-abbrs.ck sorted.ck \
+ name-lengths.ck news.ck slashed-abbrs.ck sorted.ck \
tables.ck ziguard.ck tzs.ck
# True if UTF8_LOCALE does not work;
@@ -1083,6 +1084,12 @@ zishrink-posix.ck zishrink-right.ck: \
rm -fr $@d t-$@d shrunk-$@d
touch $@
+# Check that NEWS has data release versions and dates in reverse order.
+news.ck: NEWS
+ grep '^Release [0-9][0-9][0-9][0-9]' NEWS | LC_ALL=C sort -cru
+ sed -n '/ -0000$$/!s/^Release [^ ]*//p' NEWS|LC_ALL=C sort -cru
+ touch $@
+
clean_misc:
rm -fr *.ckd *.dir
rm -f *.ck *.core *.o *.out *.t core core.* \
@@ -1139,7 +1146,8 @@ SET_TIMESTAMP_N = sh -c '\
# If DEST depends on A B C ... in this Makefile, callers should use
# $(SET_TIMESTAMP_DEP) DEST A B C ..., for the benefit of any
# downstream 'make' that considers equal timestamps to be out of date.
-# POSIX allows this 'make' behavior, and HP-UX 'make' does it.
+# POSIX allows this 'make' behavior, although only HP-UX 'make'
+# (which is no longer supported) did things that way.
# If all that matters is that the timestamp be reproducible
# and plausible, use $(SET_TIMESTAMP).
SET_TIMESTAMP = $(SET_TIMESTAMP_N) 0
@@ -1399,24 +1407,6 @@ $(ALL_ASC):
$(SET_TIMESTAMP) $(@:.t=) $(?:.t=)
touch $@
-TYPECHECK_CFLAGS = $(CFLAGS) -DTYPECHECK -D__time_t_defined -D_TIME_T
-typecheck: long-long.ck unsigned.ck
-long-long.ck unsigned.ck: $(VERSION_DEPS)
- rm -fr $@d
- mkdir $@d
- ln $(VERSION_DEPS) $@d
- cd $@d && \
- case $@ in \
- long-long.*) i="long long";; \
- unsigned.* ) i="unsigned" ;; \
- esac && \
- $(MAKE) \
- CFLAGS="$(TYPECHECK_CFLAGS) \"-Dtime_t=$$i\"" \
- TOPDIR="$$PWD" \
- install
- $@d/zdump -i -c 1970,1971 Europe/Rome
- touch $@
-
zonenames: tzdata.zi
@$(AWK) '/^Z/ { print $$2 } /^L/ { print $$3 }' tzdata.zi
@@ -1442,6 +1432,5 @@ zic.o: private.h tzdir.h tzfile.h version.h
.PHONY: traditional_signatures traditional_signatures_version
.PHONY: traditional_tarballs traditional_tarballs_version
.PHONY: tailored_tarballs tailored_tarballs_version
-.PHONY: typecheck
.PHONY: zonenames zones
.PHONY: $(ZDS)
diff --git a/contrib/tzcode/NEWS b/contrib/tzcode/NEWS
index ea52e67e804a..dd962b54d529 100644
--- a/contrib/tzcode/NEWS
+++ b/contrib/tzcode/NEWS
@@ -1,5 +1,68 @@
News for the tz database
+Release 2026c - 2026-07-08 10:23:58 -0700
+
+ Briefly:
+ Alberta moved to permanent -06 on 2026-06-18.
+ Morocco moves to permanent +00 on 2026-09-20.
+ More integer overflow bugs have been fixed in zic.
+
+ Changes to future timestamps
+
+ Alberta’s 2026-03-08 spring forward was its last foreseeable clock
+ change, as it moved to permanent -06 thereafter. (Thanks to Roozbeh
+ Pournader and others.) Model this with its traditional abbreviation
+ CST. Although the change to permanent -06 legally took place on
+ 2026-06-18, temporarily model the change to occur on 2026-11-01 at
+ 02:00 instead, for the same reason we introduced a similarly
+ temporary hack for British Columbia in 2026b.
+
+ Although another TZDB release will likely be needed soon because
+ Northwest Territories will likely follow Alberta, the legal
+ formalities have not yet taken place.
+
+ Morocco plans to move back to permanent UTC, without daylight
+ saving time transitions, on 2026-09-20 at 02:00. This also
+ affects Western Sahara.
+
+ Changes to code
+
+ zic no longer overflows integers when processing outlandish input
+ like ‘Zone Ouch 0 - LMT 9223372036854775807’, ‘Zone Ouch 0
+ 2562047788015215 LMT’, ‘Zone Ouch -2562047788015215:30:08 - LMT’,
+ and ‘Zone Ouch -2562047788015215:30:08 - %%z’. This avoids
+ undefined behavior in C. (Problems reported by Naveed Khan.)
+
+ On platforms that have EFTYPE, tzalloc now fails with errno set to
+ EFTYPE, not EINVAL, if it detects that the TZif file has an
+ invalid format or is not a regular file. Formerly it did this
+ only on NetBSD, and only when the file was not a regular file.
+
+ Unprivileged programs no longer require TZif files to be regular
+ files or reject relative names containing ".." components. This
+ reverts to the more-permissive 2025b behavior, as the stricter
+ behavior did not catch on in FreeBSD.
+
+ zic now reports any failure to remove a temporary file when
+ cleaning up after a previous failure. (Problem reported by Tom
+ Lane.)
+
+ Changes to commentary
+
+ Northwest Territories is expected to move to permanent -06 prior to
+ 2026-11-01 02:00, when clocks would otherwise fall back. (Thanks to
+ Tim Parenti and James Bellaire.) Model this with its traditional
+ abbreviation CST. Unfortunately the change is not yet official, so
+ it is currently present only as comments that can be uncommented as
+ needed.
+
+ Changes to build procedure
+
+ The undocumented ‘typecheck’ Makefile check rule has been removed.
+ It stopped working in 2025a and evidently nobody noticed.
+ The rule was superseded by ‘check_time_t_alternatives’ in 2013d.
+
+
Release 2026b - 2026-04-22 23:06:43 -0700
Briefly:
@@ -13,7 +76,7 @@ Release 2026b - 2026-04-22 23:06:43 -0700
(Thanks to Arthur David Olson.) Although the change to permanent
-07 legally took place on 2026-03-09, temporarily model the change
to occur on 2026-11-01 at 02:00 instead. This works around a
- limitation in CLDR v48.2 (2026-03-17). This temporary hack is
+ limitation in CLDR 48.1 (2026-01-08). This temporary hack is
planned to be removed after CLDR is fixed.
Changes to code
@@ -99,7 +162,7 @@ Release 2026a - 2026-03-01 22:59:49 -0800
than attempting to override this fallback with the contents of the
posixrules file. This removes library support that was declared
obsolete in release 2019b, and fixes some undefined behavior.
- (Undefined behavior reported by GitHub user Naveed8951.)
+ (Undefined behavior reported by Naveed Khan.)
The posix2time, posix2time_z, time2posix, and time2posix_z
functions now set errno=EOVERFLOW and return ((time_t) -1) if the
@@ -111,7 +174,7 @@ Release 2026a - 2026-03-01 22:59:49 -0800
Some other undefined behavior, triggered by TZif files containing
outlandish but conforming UT offsets or leap second corrections,
- has also been fixed. (Some of these bugs reported by Naveed8951.)
+ has also been fixed. (Some of these bugs reported by Naveed Khan.)
localtime.c no longer rejects TZif files that exactly fit in its
internal structures, fixing off-by-one typos introduced in 2014g.
@@ -221,7 +284,7 @@ Release 2025c - 2025-12-10 14:42:37 -0800
rarely changing and many threads call tzcode simultaneously.
It costs more CPU time and energy.
- The new CFLAGS option -TTHREAD_TM_MULTI causes localtime to return
+ The new CFLAGS option -DTHREAD_TM_MULTI causes localtime to return
a pointer to thread-specific memory, as FreeBSD does, instead of
to the same memory in all threads. This supports nonportable
programs that incorrectly use localtime instead of localtime_r.
@@ -551,7 +614,7 @@ Release 2024a - 2024-02-01 09:28:56 -0800
The leap-seconds.list file is now copied from the IERS instead of
from its downstream counterpart at NIST, as the IERS version is
now in the public domain too and tends to be more up-to-date.
- (Thanks to Martin Burnicki for liaisoning with the IERS.)
+ (Thanks to Martin Burnicki for liaising with the IERS.)
Changes to documentation
@@ -1709,7 +1772,7 @@ Release 2020a - 2020-04-23 16:03:47 -0700
zic -L now supports an Expires line in the leapseconds file, and
truncates the TZif output accordingly. This propagates leap
second expiration information into the TZif file, and avoids the
- abovementioned localtime.c bug as well as similar bugs present in
+ localtime.c bug mentioned above, as well as similar bugs present in
many client implementations. If no Expires line is present, zic
-L instead truncates the TZif output based on the #expires comment
present in leapseconds files distributed by tzdb 2018f and later;
@@ -6666,7 +6729,7 @@ few (e.g., code2012c-data2012d) have tarballs with mixed version
numbers. Recent releases also come in an experimental format
consisting of a single tarball tzdb-R.tar.lz with extra data.
-Release timestamps are taken from the release's commit (for newer,
+A release’s timestamp is taken from the release’s commit (for newer,
Git-based releases), from the newest file in the tarball (for older
releases, where this info is available) or from the email announcing
the release (if all else fails; these are marked with a time zone
diff --git a/contrib/tzcode/localtime.c b/contrib/tzcode/localtime.c
index 459d818f0d7b..cd1bc8bd7523 100644
--- a/contrib/tzcode/localtime.c
+++ b/contrib/tzcode/localtime.c
@@ -227,7 +227,7 @@ struct timespec { time_t tv_sec; long tv_nsec; };
/* How many seconds to wait before checking the default TZif file again.
Negative means no checking. Default to 61 if DETECT_TZ_CHANGES
- (as circa 2025 FreeBSD builds its localtime.c with -DDETECT_TZ_CHANGES),
+ (as FreeBSD optionally builds its localtime.c with -DDETECT_TZ_CHANGES),
and to -1 otherwise. */
#ifndef TZ_CHANGE_INTERVAL
# ifdef DETECT_TZ_CHANGES
@@ -288,10 +288,12 @@ typedef intmax_t timex_t;
# endif
#endif
-/* Placeholders for platforms lacking openat. */
+/* Placeholders for platforms lacking AT_FCWD, openat, and fstatat. */
#ifndef AT_FDCWD
# define AT_FDCWD (-1) /* any negative value will do */
static int openat(int dd, char const *path, int oflag) { unreachable (); }
+static int fstatat(int dd, char const *path, struct stat *st, int flags)
+{ unreachable(); }
#endif
/* Port to platforms that lack some O_* flags. Unless otherwise
@@ -425,8 +427,7 @@ static char const *utc = etc_utc + sizeof "Etc/" - 1;
approach of opening "/usr/share/zoneinfo/America/Los_Angeles".
Although the OPENAT_TZDIR approach is less efficient, suffers from
spurious EMFILE and ENFILE failures, and is no more secure in practice,
- it is how bleeding edge FreeBSD did things from August 2025
- through at least September 2025. */
+ bleeding edge FreeBSD started doing it this way in August 2025. */
#ifndef OPENAT_TZDIR
# define OPENAT_TZDIR 0
#endif
@@ -917,6 +918,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
int dd = AT_FDCWD;
int oflags = (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK
| O_IGNORE_CTTY | O_NOCTTY | O_REGULAR);
+ bool might_escape = false;
int err;
struct stat st;
st.st_ctime = 0;
@@ -946,16 +948,8 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
continue;
else if (issetugid())
return ENOTCAPABLE;
- else if (!O_REGULAR) {
- /* Check for devices, as their mere opening could have
- unwanted side effects. Though racy, there is no
- portable way to fix the races. This check is needed
- only for files not otherwise known to be non-devices. */
- if (stat(name, &st) < 0)
- return errno;
- if (!S_ISREG(st.st_mode))
- return EINVAL;
- }
+ else
+ might_escape = true;
}
if (relname[0] != '/') {
@@ -967,8 +961,12 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
for (component = relname; component[0]; component++)
if (component[0] == '.' && component[1] == '.'
&& component[2] == '/'
- && (component == relname || component[-1] == '/'))
- return ENOTCAPABLE;
+ && (component == relname || component[-1] == '/')) {
+ if (issetugid())
+ return ENOTCAPABLE;
+ might_escape = true;
+ break;
+ }
}
if (OPENAT_TZDIR && !SUPPRESS_TZDIR) {
@@ -981,10 +979,10 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
| O_BINARY | O_CLOEXEC | O_CLOFORK | O_DIRECTORY));
if (dd < 0)
return errno;
-#ifdef __FreeBSD__
- if (issetugid())
-#endif /* __FreeBSD__ */
- oflags |= O_RESOLVE_BENEATH;
+ if (O_RESOLVE_BENEATH && issetugid()) {
+ oflags |= O_RESOLVE_BENEATH;
+ might_escape = false;
+ }
}
}
@@ -1020,6 +1018,18 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
#endif
}
+ /* For a platform that lacks O_REGULAR and a file that might
+ be outside TZDIR, check that it is a regular file,
+ as merely opening a device could have unwanted side effects.
+ Though racy, there is no portable way to fix the race. */
+ if (!O_REGULAR && might_escape) {
+ /* (oflags & O_RESOLVE_BENEATH) must be zero here. */
+ if ((OPENAT_TZDIR ? fstatat(dd, relname, &st, 0) : stat(name, &st))
+ < 0)
+ return errno;
+ if (!S_ISREG(st.st_mode))
+ return EFTYPE;
+ }
fid = OPENAT_TZDIR ? openat(dd, relname, oflags) : open(name, oflags);
err = errno;
if (0 <= dd)
@@ -1042,7 +1052,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
}
up = &lsp->u.u;
nread = read(fid, up->buf, sizeof up->buf);
- err = tzheadsize <= nread ? 0 : nread < 0 ? errno : EINVAL;
+ err = tzheadsize <= nread ? 0 : nread < 0 ? errno : EFTYPE;
}
close(fid);
if (err)
@@ -1070,7 +1080,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
&& 0 <= charcnt && charcnt <= TZ_MAX_CHARS
&& 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES
&& 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES))
- return EINVAL;
+ return EFTYPE;
datablock_size
= (timecnt * stored /* ats */
+ timecnt /* types */
@@ -1080,12 +1090,12 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
+ ttisstdcnt /* ttisstds */
+ ttisutcnt); /* ttisuts */
if (nread < tzheadsize + datablock_size)
- return EINVAL;
+ return EFTYPE;
if (skip_datablock)
p += datablock_size;
else if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
&& (ttisutcnt == typecnt || ttisutcnt == 0)))
- return EINVAL;
+ return EFTYPE;
else {
int_fast64_t prevtr = -1;
int_fast32_2s prevcorr;
@@ -1108,7 +1118,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
? TIME_T_MIN : at);
if (timecnt && attime <= sp->ats[timecnt - 1]) {
if (attime < sp->ats[timecnt - 1])
- return EINVAL;
+ return EFTYPE;
sp->types[i - 1] = 0;
timecnt--;
}
@@ -1121,7 +1131,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
for (i = 0; i < sp->timecnt; ++i) {
unsigned char typ = *p++;
if (sp->typecnt <= typ)
- return EINVAL;
+ return EFTYPE;
if (sp->types[i])
sp->types[timecnt++] = typ;
}
@@ -1135,18 +1145,18 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
cause trouble both in this file and in callers.
Also, it violates RFC 9636 section 3.2. */
if (utoff < -TWO_31_MINUS_1)
- return EINVAL;
+ return EFTYPE;
ttisp = &sp->ttis[i];
ttisp->tt_utoff = utoff;
p += 4;
isdst = *p++;
if (! (isdst < 2))
- return EINVAL;
+ return EFTYPE;
ttisp->tt_isdst = isdst;
desigidx = *p++;
if (! (desigidx < sp->charcnt))
- return EINVAL;
+ return EFTYPE;
ttisp->tt_desigidx = desigidx;
}
for (i = 0; i < sp->charcnt; ++i)
@@ -1165,7 +1175,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
/* Leap seconds cannot occur before the Epoch,
or out of order. */
if (tr <= prevtr)
- return EINVAL;
+ return EFTYPE;
/* To avoid other botches in this code, each leap second's
correction must differ from the previous one's by 1
@@ -1177,7 +1187,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
? corr == prevcorr + 1
: (corr == prevcorr
|| corr == prevcorr - 1))))
- return EINVAL;
+ return EFTYPE;
prevtr = tr;
prevcorr = corr;
@@ -1199,7 +1209,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
ttisp->tt_ttisstd = false;
else {
if (*p != true && *p != false)
- return EINVAL;
+ return EFTYPE;
ttisp->tt_ttisstd = *p++;
}
}
@@ -1211,7 +1221,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
ttisp->tt_ttisut = false;
else {
if (*p != true && *p != false)
- return EINVAL;
+ return EFTYPE;
ttisp->tt_ttisut = *p++;
}
}
@@ -1296,7 +1306,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags,
}
}
if (sp->typecnt == 0)
- return EINVAL;
+ return EFTYPE;
return 0;
}
diff --git a/contrib/tzcode/newctime.3 b/contrib/tzcode/newctime.3
index a8779e6a7c25..f22e69f44535 100644
--- a/contrib/tzcode/newctime.3
+++ b/contrib/tzcode/newctime.3
@@ -5,34 +5,34 @@
asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time
.SH SYNOPSIS
.nf
-.B #include
+.B "#include "
.PP
-.B struct tm *localtime(time_t const *clock);
+.B "struct tm *localtime(time_t const *clock);"
.B "struct tm *localtime_r(time_t const *restrict clock,"
.B " struct tm *restrict result);"
.B "struct tm *localtime_rz(timezone_t restrict zone,"
.B " time_t const *restrict clock,"
.B " struct tm *restrict result);"
.PP
-.B struct tm *gmtime(time_t const *clock);
+.B "struct tm *gmtime(time_t const *clock);"
.B "struct tm *gmtime_r(time_t const *restrict clock,"
.B " struct tm *restrict result);"
.PP
-.B time_t mktime(struct tm *tm);
+.B "time_t mktime(struct tm *tm);"
.B "time_t mktime_z(timezone_t restrict zone,"
.B " struct tm *restrict tm);"
.PP
-.B double difftime(time_t time1, time_t time0);
+.B "double difftime(time_t time1, time_t time0);"
.PP
-.B [[deprecated]] char *asctime(struct tm const *tm);
-.B [[deprecated]] char *ctime(time_t const *clock);
+.B "[[deprecated]] char *asctime(struct tm const *tm);"
+.B "[[deprecated]] char *ctime(time_t const *clock);"
.PP
/* Only in POSIX.1-2017 and earlier. */
-.B char *ctime_r(time_t const *clock, char *buf);
+.B "char *ctime_r(time_t const *clock, char *buf);"
.B "char *asctime_r(struct tm const *restrict tm,"
.B " char *restrict result);"
.PP
-.B cc ... \-ltz
+.BR cc " ... " \-ltz
.fi
.SH DESCRIPTION
.ie '\(en'' .ds en \-
@@ -240,7 +240,7 @@ are in the
.B
header file.
The structure (of type)
-.B struct tm
+.B "struct tm"
includes the following fields:
.RS
.PP
diff --git a/contrib/tzcode/newstrftime.3 b/contrib/tzcode/newstrftime.3
index 182f44f738a3..7d23b14ace72 100644
--- a/contrib/tzcode/newstrftime.3
+++ b/contrib/tzcode/newstrftime.3
@@ -40,12 +40,12 @@
strftime \- format date and time
.SH SYNOPSIS
.nf
-.B #include
+.B "#include "
.PP
.B "size_t strftime(char *restrict buf, size_t maxsize,"
.B " char const *restrict format, struct tm const *restrict timeptr);"
.PP
-.B cc ... \-ltz
+.BR cc " ... " \-ltz
.fi
.SH DESCRIPTION
.ie '\(lq'' .ds lq \&"\"
diff --git a/contrib/tzcode/newtzset.3 b/contrib/tzcode/newtzset.3
index 77e76c9d6974..366bf3024808 100644
--- a/contrib/tzcode/newtzset.3
+++ b/contrib/tzcode/newtzset.3
@@ -5,23 +5,23 @@
tzset \- initialize time conversion information
.SH SYNOPSIS
.nf
-.B #include
+.B "#include "
.PP
.BI "timezone_t tzalloc(char const *" TZ );
.PP
.BI "void tzfree(timezone_t " tz );
.PP
-.B void tzset(void);
+.B "void tzset(void);"
.PP
/* Optional and obsolescent: */
.br
-.B extern char *tzname[];
+.B "extern char *tzname[];"
.br
-.B extern long timezone;
+.B "extern long timezone;"
.br
-.B extern int daylight;
+.B "extern int daylight;"
.PP
-.B cc ... \-ltz
+.BR cc " ... " \-ltz
.fi
.SH DESCRIPTION
.ie '\(en'' .ds en \-
@@ -161,7 +161,7 @@ seconds) \*(en if present \*(en between zero and 59. If preceded by a
.q "\-" ,
the time zone shall be east of the Prime Meridian; otherwise it shall be
west (which may be indicated by an optional preceding
-.q "+" .
+.q "+" ).
.TP
.I rule
Indicates when to change to and back from daylight saving time. The
@@ -420,7 +420,7 @@ callers can instead use the
and
.I tm_zone
members of
-.B struct tm,
+.BR "struct tm",
or use
.B strftime
with "%z" or "%Z".
diff --git a/contrib/tzcode/private.h b/contrib/tzcode/private.h
index ee191b4ec33c..7918082dca1b 100644
--- a/contrib/tzcode/private.h
+++ b/contrib/tzcode/private.h
@@ -243,6 +243,9 @@ strnlen (char const *s, size_t maxlen)
# define EINVAL ERANGE
#endif
+#ifndef EFTYPE
+# define EFTYPE EINVAL
+#endif
#ifndef ELOOP
# define ELOOP EINVAL
#endif
@@ -951,6 +954,11 @@ ATTRIBUTE_POSIX2TIME time_t time2posix_z(timezone_t, time_t);
#define TYPE_SIGNED(type) (((type) -1) < 0)
#define TWOS_COMPLEMENT(type) (TYPE_SIGNED (type) && (! ~ (type) -1))
+/* Yield the value of the arithmetic expression X after integer promotion.
+ This is safer than a cast, which in general would accept even
+ pointers and which might trap or yield a value not equal to X. */
+#define INT_PROMOTE(x) (+(x))
+
/* Minimum and maximum of two values. Use lower case to avoid
naming clashes with standard include files. */
#define max(a, b) ((a) > (b) ? (a) : (b))
@@ -1071,12 +1079,16 @@ time_t timeoff(struct tm *, long);
** The default is to use gettext if available, and use MSGID otherwise.
*/
-#if HAVE_GETTEXT
-# define _(msgid) gettext(msgid)
-#else /* !HAVE_GETTEXT */
-# define _(msgid) (msgid)
-#endif /* !HAVE_GETTEXT */
-#define N_(msgid) (msgid)
+#ifndef _
+# if HAVE_GETTEXT
+# define _(msgid) gettext(msgid)
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+#ifndef N_
+# define N_(msgid) (msgid)
+#endif
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
# define TZ_DOMAIN "tz"
diff --git a/contrib/tzcode/theory.html b/contrib/tzcode/theory.html
index 12f4f7f4b439..8f76aaf0b3c8 100644
--- a/contrib/tzcode/theory.html
+++ b/contrib/tzcode/theory.html
@@ -592,10 +592,10 @@ in decreasing order of importance:
locations while uninhabited.
The leading "-" is a flag that the UT offset is in
some sense undefined; this notation is derived
- from Internet
+ from Internet
RFC 3339.
(The abbreviation Z that
- Internet
+ Internet
RFC 9557 uses for this concept
would violate the POSIX requirement
of at least three characters in an abbreviation.)
@@ -632,7 +632,7 @@ Errors in the tz database arise from many sources:
timestamps, and current predictions
will be incorrect after future governments change the rules.
For example, if today someone schedules a meeting for 13:00 next
- October 1, Casablanca time, and tomorrow Morocco changes its
+ October 1, Dublin time, and tomorrow Ireland changes its
daylight saving rules, software can mess up after the rule change
if it blithely relies on conversions made before the change.
@@ -657,7 +657,7 @@ Errors in the tz database arise from many sources:
zones at all, often not even a stable landscape of mean times,
prior to the middle decades of the twentieth century”.
See: Timothy Shenk, Booked:
+href="https://dissentmagazine.org/online_articles/booked-a-global-history-of-time-vanessa-ogle/">Booked:
A Global History of Time. Dissent 2015-12-17.
@@ -938,7 +938,7 @@ with problems that were fixed in later POSIX editions.
has a format that is hard to describe and is error-prone in practice.
Also, proleptic TZ strings cannot deal with daylight
saving time rules not based on the Gregorian calendar (as in
- Morocco), or with situations where more than two time zone
+ Palestine), or with situations where more than two time zone
abbreviations or UT offsets are used in an area.
@@ -1128,7 +1128,7 @@ However POSIX.1-2024, like earlier POSIX editions, has some limitations:
the name of a file from which time-related information is read.
The file’s format is TZif,
a timezone information format that contains binary data; see
- Internet
+ Internet
RFC 9636.
The daylight saving time rules to be used for a
particular timezone are encoded in the
@@ -1212,8 +1212,8 @@ The vestigial APIs are:
The tm_isdst member is almost never needed and most of
- its uses should be discouraged in favor of the abovementioned
- APIs.
+ its uses should be discouraged in favor of the
+ APIs mentioned above.
It was intended as an index into the tzname variable,
but as mentioned previously that usage is obsolete.
Although it can still be used in arguments to
@@ -1558,7 +1558,7 @@ Sources for time on other planets:
Michael Allison and Robert Schmunk,
“Technical
Notes on Mars Solar Time as Adopted by the Mars24 Sunclock”
- (2020-03-08).
+ (2023-05-15).
Zara Mirmalek,
diff --git a/contrib/tzcode/tz-art.html b/contrib/tzcode/tz-art.html
index 7870a6187390..77c7983c49fd 100644
--- a/contrib/tzcode/tz-art.html
+++ b/contrib/tzcode/tz-art.html
@@ -6,10 +6,10 @@
-Time and the Arts
+Time and the arts
-
Time and the Arts
+
Time and the arts
Documentaries
@@ -201,6 +201,13 @@ time zone associated with a video timestamp.
Jonah’s inability to understand DST ends up impressing a wealthy
backer who sets him up for a 2020 presidential run.
+
+“In the Zone”, The Magic School Bus Rides Again, season 3,
+episode 3, Netflix, 2020-12-26.
+During a New Year’s Eve journey, a software update glitch causes the
+Magic School Bus and its passengers to transform every time they cross
+time zone boundaries. The visit to the South Pole is especially tricky.
+
Books, plays, and magazines
@@ -481,20 +488,16 @@ The related book What If? has an entry
“Leap Seconds” (2012-12-31).
@@ -503,9 +506,7 @@ Peppermint Patty: “What if the world comes to an end tonight, Marcie?”
Marcie: “I promise there’ll be a tomorrow, sir ... in fact,
it’s already tomorrow in Australia!”
-(Charles M. Schulz,
-Peanuts,
-1980-06-13)
+(Charles M. Schulz, Peanuts, 1980-06-13)
Jokes
@@ -612,8 +613,7 @@ but maybe in your time zone I haven’t finished yet. So stay tuned!”