timezone: sync to tzdb 2026b

Sync tzselect, zdump, zic to tzdb 2026b.

This fixes some buffer and integer overflows in zic,
adds new zic options -D, -m and -u inspired by FreeBSD,
and raises zic’s maximum number of abbreviation bytes
per timezone from 50 to 256.

This patch incorporates the following tzdb source code changes:

f9d30685 Output a minimal time zone designation table
37a4d178 Fix zic overflow bug with too-large offsets
4392f2dc zic now checks for signals more often
99a08a66 Fix zic buffer overflow when computing TZ
d63b9287 zic: keep needed last transition to new type
d005045d Pacify clang -Wunterminated-string-initialization
e67b08d3 Port to C23 strchr macro
3d4b4e46 Add zic.c overflow commentary
d9101b88 zic now a bit safer for overflows near 2**63
b23fa8e0 zic now allows more than 50 leap seconds
4ff518d2 Increase TZ_MAX_CHARS from 50 to 256
75d3b73b New -DTZ_RUNTIME_LEAPS=0 build-time option
87343c6e TZ_MAX_TIMES must be at least 310 now
fc8f1b68 Simplify int_fast32_t definition on C89 platforms
24581465 Remove TZDEFRULES ("posixrules") from localtime.c
fc708427 zic now warns about -p
b09a3f23 Port TWOS_COMPLEMENT to signed-magnitude hosts
56b7a24a Make sure 2**31 - 1 is signed
9068ab78 zic no longer generates utoff == -2**31
cb6f9b3b Omit unnecessary L suffixes
c37fbc32 Clarify when ‘__attribute__((pure))’ is a hack
859690a7 Fix some unsequenced/reproducible commentary
9c772ca7 Port to POSIX.1-2001 fflush
10f93018 Omit no-op transitions when Rule+Zone cancel
a0b09b52 Fix unlikely backslash bug in scripts
2cbd3a71 Allow builder to override GRANDPARENTED
c7257626 not used at → used outside
faed4bd3 Clarify <sys/auxv.h> vs getauxval
df08e6a1 Port mode_t (and gid_t, uid_t) to MS-Windows
6127d375 New zic option -u, inspired by FreeBSD
813c9ee0 New zic option -m, inspired by FreeBSD
987ea89c New zic option -D, inspired by FreeBSD
cc377b07 Simplify mkdir situation
cd994a90 Simplify !HAVE_POSIX_DECLS situation
052ddf76 Minor gettext macro improvements
d9018f1c Refactor duplicate duplicate-option code
8d65db97 Prefer fdopen to umask in zic
d7edca6e Omit “'”s from zic usage message
a09ba7a5 getopt returns -1 (not EOF) on failure
e22d410c zic now uses is_digit
f57cadda Always invoke umask at start
242a8338 Fix mode_t issues on MS-Windows
2fecd606 MKDIR_UMASK → MKDIR_PERMS refactoring
90ef088a Move static_assert to top level
41576478 Port better to platforms lacking mempcpy
90a08d3e * private.h: Include stddef.h early enough
aa8b35fe Simplify port to NetBSD struct __state
cd2fddf7 Port to -DHAVE_SYS_STAT_H=0 -DHAVE_POSIX_DECLS=0
8470e759 Pacify GCC 15 -Wunterminated-string-initialization
8817d42f Prefer mempcpy to doing it by hand
87abb113 Tighten security checks on TZ values
c87f0918 Use strnlen
07f7f31a Fix preprocessor indenting
3adf4123 Add offtime_r à la FreeBSD and NetBSD
b807a31e Don’t depend on ‘true’ for tzselect
ddffc800 * zic.c: Fix misspelled comment (thanks to Jonathan Wakely).
7063d08c Fix bug with -d RELATIVE -t ABSOLUTE
e8920e76 Rename emalloc to xmalloc.
e8e1a3d2 NetBSD defines STD_INSPIRED functions
3411494c Define _CRT_DECLARE_NONSTDC_NAMES for MS-Windows
7c909166 Define NOMINMAX for MS-Windows
24a4d97f 'zdump -' now reads from stdin
e6d6bc3e Pacify gcc -Wsuggest-attribute=format sans snprintf in zdump
99557862 TZNAME_MAXIMUM defaults to 254, not 255
fe5be99d Be more consistent about macro true/false vs 1/0
31f483a1 Remove dependency of asctime on strftime
7ef7ed06 Simplify timeoff redefinition
1bd67a4b Move MKTIME_MIGHT_OVERFLOW definition
67f7e8ab Pacify GCC 15ish -Wzero-as-null-pointer-constant
535a4e8b Pacify GCC 15ish -Wleading-whitespace=blanks
0706ef0b Move iinntt definition
ea814e99 strftime %s no longer is limited to time_t range
41e5344e Fix bug near the year 2**31 - 1 - 1900
4e1de249 Pacify gcc -Wsuggest-attribute=const
ebd2ed92 Don’t define _FILE_OFFSET_BITS if _TIME_BITS
26a649a1 Improve zdump overflow checking
9c8221d7 * private.h: Fix timeoff comment.
9db906a0 Switch from RFC 8536 to 9636 for documentation
af54a9e8 Port better to glibc when used internally there

Checked on x86_64-linux-gnu.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Paul Eggert
2026-05-18 13:31:00 -03:00
committed by Adhemerval Zanella
parent 08e963f675
commit 4c6f92daea
7 changed files with 1019 additions and 565 deletions
+4 -3
View File
@@ -212,8 +212,9 @@ unicode:
# The following files are shared with the upstream tzcode project and must be
# updated regularly to stay in sync with the upstream releases.
#
# Currently synced to TZDB 2024b, announced and distributed here:
# https://github.com/eggert/tz/releases/tag/2024b
# Currently synced to TZDB 2026b, distributed at:
# https://github.com/eggert/tz/releases/tag/2026b
# https://data.iana.org/time-zones/releases/tzdb-2026b.tar.lz
tzcode:
timezone/private.h
timezone/tzfile.h
@@ -258,7 +259,7 @@ tzdata:
# FLT_EVAL_METHOD equal to 2 (i386). Additionally, extra optimizations
# are applied to share the internal data table across different
# implementations.
#
#
# The project is distribute here:
# https://gitlab.inria.fr/core-math/core-math/
core-math:
+302 -184
View File
@@ -37,6 +37,38 @@
# define SUPPORT_C89 1
#endif
/* The following feature-test macros should be defined before
any #include of a system header. */
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
#define _GNU_SOURCE 1
/* Fix asctime_r on Solaris 11. */
#define _POSIX_PTHREAD_SEMANTICS 1
/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
/* Cause MS-Windows headers to define POSIX names. */
#define _CRT_DECLARE_NONSTDC_NAMES 1
/* Prevent MS-Windows headers from defining min and max. */
#define NOMINMAX 1
/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
setting _TIME_BITS to 64 does not work. The code does not
otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
use off_t or functions like 'stat' that depend on off_t. */
#ifndef _TIME_BITS
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# if _FILE_OFFSET_BITS == 64
# define _TIME_BITS 64
# endif
#endif
/* End of feature-test macro definitions. */
#ifndef __STDC_VERSION__
# define __STDC_VERSION__ 0
#endif
@@ -50,7 +82,9 @@
# include <stdbool.h>
#endif
#if __STDC_VERSION__ < 202311
/* For pre-C23 compilers, a substitute for static_assert.
Some of these compilers may warn if it is used outside the top level. */
#if __STDC_VERSION__ < 202311 && !defined static_assert
# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
#endif
@@ -65,7 +99,9 @@
#endif
/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
#ifndef GRANDPARENTED
# define GRANDPARENTED "Local time zone must be set--see zic manual page"
#endif
/*
** Defaults for preprocessor symbols.
@@ -85,13 +121,21 @@
# define HAVE__GENERIC (201112 <= __STDC_VERSION__)
#endif
#ifndef HAVE_GETEUID
# define HAVE_GETEUID 1
#endif
#ifndef HAVE_GETRESUID
# define HAVE_GETRESUID 1
#endif
#if !defined HAVE_GETTEXT && defined __has_include
# if __has_include(<libintl.h>)
# define HAVE_GETTEXT true
# define HAVE_GETTEXT 1
# endif
#endif
#ifndef HAVE_GETTEXT
# define HAVE_GETTEXT false
# define HAVE_GETTEXT 0
#endif
#ifndef HAVE_INCOMPATIBLE_CTIME_R
@@ -124,20 +168,20 @@
#if !defined HAVE_SYS_STAT_H && defined __has_include
# if !__has_include(<sys/stat.h>)
# define HAVE_SYS_STAT_H false
# define HAVE_SYS_STAT_H 0
# endif
#endif
#ifndef HAVE_SYS_STAT_H
# define HAVE_SYS_STAT_H true
# define HAVE_SYS_STAT_H 1
#endif
#if !defined HAVE_UNISTD_H && defined __has_include
# if !__has_include(<unistd.h>)
# define HAVE_UNISTD_H false
# define HAVE_UNISTD_H 0
# endif
#endif
#ifndef HAVE_UNISTD_H
# define HAVE_UNISTD_H true
# define HAVE_UNISTD_H 1
#endif
#ifndef NETBSD_INSPIRED
@@ -149,56 +193,44 @@
# define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
#define _GNU_SOURCE 1
/* Fix asctime_r on Solaris 11. */
#define _POSIX_PTHREAD_SEMANTICS 1
/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
setting _TIME_BITS to 64 does not work. The code does not
otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
use off_t or functions like 'stat' that depend on off_t. */
#ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
#endif
#if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
# define _TIME_BITS 64
#ifndef TZ_RUNTIME_LEAPS
# define TZ_RUNTIME_LEAPS 1
#endif
/*
** Nested includes
*/
/* Avoid clashes with NetBSD by renaming NetBSD's declarations.
If defining the 'timezone' variable, avoid a clash with FreeBSD's
'timezone' function by renaming its declaration. */
#define localtime_rz sys_localtime_rz
#define mktime_z sys_mktime_z
#define posix2time_z sys_posix2time_z
#define time2posix_z sys_time2posix_z
#if defined USG_COMPAT && USG_COMPAT == 2
# define timezone sys_timezone
#endif
#define timezone_t sys_timezone_t
#define tzalloc sys_tzalloc
#define tzfree sys_tzfree
#include <time.h>
#undef localtime_rz
#undef mktime_z
#undef posix2time_z
#undef time2posix_z
#if defined USG_COMPAT && USG_COMPAT == 2
# undef timezone
#endif
#undef timezone_t
#undef tzalloc
#undef tzfree
#include <stddef.h>
/* If defining the 'timezone' variable a la POSIX, avoid clashing with the old
'timezone' function of FreeBSD <= 14, by renaming the latter's declaration.
This hack can be removed after 2028-11-30, FreeBSD 14's expected EOL. */
#if (defined __FreeBSD__ && __FreeBSD__ < 15 && defined __BSD_VISIBLE \
&& defined USG_COMPAT && USG_COMPAT == 2)
# define timezone sys_timezone
# define timezone_defined
#endif
#include <time.h>
#ifdef timezone_defined
# undef timezone
# undef timezone_defined
#endif
#include <string.h>
#if defined HAVE_STRNLEN && !HAVE_STRNLEN
static size_t
strnlen (char const *s, size_t maxlen)
{
size_t i;
for (i = 0; i < maxlen && s[i]; i++)
continue;
return i;
}
#endif
#if !PORT_TO_C89
# include <inttypes.h>
#endif
@@ -220,6 +252,9 @@
#ifndef ENOMEM
# define ENOMEM EINVAL
#endif
#ifndef ENOTCAPABLE
# define ENOTCAPABLE EINVAL
#endif
#ifndef ENOTSUP
# define ENOTSUP EINVAL
#endif
@@ -232,7 +267,12 @@
#endif /* HAVE_GETTEXT */
#if HAVE_UNISTD_H
# include <unistd.h> /* for R_OK, and other POSIX goodness */
# include <unistd.h>
#else
/* Assume getopt.o or equivalent is linked via Makefile configuration. */
int getopt(int, char *const[], char const *);
extern char *optarg;
extern int optind;
#endif /* HAVE_UNISTD_H */
/* SUPPORT_POSIX2008 means the tzcode library should support
@@ -260,6 +300,20 @@
# endif
#endif
#ifndef HAVE_ISSETUGID
# if (defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __linux__ && !defined __GLIBC__) /* Android, musl, etc. */ \
|| (defined __APPLE__ && defined __MACH__) || defined __sun)
# define HAVE_ISSETUGID 1
# else
# define HAVE_ISSETUGID 0
# endif
#endif
#ifndef HAVE_SNPRINTF
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
#endif
#ifndef HAVE_STRFTIME_L
# if _POSIX_VERSION < 200809
# define HAVE_STRFTIME_L 0
@@ -292,10 +346,6 @@
# endif
#endif
#ifndef R_OK
# define R_OK 4
#endif /* !defined R_OK */
#if PORT_TO_C89
/*
@@ -304,146 +354,144 @@
** previously included files. glibc 2.1 and Solaris 10 and later have
** stdint.h, even with pre-C99 compilers.
*/
#if !defined HAVE_STDINT_H && defined __has_include
# define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h. */
#endif
#ifndef HAVE_STDINT_H
# define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
|| __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
# if !defined HAVE_STDINT_H && defined __has_include
# define HAVE_STDINT_H 1 /* C23 __has_include implies C99 stdint.h. */
# endif
# ifndef HAVE_STDINT_H
# define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
|| __CYGWIN__ || INTMAX_MAX)
# endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
# include <stdint.h>
#endif /* !HAVE_STDINT_H */
# if HAVE_STDINT_H
# include <stdint.h>
# endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
# define HAVE_INTTYPES_H HAVE_STDINT_H
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
# ifndef HAVE_INTTYPES_H
# define HAVE_INTTYPES_H HAVE_STDINT_H
# endif
# if HAVE_INTTYPES_H
# include <inttypes.h>
# endif
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
#if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
# ifndef LLONG_MAX
# define LLONG_MAX __LONG_LONG_MAX__
# if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
# ifndef LLONG_MAX
# define LLONG_MAX __LONG_LONG_MAX__
# endif
# ifndef LLONG_MIN
# define LLONG_MIN (-1 - LLONG_MAX)
# endif
# ifndef ULLONG_MAX
# define ULLONG_MAX (LLONG_MAX * 2ull + 1)
# endif
# endif
# ifndef LLONG_MIN
# define LLONG_MIN (-1 - LLONG_MAX)
# endif
# ifndef ULLONG_MAX
# define ULLONG_MAX (LLONG_MAX * 2ull + 1)
# endif
#endif
#ifndef INT_FAST64_MAX
# if 1 <= LONG_MAX >> 31 >> 31
# ifndef INT_FAST64_MAX
# if 1 <= LONG_MAX >> 31 >> 31
typedef long int_fast64_t;
# define INT_FAST64_MIN LONG_MIN
# define INT_FAST64_MAX LONG_MAX
# else
# define INT_FAST64_MIN LONG_MIN
# define INT_FAST64_MAX LONG_MAX
# else
/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
typedef long long int_fast64_t;
# define INT_FAST64_MIN LLONG_MIN
# define INT_FAST64_MAX LLONG_MAX
# define INT_FAST64_MIN LLONG_MIN
# define INT_FAST64_MAX LLONG_MAX
# endif
# endif
#endif
#ifndef PRIdFAST64
# if INT_FAST64_MAX == LONG_MAX
# define PRIdFAST64 "ld"
# else
# define PRIdFAST64 "lld"
# ifndef PRIdFAST64
# if INT_FAST64_MAX == LONG_MAX
# define PRIdFAST64 "ld"
# else
# define PRIdFAST64 "lld"
# endif
# endif
#endif
#ifndef SCNdFAST64
# define SCNdFAST64 PRIdFAST64
#endif
# ifndef SCNdFAST64
# define SCNdFAST64 PRIdFAST64
# endif
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
# ifndef INT_FAST32_MAX
typedef long int_fast32_t;
# define INT_FAST32_MAX LONG_MAX
# define INT_FAST32_MIN LONG_MIN
# else
typedef int int_fast32_t;
# define INT_FAST32_MAX INT_MAX
# define INT_FAST32_MIN INT_MIN
# endif
#endif
#ifndef INTMAX_MAX
# ifdef LLONG_MAX
# ifndef INT_LEAST32_MAX
typedef int_fast32_t int_least32_t;
# endif
# ifndef INTMAX_MAX
# ifdef LLONG_MAX
typedef long long intmax_t;
# ifndef HAVE_STRTOLL
# define HAVE_STRTOLL true
# endif
# if HAVE_STRTOLL
# define strtoimax strtoll
# endif
# define INTMAX_MAX LLONG_MAX
# define INTMAX_MIN LLONG_MIN
# else
# ifndef HAVE_STRTOLL
# define HAVE_STRTOLL 1
# endif
# if HAVE_STRTOLL
# define strtoimax strtoll
# endif
# define INTMAX_MAX LLONG_MAX
# define INTMAX_MIN LLONG_MIN
# else
typedef long intmax_t;
# define INTMAX_MAX LONG_MAX
# define INTMAX_MIN LONG_MIN
# define INTMAX_MAX LONG_MAX
# define INTMAX_MIN LONG_MIN
# endif
# ifndef strtoimax
# define strtoimax strtol
# endif
# endif
# ifndef strtoimax
# define strtoimax strtol
# ifndef PRIdMAX
# if INTMAX_MAX == LLONG_MAX
# define PRIdMAX "lld"
# else
# define PRIdMAX "ld"
# endif
# endif
#endif
#ifndef PRIdMAX
# if INTMAX_MAX == LLONG_MAX
# define PRIdMAX "lld"
# else
# define PRIdMAX "ld"
# ifndef PTRDIFF_MAX
# define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
# endif
#endif
#ifndef PTRDIFF_MAX
# define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
#endif
#ifndef UINT_FAST32_MAX
# ifndef UINT_FAST32_MAX
typedef unsigned long uint_fast32_t;
#endif
# endif
#ifndef UINT_FAST64_MAX
# if 3 <= ULONG_MAX >> 31 >> 31
# ifndef UINT_FAST64_MAX
# if 3 <= ULONG_MAX >> 31 >> 31
typedef unsigned long uint_fast64_t;
# define UINT_FAST64_MAX ULONG_MAX
# else
# define UINT_FAST64_MAX ULONG_MAX
# else
/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
typedef unsigned long long uint_fast64_t;
# define UINT_FAST64_MAX ULLONG_MAX
# define UINT_FAST64_MAX ULLONG_MAX
# endif
# endif
#endif
#ifndef UINTMAX_MAX
# ifdef ULLONG_MAX
# ifndef UINTMAX_MAX
# ifdef ULLONG_MAX
typedef unsigned long long uintmax_t;
# define UINTMAX_MAX ULLONG_MAX
# else
# define UINTMAX_MAX ULLONG_MAX
# else
typedef unsigned long uintmax_t;
# define UINTMAX_MAX ULONG_MAX
# define UINTMAX_MAX ULONG_MAX
# endif
# endif
#endif
#ifndef PRIuMAX
# ifdef ULLONG_MAX
# define PRIuMAX "llu"
# else
# define PRIuMAX "lu"
# ifndef PRIuMAX
# ifdef ULLONG_MAX
# define PRIuMAX "llu"
# else
# define PRIuMAX "lu"
# endif
# endif
#endif
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
# ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
# endif
#endif /* PORT_TO_C89 */
@@ -459,7 +507,7 @@ typedef unsigned long uintmax_t;
hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
#if !defined HAVE_STDCKDINT_H && defined __has_include
# if __has_include(<stdckdint.h>)
# define HAVE_STDCKDINT_H true
# define HAVE_STDCKDINT_H 1
# endif
#endif
#ifdef HAVE_STDCKDINT_H
@@ -491,6 +539,15 @@ typedef unsigned long uintmax_t;
# define HAVE___HAS_C_ATTRIBUTE false
#endif
#ifdef __has_attribute
# if __has_attribute (nonstring)
# define ATTRIBUTE_NONSTRING __attribute__((__nonstring__))
# endif
#endif
#ifndef ATTRIBUTE_NONSTRING
# define ATTRIBUTE_NONSTRING
#endif
#if HAVE___HAS_C_ATTRIBUTE
# if __has_c_attribute(deprecated)
# define ATTRIBUTE_DEPRECATED [[deprecated]]
@@ -554,13 +611,26 @@ typedef unsigned long uintmax_t;
# define ATTRIBUTE_REPRODUCIBLE /* empty */
#endif
/* GCC attributes that are useful in tzcode.
__attribute__((pure)) is stricter than [[reproducible]],
so the latter is an adequate substitute in non-GCC C23 platforms. */
#if HAVE___HAS_C_ATTRIBUTE
# if __has_c_attribute(unsequenced)
# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
# endif
#endif
#ifndef ATTRIBUTE_UNSEQUENCED
# define ATTRIBUTE_UNSEQUENCED /* empty */
#endif
/* GNU C attributes that are useful in tzcode.
Although neither __attribute__((const)) nor __attribute__((pure)) are
stricter than their C23 counterparts [[unsequenced]] and [[reproducible]],
the C23 attributes happen to work in each tzcode use of ATTRIBUTE_CONST
and ATTRIBUTE_PURE. (This might not work outside of tzcode!) */
#if __GNUC__ < 3
# define ATTRIBUTE_CONST ATTRIBUTE_UNSEQUENCED
# define ATTRIBUTE_FORMAT(spec) /* empty */
# define ATTRIBUTE_PURE ATTRIBUTE_REPRODUCIBLE
#else
# define ATTRIBUTE_CONST __attribute__((const))
# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
# define ATTRIBUTE_PURE __attribute__((pure))
#endif
@@ -573,6 +643,12 @@ typedef unsigned long uintmax_t;
#else
# define ATTRIBUTE_PURE_114833 /* empty */
#endif
/* GCC_LINT hack to pacify GCC bug 114833 even though the attribute is
not strictly correct, as the function might not return whereas pure
functions are supposed to return exactly once. This hack is not
known to generate wrong code for tzcode on any platform.
Remove this macro and its uses when the bug is fixed in a GCC release. */
#define ATTRIBUTE_PURE_114833_HACK ATTRIBUTE_PURE_114833
#if (__STDC_VERSION__ < 199901 && !defined restrict \
&& (PORT_TO_C89 || defined _MSC_VER))
@@ -593,6 +669,12 @@ typedef unsigned long uintmax_t;
# define RESERVE_STD_EXT_IDS 0
#endif
#ifdef time_tz
# define defined_time_tz true
#else
# define defined_time_tz false
#endif
/* If standard C identifiers with external linkage (e.g., localtime)
are reserved and are not already being renamed anyway, rename them
as if compiling with '-Dtime_tz=time_t'. */
@@ -608,9 +690,9 @@ typedef unsigned long uintmax_t;
** typical platforms.
*/
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
# define TZ_TIME_T 1
# define TZ_TIME_T true
#else
# define TZ_TIME_T 0
# define TZ_TIME_T false
#endif
#if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
@@ -643,6 +725,8 @@ typedef time_tz tz_time_t;
# define mktime_z tz_mktime_z
# undef offtime
# define offtime tz_offtime
# undef offtime_r
# define offtime_r tz_offtime_r
# undef posix2time
# define posix2time tz_posix2time
# undef posix2time_z
@@ -701,11 +785,11 @@ typedef time_tz tz_time_t;
# endif
DEPRECATED_IN_C23 char *asctime(struct tm const *);
DEPRECATED_IN_C23 char *ctime(time_t const *);
#if SUPPORT_POSIX2008
# if SUPPORT_POSIX2008
char *asctime_r(struct tm const *restrict, char *restrict);
char *ctime_r(time_t const *, char *);
#endif
double difftime(time_t, time_t);
# endif
ATTRIBUTE_CONST double difftime(time_t, time_t);
size_t strftime(char *restrict, size_t, char const *restrict,
struct tm const *restrict);
# if HAVE_STRFTIME_L
@@ -727,9 +811,9 @@ void tzset(void);
|| defined __GLIBC__ || defined __tm_zone /* musl */ \
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__))
# define HAVE_DECL_TIMEGM true
# define HAVE_DECL_TIMEGM 1
# else
# define HAVE_DECL_TIMEGM false
# define HAVE_DECL_TIMEGM 0
# endif
#endif
#if !HAVE_DECL_TIMEGM && !defined timegm
@@ -752,6 +836,23 @@ extern char *asctime_r(struct tm const *restrict, char *restrict);
extern char **environ;
#endif
#ifndef HAVE_MEMPCPY
# if (defined mempcpy \
|| defined __FreeBSD__ || defined __NetBSD__ || defined __linux__)
# define HAVE_MEMPCPY 1
# else
# define HAVE_MEMPCPY 0
# endif
#endif
#if !HAVE_MEMPCPY
static void *
mempcpy(void *restrict s1, void const *restrict s2, size_t n)
{
char *p = memcpy(s1, s2, n);
return p + n;
}
#endif
#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
extern char *tzname[];
#endif
@@ -769,12 +870,19 @@ extern long altzone;
*/
#ifndef STD_INSPIRED
# define STD_INSPIRED 0
# ifdef __NetBSD__
# define STD_INSPIRED 1
# else
# define STD_INSPIRED 0
# endif
#endif
#if STD_INSPIRED
# if TZ_TIME_T || !defined offtime
struct tm *offtime(time_t const *, long);
# endif
# if TZ_TIME_T || !defined offtime_r
struct tm *offtime_r(time_t const *restrict, long, struct tm *restrict);
# endif
# if TZ_TIME_T || !defined timelocal
time_t timelocal(struct tm *);
# endif
@@ -805,26 +913,32 @@ time_t posix2time(time_t);
#endif
/*
** Define functions that are ABI compatible with NetBSD but have
** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
** and labors under the misconception that 'const timezone_t' is a
** pointer to a constant. This use of 'const' is ineffective, so it
** is not done here. What we call 'struct state' NetBSD calls
** Define functions that are ABI compatible with NetBSD.
** What we call 'struct state' NetBSD calls
** 'struct __state', but this is a private name so it doesn't matter.
*/
#if NETBSD_INSPIRED
# ifdef _NETBSD_SOURCE
# define state __state
# else
typedef struct state *timezone_t;
# endif
struct tm *localtime_rz(timezone_t restrict, time_t const *restrict,
struct tm *restrict);
time_t mktime_z(timezone_t restrict, struct tm *restrict);
timezone_t tzalloc(char const *);
void tzfree(timezone_t);
# if STD_INSPIRED
# if TZ_RUNTIME_LEAPS
# define ATTRIBUTE_POSIX2TIME ATTRIBUTE_PURE
# else
# define ATTRIBUTE_POSIX2TIME ATTRIBUTE_CONST
# endif
# if TZ_TIME_T || !defined posix2time_z
ATTRIBUTE_PURE time_t posix2time_z(timezone_t, time_t);
ATTRIBUTE_POSIX2TIME time_t posix2time_z(timezone_t, time_t);
# endif
# if TZ_TIME_T || !defined time2posix_z
ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t);
ATTRIBUTE_POSIX2TIME time_t time2posix_z(timezone_t, time_t);
# endif
# endif
#endif
@@ -835,7 +949,7 @@ ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t);
#define TYPE_BIT(type) (CHAR_BIT * (ptrdiff_t) sizeof(type))
#define TYPE_SIGNED(type) (((type) -1) < 0)
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
#define TWOS_COMPLEMENT(type) (TYPE_SIGNED (type) && (! ~ (type) -1))
/* Minimum and maximum of two values. Use lower case to avoid
naming clashes with standard include files. */
@@ -875,7 +989,7 @@ ATTRIBUTE_PURE time_t time2posix_z(timezone_t, time_t);
default: TIME_T_MAX_NO_PADDING) \
: (time_t) -1)
enum { SIGNED_PADDING_CHECK_NEEDED
= _Generic((time_t) 0,
= _Generic((time_t) 0,
signed char: false, short: false,
int: false, long: false, long long: false,
default: true) };
@@ -922,8 +1036,8 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
# define UNINIT_TRAP 0
#endif
/* localtime.c sometimes needs access to timeoff if it is not already public.
tz_private_timeoff should be used only by localtime.c. */
/* strftime.c sometimes needs access to timeoff if it is not already public.
tz_private_timeoff should be used only by localtime.c and strftime.c. */
#if (!defined EXTERN_TIMEOFF \
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
# ifndef timeoff
@@ -958,23 +1072,27 @@ time_t timeoff(struct tm *, long);
*/
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
# define _(msgid) gettext(msgid)
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
# define _(msgid) (msgid)
#endif /* !HAVE_GETTEXT */
#define N_(msgid) (msgid)
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
# define TZ_DOMAIN "tz"
#endif
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
# undef asctime_r
# undef ctime_r
char *asctime_r(struct tm const *restrict, char *restrict);
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Handy macros that are independent of tzfile implementation. */
/* Handy constants that are independent of tzfile implementation. */
/* 2**31 - 1 as a signed integer, and usable in #if. */
#define TWO_31_MINUS_1 2147483647
enum {
SECSPERMIN = 60,
+10 -16
View File
@@ -17,22 +17,14 @@
** Thank you!
*/
/*
** Information about time zone files.
*/
#ifndef TZDEFRULES
# define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
/* See Internet RFC 8536 for more details about the following format. */
/* Information about time zone files.
See Internet RFC 9636 for more details about the following format. */
/*
** Each file begins with. . .
*/
#define TZ_MAGIC "TZif"
#define TZ_MAGIC "TZif"
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
@@ -97,23 +89,25 @@ struct tzhead {
*/
#ifndef TZ_MAX_TIMES
/* This must be at least 242 for Europe/London with 'zic -b fat'. */
/* The following limit applies to localtime.c; zic has no such limit.
The limit must be at least 310 for Asia/Hebron with 'zic -b fat'. */
# define TZ_MAX_TIMES 2000
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
/* This must be at least 18 for Europe/Vilnius with 'zic -b fat'. */
# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
# define TZ_MAX_TYPES 256 /* Limited to 256 by Internet RFC 9636. */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
/* This must be at least 40 for America/Anchorage. */
# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
# define TZ_MAX_CHARS 256 /* Maximum number of abbreviation characters */
/* (limited to 256 by Internet RFC 9636) */
#endif /* !defined TZ_MAX_CHARS */
#ifndef TZ_MAX_LEAPS
/* This must be at least 27 for leap seconds from 1972 through mid-2023.
/* The following limit applies to localtime.c; zic has no such limit.
The limit must be at least 27 for leap seconds from 1972 through mid-2023.
There's a plan to discontinue leap seconds by 2035. */
# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
+8 -7
View File
@@ -145,9 +145,11 @@ do
t*) # Undocumented option, used for developer testing.
zonetabtype=$OPTARG;;
-help)
exec echo "$usage";;
say "$usage"
exit;;
-version)
exec echo "tzselect $PKGVERSION$TZVERSION";;
say "tzselect $PKGVERSION$TZVERSION"
exit;;
-*)
say >&2 "$0: -$opt$OPTARG: unknown option; try '$0 --help'"; exit 1;;
*)
@@ -161,15 +163,15 @@ case $# in
*) say >&2 "$0: $1: unknown argument"; exit 1
esac
# translit=true to try transliteration.
# translit=: to try transliteration.
# This is false if U+12345 CUNEIFORM SIGN URU TIMES KI has length 1
# which means the shell and (presumably) awk do not need transliteration.
# It is true if the byte string has some other length in characters, or
# It is ':' if the byte string has some other length in characters, or
# if this is a POSIX.1-2017 or earlier shell that does not support $'...'.
CUNEIFORM_SIGN_URU_TIMES_KI=$'\360\222\215\205'
if test ${#CUNEIFORM_SIGN_URU_TIMES_KI} = 1
then translit=false
else translit=true
else translit=:
fi
# Read into shell variable $1 the contents of file $2.
@@ -516,8 +518,7 @@ while
' ="$distance_table"
)
echo >&2 'Please select one of the following timezones,'
echo >&2 'listed roughly in increasing order' \
"of distance from $coord".
say >&2 "listed roughly in increasing order of distance from $coord."
doselect $regions
region=$select_result
tz=$(
+1 -1
View File
@@ -1 +1 @@
2024a
2026b
+35 -48
View File
@@ -14,10 +14,6 @@
#include "private.h"
#include <stdio.h>
#ifndef HAVE_SNPRINTF
# define HAVE_SNPRINTF (!PORT_TO_C89 || 199901 <= __STDC_VERSION__)
#endif
#ifndef HAVE_LOCALTIME_R
# define HAVE_LOCALTIME_R 1
#endif
@@ -65,13 +61,6 @@ enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
# define timezone_t char **
#endif
#if !HAVE_POSIX_DECLS
extern int getopt(int argc, char * const argv[],
const char * options);
extern char * optarg;
extern int optind;
#endif
/* The minimum and maximum finite time values. */
enum { atime_shift = CHAR_BIT * sizeof(time_t) - 2 };
static time_t const absolute_min_time =
@@ -134,7 +123,8 @@ size_overflow(void)
/* Return A + B, exiting if the result would overflow either ptrdiff_t
or size_t. A and B are both nonnegative. */
ATTRIBUTE_PURE_114833 static ptrdiff_t
ATTRIBUTE_PURE_114833_HACK
static ptrdiff_t
sumsize(ptrdiff_t a, ptrdiff_t b)
{
#ifdef ckd_add
@@ -148,17 +138,6 @@ sumsize(ptrdiff_t a, ptrdiff_t b)
size_overflow();
}
/* Return the size of of the string STR, including its trailing NUL.
Report an error and exit if this would exceed INDEX_MAX which means
pointer subtraction wouldn't work. */
static ptrdiff_t
xstrsize(char const *str)
{
size_t len = strlen(str);
if (len < INDEX_MAX)
return len + 1;
size_overflow();
}
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
on failure. SIZE should be positive. */
@@ -266,7 +245,7 @@ tzalloc(char const *val)
static ptrdiff_t fakeenv0size;
void *freeable = NULL;
char **env = fakeenv, **initial_environ;
ptrdiff_t valsize = xstrsize(val);
ptrdiff_t valsize = strlen(val) + 1;
if (fakeenv0size < valsize) {
char **e = environ, **to;
ptrdiff_t initial_nenvptrs = 1; /* Counting the trailing NULL pointer. */
@@ -425,7 +404,7 @@ saveabbr(char **buf, ptrdiff_t *bufalloc, struct tm const *tmp)
if (HAVE_LOCALTIME_RZ)
return ab;
else {
ptrdiff_t absize = xstrsize(ab);
ptrdiff_t absize = strlen(ab) + 1;
if (*bufalloc < absize) {
free(*buf);
@@ -487,6 +466,7 @@ main(int argc, char *argv[])
register time_t cuthitime;
time_t now;
bool iflag = false;
size_t arglenmax = 0;
cutlotime = absolute_min_time;
cuthitime = absolute_max_time;
@@ -586,15 +566,21 @@ main(int argc, char *argv[])
now = time(NULL);
now |= !now;
}
longest = 0;
for (i = optind; i < argc; i++) {
size_t arglen = strlen(argv[i]);
if (longest < arglen)
longest = min(arglen, INT_MAX);
if (arglenmax < arglen)
arglenmax = arglen;
}
if (!HAVE_SETENV && INDEX_MAX <= arglenmax)
size_overflow();
longest = min(arglenmax, INT_MAX - 2);
for (i = optind; i < argc; ++i) {
timezone_t tz = tzalloc(argv[i]);
/* Treat "-" as standard input on platforms with /dev/stdin.
It's not worth the bother of supporting "-" on other
platforms, as that would need temp files. */
timezone_t tz = tzalloc(strcmp(argv[i], "-") == 0
? "/dev/stdin" : argv[i]);
char const *ab;
time_t t;
struct tm tm, newtm;
@@ -695,7 +681,7 @@ yeartot(intmax_t y)
return absolute_max_time;
seconds = diff400 * SECSPER400YEARS;
years = diff400 * 400;
} else {
} else {
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
years = 1;
}
@@ -926,18 +912,16 @@ showextrema(timezone_t tz, char *zone, time_t lo, struct tm *lotmp, time_t hi)
}
}
#if HAVE_SNPRINTF
# define my_snprintf snprintf
#else
/* On pre-C99 platforms, a snprintf substitute good enough for us. */
#if !HAVE_SNPRINTF
# include <stdarg.h>
/* A substitute for snprintf that is good enough for zdump. */
static int
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
my_snprintf(char *s, size_t size, char const *format, ...)
{
int n;
va_list args;
char const *arg;
char *cp;
size_t arglen, slen;
char buf[1024];
va_start(args, format);
@@ -954,12 +938,14 @@ my_snprintf(char *s, size_t size, char const *format, ...)
arglen = n;
}
slen = arglen < size ? arglen : size - 1;
memcpy(s, arg, slen);
s[slen] = '\0';
cp = s;
cp = mempcpy(cp, arg, slen);
*cp = '\0';
n = arglen <= INT_MAX ? arglen : -1;
va_end(args);
return n;
}
# define snprintf my_snprintf
#endif
/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
@@ -974,10 +960,10 @@ format_local_time(char *buf, ptrdiff_t size, struct tm const *tm)
{
int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
return (ss
? my_snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
? snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
: mm
? my_snprintf(buf, size, "%02d:%02d", hh, mm)
: my_snprintf(buf, size, "%02d", hh));
? snprintf(buf, size, "%02d:%02d", hh, mm)
: snprintf(buf, size, "%02d", hh));
}
/* Store into BUF, of size SIZE, a formatted UT offset for the
@@ -1012,10 +998,10 @@ format_utc_offset(char *buf, ptrdiff_t size, struct tm const *tm, time_t t)
mm = off / 60 % 60;
hh = off / 60 / 60;
return (ss || 100 <= hh
? my_snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
? snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
: mm
? my_snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
: my_snprintf(buf, size, "%c%02ld", sign, hh));
? snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
: snprintf(buf, size, "%c%02ld", sign, hh));
}
/* Store into BUF (of size SIZE) a quoted string representation of P.
@@ -1083,8 +1069,9 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
char fbuf[100];
bool oversized = sizeof fbuf <= f_prefix_copy_size;
char *f_prefix_copy = oversized ? xmalloc(f_prefix_copy_size) : fbuf;
memcpy(f_prefix_copy, f, f_prefix_len);
strcpy(f_prefix_copy + f_prefix_len, "X");
char *cp = f_prefix_copy;
cp = mempcpy(cp, f, f_prefix_len);
strcpy(cp, "X");
formatted_len = strftime(b, s, f_prefix_copy, tm);
if (oversized)
free(f_prefix_copy);
@@ -1118,7 +1105,7 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
for (abp = ab; is_alpha(*abp); abp++)
continue;
len = (!*abp && *ab
? my_snprintf(b, s, "%s", ab)
? snprintf(b, s, "%s", ab)
: format_quoted_string(b, s, ab));
if (s <= len)
return false;
@@ -1126,7 +1113,7 @@ istrftime(char *buf, ptrdiff_t size, char const *time_fmt,
}
formatted_len
= (tm->tm_isdst
? my_snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
? snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
: 0);
}
break;
+659 -306
View File
File diff suppressed because it is too large Load Diff