1 /* Convert timestamp from time_t to struct tm. */ 2 3 /* 4 ** This file is in the public domain, so clarified as of 5 ** 1996-06-05 by Arthur David Olson. 6 */ 7 8 /* 9 ** Leap second handling from Bradley White. 10 ** POSIX.1-1988 style TZ environment variable handling from Guy Harris. 11 */ 12 13 /*LINTLIBRARY*/ 14 15 #define LOCALTIME_IMPLEMENTATION 16 #include "private.h" 17 18 #include "tzdir.h" 19 #include "tzfile.h" 20 #include <fcntl.h> 21 22 #if HAVE_SYS_STAT_H 23 # include <sys/stat.h> 24 # ifndef S_ISREG 25 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) /* Ancient UNIX. */ 26 # endif 27 #else 28 struct stat { char st_ctime, st_dev, st_ino; }; 29 # define dev_t char 30 # define ino_t char 31 # define fstat(fd, st) (memset(st, 0, sizeof *(st)), 0) 32 # define stat(name, st) fstat(0, st) 33 # define S_ISREG(mode) 1 34 #endif 35 36 #ifndef HAVE_STRUCT_STAT_ST_CTIM 37 # define HAVE_STRUCT_STAT_ST_CTIM 1 38 #endif 39 #if !defined st_ctim && defined __APPLE__ && defined __MACH__ 40 # define st_ctim st_ctimespec 41 #endif 42 43 #ifndef THREAD_SAFE 44 # define THREAD_SAFE 0 45 #endif 46 47 #ifndef THREAD_RWLOCK 48 # define THREAD_RWLOCK 0 49 #endif 50 51 #ifndef THREAD_TM_MULTI 52 # define THREAD_TM_MULTI 0 53 #endif 54 55 #ifndef USE_TIMEX_T 56 # define USE_TIMEX_T false 57 #endif 58 59 #if THREAD_SAFE 60 # include <pthread.h> 61 62 # ifndef THREAD_PREFER_SINGLE 63 # define THREAD_PREFER_SINGLE 0 64 # endif 65 # if THREAD_PREFER_SINGLE 66 # ifndef HAVE___ISTHREADED 67 # if defined __FreeBSD__ || defined __OpenBSD__ 68 # define HAVE___ISTHREADED 1 69 # else 70 # define HAVE___ISTHREADED 0 71 # endif 72 # endif 73 # if HAVE___ISTHREADED 74 extern int __isthreaded; 75 # else 76 # if !defined HAVE_SYS_SINGLE_THREADED_H && defined __has_include 77 # if __has_include(<sys/single_threaded.h>) 78 # define HAVE_SYS_SINGLE_THREADED_H 1 79 # else 80 # define HAVE_SYS_SINGLE_THREADED_H 0 81 # endif 82 # endif 83 # ifndef HAVE_SYS_SINGLE_THREADED_H 84 # if defined __GLIBC__ && 2 < __GLIBC__ + (32 <= __GLIBC_MINOR__) 85 # define HAVE_SYS_SINGLE_THREADED_H 1 86 # else 87 # define HAVE_SYS_SINGLE_THREADED_H 0 88 # endif 89 # endif 90 # if HAVE_SYS_SINGLE_THREADED_H 91 # include <sys/single_threaded.h> 92 # endif 93 # endif 94 # endif 95 #endif 96 97 #if !defined TM_GMTOFF || !USE_TIMEX_T 98 # if THREAD_SAFE 99 100 /* True if the current process might be multi-threaded, 101 false if it is definitely single-threaded. 102 If false, it will be false the next time it is called 103 unless the caller creates a thread in the meantime. 104 If true, it might become false the next time it is called 105 if all other threads exit in the meantime. */ 106 static bool 107 is_threaded(void) 108 { 109 # if THREAD_PREFER_SINGLE && HAVE___ISTHREADED 110 return !!__isthreaded; 111 # elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H 112 return !__libc_single_threaded; 113 # else 114 return true; 115 # endif 116 } 117 118 # if THREAD_RWLOCK 119 static pthread_rwlock_t locallock = PTHREAD_RWLOCK_INITIALIZER; 120 static int dolock(void) { return pthread_rwlock_rdlock(&locallock); } 121 static void dounlock(void) { pthread_rwlock_unlock(&locallock); } 122 # else 123 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; 124 static int dolock(void) { return pthread_mutex_lock(&locallock); } 125 static void dounlock(void) { pthread_mutex_unlock(&locallock); } 126 # endif 127 128 /* Get a lock. Return 0 on success, a positive errno value on failure, 129 negative if known to be single-threaded so no lock is needed. */ 130 static int 131 lock(void) 132 { 133 if (!is_threaded()) 134 return -1; 135 return dolock(); 136 } 137 static void 138 unlock(bool threaded) 139 { 140 if (threaded) 141 dounlock(); 142 } 143 # else 144 static int lock(void) { return -1; } 145 static void unlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) { } 146 # endif 147 #endif 148 149 #if THREAD_SAFE 150 typedef pthread_once_t once_t; 151 # define ONCE_INIT PTHREAD_ONCE_INIT 152 #else 153 typedef bool once_t; 154 # define ONCE_INIT false 155 #endif 156 157 static void 158 once(once_t *once_control, void init_routine(void)) 159 { 160 #if THREAD_SAFE 161 pthread_once(once_control, init_routine); 162 #else 163 if (!*once_control) { 164 *once_control = true; 165 init_routine(); 166 } 167 #endif 168 } 169 170 enum tm_multi { LOCALTIME_TM_MULTI, GMTIME_TM_MULTI, OFFTIME_TM_MULTI }; 171 172 #if THREAD_SAFE && THREAD_TM_MULTI 173 174 enum { N_TM_MULTI = OFFTIME_TM_MULTI + 1 }; 175 static pthread_key_t tm_multi_key; 176 static int tm_multi_key_err; 177 178 static void 179 tm_multi_key_init(void) 180 { 181 tm_multi_key_err = pthread_key_create(&tm_multi_key, free); 182 } 183 184 #endif 185 186 /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. 187 Use this carefully, as the casts disable type checking. 188 This is a macro so that it can be used in static initializers. */ 189 #ifdef INTPTR_MAX 190 # define UNCONST(a) ((char *) (intptr_t) (a)) 191 #else 192 # define UNCONST(a) ((char *) (a)) 193 #endif 194 195 /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year 196 without overflow. The static_assert checks that it is indeed wider 197 than int; if this fails on your platform please let us know. */ 198 #if INT_MAX < LONG_MAX 199 typedef long iinntt; 200 # define IINNTT_MIN LONG_MIN 201 # define IINNTT_MAX LONG_MAX 202 #elif INT_MAX < LLONG_MAX 203 typedef long long iinntt; 204 # define IINNTT_MIN LLONG_MIN 205 # define IINNTT_MAX LLONG_MAX 206 #else 207 typedef intmax_t iinntt; 208 # define IINNTT_MIN INTMAX_MIN 209 # define IINNTT_MAX INTMAX_MAX 210 #endif 211 static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX); 212 213 #ifndef HAVE_STRUCT_TIMESPEC 214 # define HAVE_STRUCT_TIMESPEC 1 215 #endif 216 #if !HAVE_STRUCT_TIMESPEC 217 struct timespec { time_t tv_sec; long tv_nsec; }; 218 #endif 219 220 #if !defined CLOCK_MONOTONIC_COARSE && defined CLOCK_MONOTONIC 221 # define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC 222 #endif 223 #ifndef CLOCK_MONOTONIC_COARSE 224 # undef clock_gettime 225 # define clock_gettime(id, t) ((t)->tv_sec = time(NULL), (t)->tv_nsec = 0, 0) 226 #endif 227 228 /* How many seconds to wait before checking the default TZif file again. 229 Negative means no checking. Default to 61 if DETECT_TZ_CHANGES 230 (as FreeBSD optionally builds its localtime.c with -DDETECT_TZ_CHANGES), 231 and to -1 otherwise. */ 232 #ifndef TZ_CHANGE_INTERVAL 233 # ifdef DETECT_TZ_CHANGES 234 # define TZ_CHANGE_INTERVAL 61 235 # else 236 # define TZ_CHANGE_INTERVAL (-1) 237 # endif 238 #endif 239 static_assert(TZ_CHANGE_INTERVAL < 0 || HAVE_SYS_STAT_H); 240 241 /* The change detection interval. */ 242 #if TZ_CHANGE_INTERVAL < 0 || !defined __FreeBSD__ 243 enum { tz_change_interval = TZ_CHANGE_INTERVAL }; 244 #else 245 /* FreeBSD uses this private-but-extern var in its internal test suite. */ 246 int __tz_change_interval = TZ_CHANGE_INTERVAL; 247 # define tz_change_interval __tz_change_interval 248 #endif 249 250 /* The type of monotonic times. 251 This is the system time_t, even if USE_TIMEX_T #defines time_t below. */ 252 typedef time_t monotime_t; 253 254 /* On platforms where offtime or mktime might overflow, 255 strftime.c defines USE_TIMEX_T to be true and includes us. 256 This tells us to #define time_t to an internal type timex_t that is 257 wide enough so that strftime %s never suffers from integer overflow, 258 and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise) 259 to a static function that returns the redefined time_t. 260 It also tells us to define only data and code needed 261 to support the offtime or mktime variant. */ 262 #if USE_TIMEX_T 263 # undef TIME_T_MIN 264 # undef TIME_T_MAX 265 # undef time_t 266 # define time_t timex_t 267 # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX) 268 typedef long timex_t; 269 # define TIME_T_MIN LONG_MIN 270 # define TIME_T_MAX LONG_MAX 271 # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX) 272 typedef long long timex_t; 273 # define TIME_T_MIN LLONG_MIN 274 # define TIME_T_MAX LLONG_MAX 275 # else 276 typedef intmax_t timex_t; 277 # define TIME_T_MIN INTMAX_MIN 278 # define TIME_T_MAX INTMAX_MAX 279 # endif 280 281 # ifdef TM_GMTOFF 282 # undef timeoff 283 # define timeoff timex_timeoff 284 # undef EXTERN_TIMEOFF 285 # else 286 # undef mktime 287 # define mktime timex_mktime 288 # endif 289 #endif 290 291 /* Placeholders for platforms lacking AT_FCWD, openat, and fstatat. */ 292 #ifndef AT_FDCWD 293 # define AT_FDCWD (-1) /* any negative value will do */ 294 static int openat(int dd, char const *path, int oflag) { unreachable (); } 295 static int fstatat(int dd, char const *path, struct stat *st, int flags) 296 { unreachable(); } 297 #endif 298 299 /* Port to platforms that lack some O_* flags. Unless otherwise 300 specified, the flags are standardized by POSIX. */ 301 302 #ifndef O_BINARY 303 # define O_BINARY 0 /* MS-Windows */ 304 #endif 305 #ifndef O_CLOEXEC 306 # define O_CLOEXEC 0 307 #endif 308 #ifndef O_CLOFORK 309 # define O_CLOFORK 0 310 #endif 311 #ifndef O_DIRECTORY 312 # define O_DIRECTORY 0 313 #endif 314 #ifndef O_IGNORE_CTTY 315 # define O_IGNORE_CTTY 0 /* GNU/Hurd */ 316 #endif 317 #ifndef O_NOCTTY 318 # define O_NOCTTY 0 319 #endif 320 #ifndef O_PATH 321 # define O_PATH 0 322 #endif 323 #ifndef O_REGULAR 324 # define O_REGULAR 0 325 #endif 326 #ifndef O_RESOLVE_BENEATH 327 # define O_RESOLVE_BENEATH 0 328 #endif 329 #ifndef O_SEARCH 330 # define O_SEARCH 0 331 #endif 332 333 #if !HAVE_ISSETUGID 334 335 # if !defined HAVE_SYS_AUXV_H && defined __has_include 336 # if __has_include(<sys/auxv.h>) 337 # define HAVE_SYS_AUXV_H 1 338 # endif 339 # endif 340 # ifndef HAVE_SYS_AUXV_H 341 # if defined __GLIBC__ && 2 < __GLIBC__ + (19 <= __GLIBC_MINOR__) 342 # define HAVE_SYS_AUXV_H 1 343 # else 344 # define HAVE_SYS_AUXV_H 0 345 # endif 346 # endif 347 # if HAVE_SYS_AUXV_H 348 # include <sys/auxv.h> 349 # endif 350 351 /* Return 1 if the process is privileged, 0 otherwise. */ 352 static int 353 issetugid(void) 354 { 355 # if HAVE_SYS_AUXV_H && defined AT_SECURE 356 unsigned long val; 357 errno = 0; 358 val = getauxval(AT_SECURE); 359 if (val || errno != ENOENT) 360 return !!val; 361 # endif 362 # if HAVE_GETRESUID 363 { 364 uid_t ruid, euid, suid; 365 gid_t rgid, egid, sgid; 366 if (0 <= getresuid (&ruid, &euid, &suid)) { 367 if ((ruid ^ euid) | (ruid ^ suid)) 368 return 1; 369 if (0 <= getresgid (&rgid, &egid, &sgid)) 370 return !!((rgid ^ egid) | (rgid ^ sgid)); 371 } 372 } 373 # endif 374 # if HAVE_GETEUID 375 return geteuid() != getuid() || getegid() != getgid(); 376 # else 377 return 0; 378 # endif 379 } 380 #endif 381 382 #ifndef WILDABBR 383 /* 384 ** Someone might make incorrect use of a time zone abbreviation: 385 ** 1. They might reference tzname[0] before calling tzset (explicitly 386 ** or implicitly). 387 ** 2. They might reference tzname[1] before calling tzset (explicitly 388 ** or implicitly). 389 ** 3. They might reference tzname[1] after setting to a time zone 390 ** in which Daylight Saving Time is never observed. 391 ** 4. They might reference tzname[0] after setting to a time zone 392 ** in which Standard Time is never observed. 393 ** 5. They might reference tm.TM_ZONE after calling offtime. 394 ** What's best to do in the above cases is open to debate; 395 ** for now, we just set things up so that in any of the five cases 396 ** WILDABBR is used. Another possibility: initialize tzname[0] to the 397 ** string "tzname[0] used before set", and similarly for the other cases. 398 ** And another: initialize tzname[0] to "ERA", with an explanation in the 399 ** manual page of what this "time zone abbreviation" means (doing this so 400 ** that tzname[0] has the "normal" length of three characters). 401 */ 402 # define WILDABBR " " 403 #endif /* !defined WILDABBR */ 404 405 static const char wildabbr[] = WILDABBR; 406 407 static char const etc_utc[] = "Etc/UTC"; 408 409 #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF 410 static char const *utc = etc_utc + sizeof "Etc/" - 1; 411 #endif 412 413 /* 414 ** The DST rules to use if TZ has no rules. 415 ** Default to US rules as of 2017-05-07. 416 ** POSIX does not specify the default DST rules; 417 ** for historical reasons, US rules are a common default. 418 */ 419 #ifndef TZDEFRULESTRING 420 # define TZDEFRULESTRING ",M3.2.0,M11.1.0" 421 #endif 422 423 /* If compiled with -DOPENAT_TZDIR, then when accessing a relative 424 name like "America/Los_Angeles", first open TZDIR (default 425 "/usr/share/zoneinfo") as a directory and then use the result in 426 openat with "America/Los_Angeles", rather than the traditional 427 approach of opening "/usr/share/zoneinfo/America/Los_Angeles". 428 Although the OPENAT_TZDIR approach is less efficient, suffers from 429 spurious EMFILE and ENFILE failures, and is no more secure in practice, 430 bleeding edge FreeBSD started doing it this way in August 2025. */ 431 #ifndef OPENAT_TZDIR 432 # define OPENAT_TZDIR 0 433 #endif 434 435 /* If compiled with -DSUPPRESS_TZDIR, do not prepend TZDIR to relative TZ. 436 This is intended for specialized applications only, due to its 437 security implications. */ 438 #ifndef SUPPRESS_TZDIR 439 # define SUPPRESS_TZDIR 0 440 #endif 441 442 /* Limit to time zone abbreviation length in proleptic TZ strings. 443 This is distinct from TZ_MAX_CHARS, which limits TZif file contents. 444 It defaults to 254, not 255, so that desigidx_type can be an unsigned char. 445 unsigned char suffices for TZif files, so the only reason to increase 446 TZNAME_MAXIMUM is to support TZ strings specifying abbreviations 447 longer than 254 bytes. There is little reason to do that, though, 448 as strings that long are hardly "abbreviations". */ 449 #ifndef TZNAME_MAXIMUM 450 # define TZNAME_MAXIMUM 254 451 #endif 452 453 #if TZNAME_MAXIMUM < UCHAR_MAX 454 typedef unsigned char desigidx_type; 455 #elif TZNAME_MAXIMUM < INT_MAX 456 typedef int desigidx_type; 457 #elif TZNAME_MAXIMUM < PTRDIFF_MAX 458 typedef ptrdiff_t desigidx_type; 459 #else 460 # error "TZNAME_MAXIMUM too large" 461 #endif 462 463 /* A type that can represent any 32-bit two's complement integer, 464 i.e., any integer in the range -2**31 .. 2**31 - 1. 465 Ordinarily this is int_fast32_t, but on non-C23 hosts 466 that are not two's complement it is int_fast64_t. */ 467 #if INT_FAST32_MIN < -TWO_31_MINUS_1 468 typedef int_fast32_t int_fast32_2s; 469 #else 470 typedef int_fast64_t int_fast32_2s; 471 #endif 472 473 struct ttinfo { /* time type information */ 474 int_least32_t tt_utoff; /* UT offset in seconds; in the range 475 -2**31 + 1 .. 2**31 - 1 */ 476 desigidx_type tt_desigidx; /* abbreviation list index */ 477 bool tt_isdst; /* used to set tm_isdst */ 478 bool tt_ttisstd; /* transition is std time */ 479 bool tt_ttisut; /* transition is UT */ 480 }; 481 482 struct lsinfo { /* leap second information */ 483 time_t ls_trans; /* transition time (positive) */ 484 int_fast32_2s ls_corr; /* correction to apply */ 485 }; 486 487 /* This abbreviation means local time is unspecified. */ 488 static char const UNSPEC[] = "-00"; 489 490 /* How many extra bytes are needed at the end of struct state's chars array. 491 This needs to be at least 1 for null termination in case the input 492 data isn't properly terminated, and it also needs to be big enough 493 for ttunspecified to work without crashing. */ 494 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; 495 496 /* A representation of the contents of a TZif file. Ideally this 497 would have no size limits; the following sizes should suffice for 498 practical use. This struct should not be too large, as instances 499 are put on the stack and stacks are relatively small on some platforms. 500 See tzfile.h for more about the sizes. */ 501 struct state { 502 #if TZ_RUNTIME_LEAPS 503 int leapcnt; 504 #endif 505 int timecnt; 506 int typecnt; 507 int charcnt; 508 bool goback; 509 bool goahead; 510 time_t ats[TZ_MAX_TIMES]; 511 unsigned char types[TZ_MAX_TIMES]; 512 struct ttinfo ttis[TZ_MAX_TYPES]; 513 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"), 514 2 * (TZNAME_MAXIMUM + 1))]; 515 #if TZ_RUNTIME_LEAPS 516 struct lsinfo lsis[TZ_MAX_LEAPS]; 517 #endif 518 }; 519 520 static int 521 leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp) 522 { 523 #if TZ_RUNTIME_LEAPS 524 return sp->leapcnt; 525 #else 526 return 0; 527 #endif 528 } 529 static void 530 set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 531 ATTRIBUTE_MAYBE_UNUSED int leapcnt) 532 { 533 #if TZ_RUNTIME_LEAPS 534 sp->leapcnt = leapcnt; 535 #endif 536 } 537 static struct lsinfo 538 lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, 539 ATTRIBUTE_MAYBE_UNUSED int i) 540 { 541 #if TZ_RUNTIME_LEAPS 542 return sp->lsis[i]; 543 #else 544 unreachable(); 545 #endif 546 } 547 static void 548 set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 549 ATTRIBUTE_MAYBE_UNUSED int i, 550 ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo) 551 { 552 #if TZ_RUNTIME_LEAPS 553 sp->lsis[i] = lsinfo; 554 #endif 555 } 556 557 enum r_type { 558 JULIAN_DAY, /* Jn = Julian day */ 559 DAY_OF_YEAR, /* n = day of year */ 560 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 561 }; 562 563 struct rule { 564 enum r_type r_type; /* type of rule */ 565 int r_day; /* day number of rule */ 566 int r_week; /* week number of rule */ 567 int r_mon; /* month number of rule */ 568 int_fast32_t r_time; /* transition time of rule */ 569 }; 570 571 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 572 struct tm *); 573 static bool increment_overflow(int *, int); 574 static bool increment_overflow_time(time_t *, int_fast32_2s); 575 static int_fast32_2s leapcorr(struct state const *, time_t); 576 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 577 struct tm *); 578 static bool tzparse(char const *, struct state *, struct state const *); 579 580 #ifndef ALL_STATE 581 # define ALL_STATE 0 582 #endif 583 584 #if ALL_STATE 585 static struct state * lclptr; 586 static struct state * gmtptr; 587 #else 588 static struct state lclmem; 589 static struct state gmtmem; 590 static struct state *const lclptr = &lclmem; 591 static struct state *const gmtptr = &gmtmem; 592 #endif /* State Farm */ 593 594 /* Maximum number of bytes in an efficiently-handled TZ string. 595 Longer strings work, albeit less efficiently. */ 596 #ifndef TZ_STRLEN_MAX 597 # define TZ_STRLEN_MAX 255 598 #endif /* !defined TZ_STRLEN_MAX */ 599 600 #if !USE_TIMEX_T || !defined TM_GMTOFF 601 static char lcl_TZname[TZ_STRLEN_MAX + 1]; 602 static int lcl_is_set; 603 #endif 604 605 /* 606 ** Section 4.12.3 of X3.159-1989 requires that 607 ** Except for the strftime function, these functions [asctime, 608 ** ctime, gmtime, localtime] return values in one of two static 609 ** objects: a broken-down time structure and an array of char. 610 ** Thanks to Paul Eggert for noting this. 611 ** 612 ** Although this requirement was removed in C99 it is still present in POSIX. 613 ** Follow the requirement if SUPPORT_C89, even though this is more likely to 614 ** trigger latent bugs in programs. 615 */ 616 617 #if !USE_TIMEX_T 618 619 # if SUPPORT_C89 620 static struct tm tm; 621 # endif 622 623 # if 2 <= HAVE_TZNAME + TZ_TIME_T 624 char *tzname[2] = { UNCONST(wildabbr), UNCONST(wildabbr) }; 625 # endif 626 # if 2 <= USG_COMPAT + TZ_TIME_T 627 long timezone; 628 int daylight; 629 # endif 630 # if 2 <= ALTZONE + TZ_TIME_T 631 long altzone; 632 # endif 633 634 #endif 635 636 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ 637 static void 638 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, 639 desigidx_type desigidx) 640 { 641 s->tt_utoff = utoff; 642 s->tt_isdst = isdst; 643 s->tt_desigidx = desigidx; 644 s->tt_ttisstd = false; 645 s->tt_ttisut = false; 646 } 647 648 /* Return true if SP's time type I does not specify local time. */ 649 static bool 650 ttunspecified(struct state const *sp, int i) 651 { 652 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; 653 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ 654 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; 655 } 656 657 static int_fast32_2s 658 detzcode(const char *const codep) 659 { 660 register int i; 661 int_fast32_2s 662 maxval = TWO_31_MINUS_1, 663 minval = -1 - maxval, 664 result; 665 666 result = codep[0] & 0x7f; 667 for (i = 1; i < 4; ++i) 668 result = (result << 8) | (codep[i] & 0xff); 669 670 if (codep[0] & 0x80) { 671 /* Do two's-complement negation even on non-two's-complement machines. 672 This cannot overflow, as int_fast32_2s is wide enough. */ 673 result += minval; 674 } 675 return result; 676 } 677 678 static int_fast64_t 679 detzcode64(const char *const codep) 680 { 681 register int_fast64_t result; 682 register int i; 683 int_fast64_t one = 1; 684 int_fast64_t halfmaxval = one << (64 - 2); 685 int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 686 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 687 688 result = codep[0] & 0x7f; 689 for (i = 1; i < 8; ++i) 690 result = (result << 8) | (codep[i] & 0xff); 691 692 if (codep[0] & 0x80) { 693 /* Do two's-complement negation even on non-two's-complement machines. 694 If the result would be minval - 1, return minval. */ 695 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 696 result += minval; 697 } 698 return result; 699 } 700 701 #if !USE_TIMEX_T || !defined TM_GMTOFF 702 703 static void 704 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) 705 { 706 # if HAVE_TZNAME 707 tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]); 708 # endif 709 # if USG_COMPAT 710 if (!ttisp->tt_isdst) 711 timezone = - ttisp->tt_utoff; 712 # endif 713 # if ALTZONE 714 if (ttisp->tt_isdst) 715 altzone = - ttisp->tt_utoff; 716 # endif 717 } 718 719 /* If STDDST_MASK indicates that SP's TYPE provides useful info, 720 update tzname, timezone, and/or altzone and return STDDST_MASK, 721 diminished by the provided info if it is a specified local time. 722 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */ 723 static int 724 may_update_tzname_etc(int stddst_mask, struct state *sp, int type) 725 { 726 struct ttinfo *ttisp = &sp->ttis[type]; 727 int this_bit = 1 << ttisp->tt_isdst; 728 if (stddst_mask & this_bit) { 729 update_tzname_etc(sp, ttisp); 730 if (!ttunspecified(sp, type)) 731 return stddst_mask & ~this_bit; 732 } 733 return stddst_mask; 734 } 735 736 static void 737 settzname(void) 738 { 739 register struct state * const sp = lclptr; 740 register int i; 741 742 /* If STDDST_MASK & 1 we need info about a standard time. 743 If STDDST_MASK & 2 we need info about a daylight saving time. 744 When STDDST_MASK becomes zero we can stop looking. */ 745 int stddst_mask = 0; 746 747 # if HAVE_TZNAME 748 tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc); 749 stddst_mask = 3; 750 # endif 751 # if USG_COMPAT 752 timezone = 0; 753 stddst_mask = 3; 754 # endif 755 # if ALTZONE 756 altzone = 0; 757 stddst_mask |= 2; 758 # endif 759 /* 760 ** And to get the latest time zone abbreviations into tzname. . . 761 */ 762 if (sp) { 763 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--) 764 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]); 765 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--) 766 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i); 767 } 768 # if USG_COMPAT 769 daylight = stddst_mask >> 1 ^ 1; 770 # endif 771 } 772 773 /* Replace bogus characters in time zone abbreviations. 774 Return 0 on success, an errno value if a time zone abbreviation is 775 too long. */ 776 static int 777 scrub_abbrs(struct state *sp) 778 { 779 int i; 780 781 /* Reject overlong abbreviations. */ 782 for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) { 783 int len = strnlen(&sp->chars[i], TZNAME_MAXIMUM + 1); 784 if (TZNAME_MAXIMUM < len) 785 return EOVERFLOW; 786 i += len + 1; 787 } 788 789 /* Replace bogus characters. */ 790 for (i = 0; i < sp->charcnt; ++i) 791 switch (sp->chars[i]) { 792 case '\0': 793 case '+': case '-': case '.': 794 case '0': case '1': case '2': case '3': case '4': 795 case '5': case '6': case '7': case '8': case '9': 796 case ':': 797 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 798 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 799 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 800 case 'V': case 'W': case 'X': case 'Y': case 'Z': 801 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 802 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 803 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 804 case 'v': case 'w': case 'x': case 'y': case 'z': 805 break; 806 807 default: 808 sp->chars[i] = '_'; 809 break; 810 } 811 812 return 0; 813 } 814 815 #endif 816 817 /* Return true if the TZif file with descriptor FD changed, 818 or may have changed, since the last time we were called. 819 Return false if it did not change. 820 If *ST is valid it is the file's current status; 821 otherwise, update *ST to the status if possible. */ 822 static bool 823 tzfile_changed(int fd, struct stat *st) 824 { 825 /* If old_ctim.tv_sec, these variables hold the corresponding part 826 of the file's metadata the last time this function was called. */ 827 static struct timespec old_ctim; 828 static dev_t old_dev; 829 static ino_t old_ino; 830 831 if (!st->st_ctime && fstat(fd, st) < 0) { 832 /* We do not know the file's state, so reset. */ 833 old_ctim.tv_sec = 0; 834 return true; 835 } else { 836 /* Use the change time, as it changes more reliably; mod time can 837 be set back with futimens etc. Use subsecond timestamp 838 resolution if available, as this can help distinguish files on 839 non-POSIX platforms where st_dev and st_ino are unreliable. */ 840 struct timespec ctim; 841 #if HAVE_STRUCT_STAT_ST_CTIM 842 ctim = st->st_ctim; 843 #else 844 ctim.tv_sec = st->st_ctime; 845 ctim.tv_nsec = 0; 846 #endif 847 848 if ((ctim.tv_sec ^ old_ctim.tv_sec) | (ctim.tv_nsec ^ old_ctim.tv_nsec) 849 | (st->st_dev ^ old_dev) | (st->st_ino ^ old_ino)) { 850 old_ctim = ctim; 851 old_dev = st->st_dev; 852 old_ino = st->st_ino; 853 return true; 854 } 855 856 return false; 857 } 858 } 859 860 /* Input buffer for data read from a compiled tz file. */ 861 union input_buffer { 862 /* The first part of the buffer, interpreted as a header. */ 863 struct tzhead tzhead; 864 865 /* The entire buffer. Ideally this would have no size limits; 866 the following should suffice for practical use. */ 867 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 868 + 4 * TZ_MAX_TIMES]; 869 }; 870 871 /* TZDIR with a trailing '/'. It is null-terminated if OPENAT_TZDIR. */ 872 #if !OPENAT_TZDIR 873 ATTRIBUTE_NONSTRING 874 #endif 875 static char const tzdirslash[sizeof TZDIR + OPENAT_TZDIR] = TZDIR "/"; 876 enum { tzdirslashlen = sizeof TZDIR }; 877 #ifdef PATH_MAX 878 static_assert(tzdirslashlen <= PATH_MAX); /* Sanity check; assumed below. */ 879 #endif 880 881 /* Local storage needed for 'tzloadbody'. */ 882 union local_storage { 883 /* The results of analyzing the file's contents after it is opened. */ 884 struct file_analysis { 885 /* The input buffer. */ 886 union input_buffer u; 887 888 /* A temporary state used for parsing a TZ string in the file. */ 889 struct state st; 890 } u; 891 892 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 893 /* The name of the file to be opened. */ 894 char fullname[PATH_MAX]; 895 #endif 896 }; 897 898 /* These tzload flags can be ORed together, and fit into 'char'. */ 899 enum { TZLOAD_FROMENV = 1 }; /* The TZ string came from the environment. */ 900 enum { TZLOAD_TZSTRING = 2 }; /* Read any newline-surrounded TZ string. */ 901 enum { TZLOAD_TZDIR_SUB = 4 }; /* TZ should be a file under TZDIR. */ 902 903 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 904 Use **LSPP for temporary storage. Return 0 on 905 success, an errno value on failure. */ 906 static int 907 tzloadbody(char const *name, struct state *sp, char tzloadflags, 908 union local_storage **lspp) 909 { 910 register int i; 911 register int fid; 912 register int stored; 913 register ssize_t nread; 914 char const *relname; 915 union local_storage *lsp = *lspp; 916 union input_buffer *up; 917 register int tzheadsize = sizeof(struct tzhead); 918 int dd = AT_FDCWD; 919 int oflags = (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK 920 | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR); 921 bool might_escape = false; 922 int err; 923 struct stat st; 924 st.st_ctime = 0; 925 926 sp->goback = sp->goahead = false; 927 928 if (! name) { 929 name = TZDEFAULT; 930 if (! name) 931 return EINVAL; 932 #ifdef __FreeBSD__ 933 tzloadflags &= ~TZLOAD_FROMENV; 934 #endif /* __FreeBSD__ */ 935 } 936 937 if (name[0] == ':') 938 ++name; 939 940 relname = name; 941 942 /* If the program is privileged, NAME is TZDEFAULT or 943 subsidiary to TZDIR. Also, NAME is not a device. */ 944 if (name[0] == '/' && strcmp(name, TZDEFAULT) != 0) { 945 if (!SUPPRESS_TZDIR 946 && strncmp(relname, tzdirslash, tzdirslashlen) == 0) 947 for (relname += tzdirslashlen; *relname == '/'; relname++) 948 continue; 949 else if (issetugid()) 950 return ENOTCAPABLE; 951 else 952 might_escape = true; 953 } 954 955 if (relname[0] != '/') { 956 if (!OPENAT_TZDIR || !O_RESOLVE_BENEATH) { 957 /* Fail if a relative name contains a non-terminal ".." component, 958 as such a name could read a non-directory outside TZDIR 959 when AT_FDCWD and O_RESOLVE_BENEATH are not available. */ 960 char const *component; 961 for (component = relname; component[0]; component++) 962 if (component[0] == '.' && component[1] == '.' 963 && component[2] == '/' 964 && (component == relname || component[-1] == '/')) { 965 if (issetugid()) 966 return ENOTCAPABLE; 967 might_escape = true; 968 break; 969 } 970 } 971 972 if (OPENAT_TZDIR && !SUPPRESS_TZDIR) { 973 /* Prefer O_SEARCH or O_PATH if available; 974 O_RDONLY should be OK too, as TZDIR is invariably readable. 975 O_DIRECTORY should be redundant but might help 976 on old platforms that mishandle trailing '/'. */ 977 dd = open(tzdirslash, 978 ((O_SEARCH ? O_SEARCH : O_PATH ? O_PATH : O_RDONLY) 979 | O_BINARY | O_CLOEXEC | O_CLOFORK | O_DIRECTORY)); 980 if (dd < 0) 981 return errno; 982 if (O_RESOLVE_BENEATH && issetugid()) { 983 oflags |= O_RESOLVE_BENEATH; 984 might_escape = false; 985 } 986 } 987 } 988 989 if (!OPENAT_TZDIR && !SUPPRESS_TZDIR && name[0] != '/') { 990 char *cp; 991 size_t fullnamesize; 992 #ifdef PATH_MAX 993 size_t namesizemax = PATH_MAX - tzdirslashlen; 994 size_t namelen = strnlen (name, namesizemax); 995 if (namesizemax <= namelen) 996 return ENAMETOOLONG; 997 #else 998 size_t namelen = strlen (name); 999 #endif 1000 fullnamesize = tzdirslashlen + namelen + 1; 1001 1002 /* Create a string "TZDIR/NAME". Using sprintf here 1003 would pull in stdio (and would fail if the 1004 resulting string length exceeded INT_MAX!). */ 1005 if (ALL_STATE || sizeof *lsp < fullnamesize) { 1006 lsp = malloc(max(sizeof *lsp, fullnamesize)); 1007 if (!lsp) 1008 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1009 *lspp = lsp; 1010 } 1011 cp = mempcpy(lsp, tzdirslash, tzdirslashlen); 1012 cp = mempcpy(cp, name, namelen); 1013 *cp = '\0'; 1014 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 1015 name = lsp->fullname; 1016 #else 1017 name = (char *) lsp; 1018 #endif 1019 } 1020 1021 /* For a platform that lacks O_REGULAR and a file that might 1022 be outside TZDIR, check that it is a regular file, 1023 as merely opening a device could have unwanted side effects. 1024 Though racy, there is no portable way to fix the race. */ 1025 if (!O_REGULAR && might_escape) { 1026 /* (oflags & O_RESOLVE_BENEATH) must be zero here. */ 1027 if ((OPENAT_TZDIR ? fstatat(dd, relname, &st, 0) : stat(name, &st)) 1028 < 0) 1029 return errno; 1030 if (!S_ISREG(st.st_mode)) 1031 return EFTYPE; 1032 } 1033 fid = OPENAT_TZDIR ? openat(dd, relname, oflags) : open(name, oflags); 1034 err = errno; 1035 if (0 <= dd) 1036 close(dd); 1037 if (fid < 0) 1038 return err; 1039 1040 /* If detecting changes to the the primary TZif file's state and 1041 the file's status is unchanged, save time by returning now. 1042 Otherwise read the file's contents. Close the file either way. */ 1043 if (0 <= tz_change_interval && (tzloadflags & TZLOAD_FROMENV) 1044 && !tzfile_changed(fid, &st)) 1045 err = -1; 1046 else { 1047 if (ALL_STATE && !lsp) { 1048 lsp = malloc(sizeof *lsp); 1049 if (!lsp) 1050 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1051 *lspp = lsp; 1052 } 1053 up = &lsp->u.u; 1054 nread = read(fid, up->buf, sizeof up->buf); 1055 err = tzheadsize <= nread ? 0 : nread < 0 ? errno : EFTYPE; 1056 } 1057 close(fid); 1058 if (err) 1059 return err < 0 ? 0 : err; 1060 1061 for (stored = 4; stored <= 8; stored *= 2) { 1062 char version = up->tzhead.tzh_version[0]; 1063 bool skip_datablock = stored == 4 && version; 1064 int_fast32_t datablock_size; 1065 int_fast32_2s 1066 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt), 1067 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt), 1068 leapcnt = detzcode(up->tzhead.tzh_leapcnt), 1069 timecnt = detzcode(up->tzhead.tzh_timecnt), 1070 typecnt = detzcode(up->tzhead.tzh_typecnt), 1071 charcnt = detzcode(up->tzhead.tzh_charcnt); 1072 char const *p = up->buf + tzheadsize; 1073 /* Although tzfile(5) currently requires typecnt to be nonzero, 1074 support future formats that may allow zero typecnt 1075 in files that have a TZ string and no transitions. */ 1076 if (! (0 <= leapcnt 1077 && leapcnt <= (TZ_RUNTIME_LEAPS ? TZ_MAX_LEAPS : 0) 1078 && 0 <= typecnt && typecnt <= TZ_MAX_TYPES 1079 && 0 <= timecnt && timecnt <= TZ_MAX_TIMES 1080 && 0 <= charcnt && charcnt <= TZ_MAX_CHARS 1081 && 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES 1082 && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES)) 1083 return EFTYPE; 1084 datablock_size 1085 = (timecnt * stored /* ats */ 1086 + timecnt /* types */ 1087 + typecnt * 6 /* ttinfos */ 1088 + charcnt /* chars */ 1089 + leapcnt * (stored + 4) /* lsinfos */ 1090 + ttisstdcnt /* ttisstds */ 1091 + ttisutcnt); /* ttisuts */ 1092 if (nread < tzheadsize + datablock_size) 1093 return EFTYPE; 1094 if (skip_datablock) 1095 p += datablock_size; 1096 else if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 1097 && (ttisutcnt == typecnt || ttisutcnt == 0))) 1098 return EFTYPE; 1099 else { 1100 int_fast64_t prevtr = -1; 1101 int_fast32_2s prevcorr; 1102 set_leapcount(sp, leapcnt); 1103 sp->timecnt = timecnt; 1104 sp->typecnt = typecnt; 1105 sp->charcnt = charcnt; 1106 1107 /* Read transitions, discarding those out of time_t range. 1108 But pretend the last transition before TIME_T_MIN 1109 occurred at TIME_T_MIN. */ 1110 timecnt = 0; 1111 for (i = 0; i < sp->timecnt; ++i) { 1112 int_fast64_t at 1113 = stored == 4 ? detzcode(p) : detzcode64(p); 1114 sp->types[i] = at <= TIME_T_MAX; 1115 if (sp->types[i]) { 1116 time_t attime 1117 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 1118 ? TIME_T_MIN : at); 1119 if (timecnt && attime <= sp->ats[timecnt - 1]) { 1120 if (attime < sp->ats[timecnt - 1]) 1121 return EFTYPE; 1122 sp->types[i - 1] = 0; 1123 timecnt--; 1124 } 1125 sp->ats[timecnt++] = attime; 1126 } 1127 p += stored; 1128 } 1129 1130 timecnt = 0; 1131 for (i = 0; i < sp->timecnt; ++i) { 1132 unsigned char typ = *p++; 1133 if (sp->typecnt <= typ) 1134 return EFTYPE; 1135 if (sp->types[i]) 1136 sp->types[timecnt++] = typ; 1137 } 1138 sp->timecnt = timecnt; 1139 for (i = 0; i < sp->typecnt; ++i) { 1140 register struct ttinfo * ttisp; 1141 unsigned char isdst, desigidx; 1142 int_fast32_2s utoff = detzcode(p); 1143 1144 /* Reject a UT offset equal to -2**31, as it might 1145 cause trouble both in this file and in callers. 1146 Also, it violates RFC 9636 section 3.2. */ 1147 if (utoff < -TWO_31_MINUS_1) 1148 return EFTYPE; 1149 1150 ttisp = &sp->ttis[i]; 1151 ttisp->tt_utoff = utoff; 1152 p += 4; 1153 isdst = *p++; 1154 if (! (isdst < 2)) 1155 return EFTYPE; 1156 ttisp->tt_isdst = isdst; 1157 desigidx = *p++; 1158 if (! (desigidx < sp->charcnt)) 1159 return EFTYPE; 1160 ttisp->tt_desigidx = desigidx; 1161 } 1162 for (i = 0; i < sp->charcnt; ++i) 1163 sp->chars[i] = *p++; 1164 /* Ensure '\0'-terminated, and make it safe to call 1165 ttunspecified later. */ 1166 memset(&sp->chars[i], 0, CHARS_EXTRA); 1167 1168 /* Read leap seconds, discarding those out of time_t range. */ 1169 leapcnt = 0; 1170 for (i = 0; i < leapcount(sp); i++) { 1171 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 1172 int_fast32_2s corr = detzcode(p + stored); 1173 p += stored + 4; 1174 1175 /* Leap seconds cannot occur before the Epoch, 1176 or out of order. */ 1177 if (tr <= prevtr) 1178 return EFTYPE; 1179 1180 /* To avoid other botches in this code, each leap second's 1181 correction must differ from the previous one's by 1 1182 second or less, except that the first correction can be 1183 any value; these requirements are more generous than 1184 RFC 9636, to allow future RFC extensions. */ 1185 if (! (i == 0 1186 || (prevcorr < corr 1187 ? corr == prevcorr + 1 1188 : (corr == prevcorr 1189 || corr == prevcorr - 1)))) 1190 return EFTYPE; 1191 prevtr = tr; 1192 prevcorr = corr; 1193 1194 if (tr <= TIME_T_MAX) { 1195 struct lsinfo ls; 1196 ls.ls_trans = tr; 1197 ls.ls_corr = corr; 1198 set_lsinfo(sp, leapcnt, ls); 1199 leapcnt++; 1200 } 1201 } 1202 set_leapcount(sp, leapcnt); 1203 1204 for (i = 0; i < sp->typecnt; ++i) { 1205 register struct ttinfo * ttisp; 1206 1207 ttisp = &sp->ttis[i]; 1208 if (ttisstdcnt == 0) 1209 ttisp->tt_ttisstd = false; 1210 else { 1211 if (*p != true && *p != false) 1212 return EFTYPE; 1213 ttisp->tt_ttisstd = *p++; 1214 } 1215 } 1216 for (i = 0; i < sp->typecnt; ++i) { 1217 register struct ttinfo * ttisp; 1218 1219 ttisp = &sp->ttis[i]; 1220 if (ttisutcnt == 0) 1221 ttisp->tt_ttisut = false; 1222 else { 1223 if (*p != true && *p != false) 1224 return EFTYPE; 1225 ttisp->tt_ttisut = *p++; 1226 } 1227 } 1228 } 1229 1230 nread -= p - up->buf; 1231 memmove(up->buf, p, nread); 1232 1233 /* If this is an old file, we're done. */ 1234 if (!version) 1235 break; 1236 } 1237 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 && 1238 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 1239 sp->typecnt + 2 <= TZ_MAX_TYPES) { 1240 struct state *ts = &lsp->u.st; 1241 1242 up->buf[nread - 1] = '\0'; 1243 if (tzparse(&up->buf[1], ts, sp)) { 1244 1245 /* Attempt to reuse existing abbreviations. 1246 Without this, America/Anchorage would 1247 consume 50 bytes for abbreviations, as 1248 sp->charcnt equals 40 (for LMT AST AWT APT AHST 1249 AHDT YST AKDT AKST) and ts->charcnt equals 10 1250 (for AKST AKDT). Reusing means sp->charcnt can 1251 stay 40 in this example. */ 1252 int gotabbr = 0; 1253 int charcnt = sp->charcnt; 1254 for (i = 0; i < ts->typecnt; i++) { 1255 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 1256 int j; 1257 for (j = 0; j < charcnt; j++) 1258 if (strcmp(sp->chars + j, tsabbr) == 0) { 1259 ts->ttis[i].tt_desigidx = j; 1260 gotabbr++; 1261 break; 1262 } 1263 if (! (j < charcnt)) { 1264 int tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j); 1265 if (j + tsabbrlen < TZ_MAX_CHARS) { 1266 char *cp = sp->chars + j; 1267 cp = mempcpy(cp, tsabbr, tsabbrlen); 1268 *cp = '\0'; 1269 charcnt = j + tsabbrlen + 1; 1270 ts->ttis[i].tt_desigidx = j; 1271 gotabbr++; 1272 } 1273 } 1274 } 1275 if (gotabbr == ts->typecnt) { 1276 sp->charcnt = charcnt; 1277 1278 /* Ignore any trailing, no-op transitions generated 1279 by zic as they don't help here and can run afoul 1280 of bugs in zic 2016j or earlier. */ 1281 while (1 < sp->timecnt 1282 && (sp->types[sp->timecnt - 1] 1283 == sp->types[sp->timecnt - 2])) 1284 sp->timecnt--; 1285 1286 sp->goahead = ts->goahead; 1287 1288 for (i = 0; i < ts->timecnt; i++) { 1289 time_t t = ts->ats[i]; 1290 if (increment_overflow_time(&t, leapcorr(sp, t)) 1291 || (0 < sp->timecnt 1292 && t <= sp->ats[sp->timecnt - 1])) 1293 continue; 1294 if (TZ_MAX_TIMES <= sp->timecnt) { 1295 sp->goahead = false; 1296 break; 1297 } 1298 sp->ats[sp->timecnt] = t; 1299 sp->types[sp->timecnt] = (sp->typecnt 1300 + ts->types[i]); 1301 sp->timecnt++; 1302 } 1303 for (i = 0; i < ts->typecnt; i++) 1304 sp->ttis[sp->typecnt++] = ts->ttis[i]; 1305 } 1306 } 1307 } 1308 if (sp->typecnt == 0) 1309 return EFTYPE; 1310 1311 return 0; 1312 } 1313 1314 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 1315 Return 0 on success, an errno value on failure. */ 1316 static int 1317 tzload(char const *name, struct state *sp, char tzloadflags) 1318 { 1319 int r; 1320 union local_storage *lsp0; 1321 union local_storage *lsp; 1322 #if ALL_STATE 1323 lsp = NULL; 1324 #else 1325 union local_storage ls; 1326 lsp = &ls; 1327 #endif 1328 lsp0 = lsp; 1329 r = tzloadbody(name, sp, tzloadflags, &lsp); 1330 if (lsp != lsp0) 1331 free(lsp); 1332 return r; 1333 } 1334 1335 static const int mon_lengths[2][MONSPERYEAR] = { 1336 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 1337 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 1338 }; 1339 1340 static const int year_lengths[2] = { 1341 DAYSPERNYEAR, DAYSPERLYEAR 1342 }; 1343 1344 /* Is C an ASCII digit? */ 1345 static bool 1346 is_digit(char c) 1347 { 1348 return '0' <= c && c <= '9'; 1349 } 1350 1351 /* 1352 ** Given a pointer into a timezone string, scan until a character that is not 1353 ** a valid character in a time zone abbreviation is found. 1354 ** Return a pointer to that character. 1355 */ 1356 1357 ATTRIBUTE_PURE_114833 static const char * 1358 getzname(register const char *strp) 1359 { 1360 register char c; 1361 1362 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 1363 c != '+') 1364 ++strp; 1365 return strp; 1366 } 1367 1368 /* 1369 ** Given a pointer into an extended timezone string, scan until the ending 1370 ** delimiter of the time zone abbreviation is located. 1371 ** Return a pointer to the delimiter. 1372 ** 1373 ** As with getzname above, the legal character set is actually quite 1374 ** restricted, with other characters producing undefined results. 1375 ** We don't do any checking here; checking is done later in common-case code. 1376 */ 1377 1378 ATTRIBUTE_PURE_114833 static const char * 1379 getqzname(register const char *strp, const int delim) 1380 { 1381 register int c; 1382 1383 while ((c = *strp) != '\0' && c != delim) 1384 ++strp; 1385 return strp; 1386 } 1387 1388 /* 1389 ** Given a pointer into a timezone string, extract a number from that string. 1390 ** Check that the number is within a specified range; if it is not, return 1391 ** NULL. 1392 ** Otherwise, return a pointer to the first character not part of the number. 1393 */ 1394 1395 static const char * 1396 getnum(register const char *strp, int *const nump, const int min, const int max) 1397 { 1398 register char c; 1399 register int num; 1400 1401 if (strp == NULL || !is_digit(c = *strp)) 1402 return NULL; 1403 num = 0; 1404 do { 1405 num = num * 10 + (c - '0'); 1406 if (num > max) 1407 return NULL; /* illegal value */ 1408 c = *++strp; 1409 } while (is_digit(c)); 1410 if (num < min) 1411 return NULL; /* illegal value */ 1412 *nump = num; 1413 return strp; 1414 } 1415 1416 /* 1417 ** Given a pointer into a timezone string, extract a number of seconds, 1418 ** in hh[:mm[:ss]] form, from the string. 1419 ** If any error occurs, return NULL. 1420 ** Otherwise, return a pointer to the first character not part of the number 1421 ** of seconds. 1422 */ 1423 1424 static const char * 1425 getsecs(register const char *strp, int_fast32_t *const secsp) 1426 { 1427 int num; 1428 int_fast32_t secsperhour = SECSPERHOUR; 1429 1430 /* 1431 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 1432 ** "M10.4.6/26", which does not conform to POSIX, 1433 ** but which specifies the equivalent of 1434 ** "02:00 on the first Sunday on or after 23 Oct". 1435 */ 1436 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 1437 if (strp == NULL) 1438 return NULL; 1439 *secsp = num * secsperhour; 1440 if (*strp == ':') { 1441 ++strp; 1442 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 1443 if (strp == NULL) 1444 return NULL; 1445 *secsp += num * SECSPERMIN; 1446 if (*strp == ':') { 1447 ++strp; 1448 /* 'SECSPERMIN' allows for leap seconds. */ 1449 strp = getnum(strp, &num, 0, SECSPERMIN); 1450 if (strp == NULL) 1451 return NULL; 1452 *secsp += num; 1453 } 1454 } 1455 return strp; 1456 } 1457 1458 /* 1459 ** Given a pointer into a timezone string, extract an offset, in 1460 ** [+-]hh[:mm[:ss]] form, from the string. 1461 ** If any error occurs, return NULL. 1462 ** Otherwise, return a pointer to the first character not part of the time. 1463 */ 1464 1465 static const char * 1466 getoffset(register const char *strp, int_fast32_t *const offsetp) 1467 { 1468 register bool neg = false; 1469 1470 if (*strp == '-') { 1471 neg = true; 1472 ++strp; 1473 } else if (*strp == '+') 1474 ++strp; 1475 strp = getsecs(strp, offsetp); 1476 if (strp == NULL) 1477 return NULL; /* illegal time */ 1478 if (neg) 1479 *offsetp = -*offsetp; 1480 return strp; 1481 } 1482 1483 /* 1484 ** Given a pointer into a timezone string, extract a rule in the form 1485 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 1486 ** for the format of "date" and "time". 1487 ** If a valid rule is not found, return NULL. 1488 ** Otherwise, return a pointer to the first character not part of the rule. 1489 */ 1490 1491 static const char * 1492 getrule(const char *strp, register struct rule *const rulep) 1493 { 1494 if (*strp == 'J') { 1495 /* 1496 ** Julian day. 1497 */ 1498 rulep->r_type = JULIAN_DAY; 1499 ++strp; 1500 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1501 } else if (*strp == 'M') { 1502 /* 1503 ** Month, week, day. 1504 */ 1505 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1506 ++strp; 1507 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1508 if (strp == NULL) 1509 return NULL; 1510 if (*strp++ != '.') 1511 return NULL; 1512 strp = getnum(strp, &rulep->r_week, 1, 5); 1513 if (strp == NULL) 1514 return NULL; 1515 if (*strp++ != '.') 1516 return NULL; 1517 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1518 } else if (is_digit(*strp)) { 1519 /* 1520 ** Day of year. 1521 */ 1522 rulep->r_type = DAY_OF_YEAR; 1523 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1524 } else return NULL; /* invalid format */ 1525 if (strp == NULL) 1526 return NULL; 1527 if (*strp == '/') { 1528 /* 1529 ** Time specified. 1530 */ 1531 ++strp; 1532 strp = getoffset(strp, &rulep->r_time); 1533 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1534 return strp; 1535 } 1536 1537 /* 1538 ** Given a year, a rule, and the offset from UT at the time that rule takes 1539 ** effect, calculate the year-relative time that rule takes effect. 1540 */ 1541 1542 static int_fast32_t 1543 transtime(const int year, register const struct rule *const rulep, 1544 const int_fast32_t offset) 1545 { 1546 register bool leapyear; 1547 register int_fast32_t value; 1548 register int i; 1549 int d, m1, yy0, yy1, yy2, dow; 1550 1551 leapyear = isleap(year); 1552 switch (rulep->r_type) { 1553 1554 case JULIAN_DAY: 1555 /* 1556 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1557 ** years. 1558 ** In non-leap years, or if the day number is 59 or less, just 1559 ** add SECSPERDAY times the day number-1 to the time of 1560 ** January 1, midnight, to get the day. 1561 */ 1562 value = (rulep->r_day - 1) * SECSPERDAY; 1563 if (leapyear && rulep->r_day >= 60) 1564 value += SECSPERDAY; 1565 break; 1566 1567 case DAY_OF_YEAR: 1568 /* 1569 ** n - day of year. 1570 ** Just add SECSPERDAY times the day number to the time of 1571 ** January 1, midnight, to get the day. 1572 */ 1573 value = rulep->r_day * SECSPERDAY; 1574 break; 1575 1576 case MONTH_NTH_DAY_OF_WEEK: 1577 /* 1578 ** Mm.n.d - nth "dth day" of month m. 1579 */ 1580 1581 /* 1582 ** Use Zeller's Congruence to get day-of-week of first day of 1583 ** month. 1584 */ 1585 m1 = (rulep->r_mon + 9) % 12 + 1; 1586 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1587 yy1 = yy0 / 100; 1588 yy2 = yy0 % 100; 1589 dow = ((26 * m1 - 2) / 10 + 1590 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1591 if (dow < 0) 1592 dow += DAYSPERWEEK; 1593 1594 /* 1595 ** "dow" is the day-of-week of the first day of the month. Get 1596 ** the day-of-month (zero-origin) of the first "dow" day of the 1597 ** month. 1598 */ 1599 d = rulep->r_day - dow; 1600 if (d < 0) 1601 d += DAYSPERWEEK; 1602 for (i = 1; i < rulep->r_week; ++i) { 1603 if (d + DAYSPERWEEK >= 1604 mon_lengths[leapyear][rulep->r_mon - 1]) 1605 break; 1606 d += DAYSPERWEEK; 1607 } 1608 1609 /* 1610 ** "d" is the day-of-month (zero-origin) of the day we want. 1611 */ 1612 value = d * SECSPERDAY; 1613 for (i = 0; i < rulep->r_mon - 1; ++i) 1614 value += mon_lengths[leapyear][i] * SECSPERDAY; 1615 break; 1616 1617 default: unreachable(); 1618 } 1619 1620 /* 1621 ** "value" is the year-relative time of 00:00:00 UT on the day in 1622 ** question. To get the year-relative time of the specified local 1623 ** time on that day, add the transition time and the current offset 1624 ** from UT. 1625 */ 1626 return value + rulep->r_time + offset; 1627 } 1628 1629 /* 1630 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1631 ** appropriate. 1632 */ 1633 1634 static bool 1635 tzparse(const char *name, struct state *sp, struct state const *basep) 1636 { 1637 const char * stdname; 1638 const char * dstname; 1639 int_fast32_t stdoffset; 1640 int_fast32_t dstoffset; 1641 register char * cp; 1642 ptrdiff_t stdlen, dstlen, charcnt; 1643 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1644 1645 stdname = name; 1646 if (*name == '<') { 1647 name++; 1648 stdname = name; 1649 name = getqzname(name, '>'); 1650 if (*name != '>') 1651 return false; 1652 stdlen = name - stdname; 1653 name++; 1654 } else { 1655 name = getzname(name); 1656 stdlen = name - stdname; 1657 } 1658 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1659 return false; 1660 name = getoffset(name, &stdoffset); 1661 if (name == NULL) 1662 return false; 1663 charcnt = stdlen + 1; 1664 if (basep) { 1665 if (0 < basep->timecnt) 1666 atlo = basep->ats[basep->timecnt - 1]; 1667 set_leapcount(sp, leapcount(basep)); 1668 if (0 < leapcount(sp)) { 1669 int i; 1670 for (i = 0; i < leapcount(sp); i++) 1671 set_lsinfo(sp, i, lsinfo(basep, i)); 1672 leaplo = lsinfo(sp, leapcount(sp) - 1).ls_trans; 1673 } 1674 } else 1675 set_leapcount(sp, 0); /* So, we're off a little. */ 1676 sp->goback = sp->goahead = false; 1677 if (*name != '\0') { 1678 struct rule start, end; 1679 int year, yearbeg, yearlim, timecnt; 1680 time_t janfirst; 1681 int_fast32_t janoffset = 0; 1682 1683 if (*name == '<') { 1684 dstname = ++name; 1685 name = getqzname(name, '>'); 1686 if (*name != '>') 1687 return false; 1688 dstlen = name - dstname; 1689 name++; 1690 } else { 1691 dstname = name; 1692 name = getzname(name); 1693 dstlen = name - dstname; /* length of DST abbr. */ 1694 } 1695 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1696 return false; 1697 charcnt += dstlen + 1; 1698 if (*name != '\0' && *name != ',' && *name != ';') { 1699 name = getoffset(name, &dstoffset); 1700 if (name == NULL) 1701 return false; 1702 } else dstoffset = stdoffset - SECSPERHOUR; 1703 1704 if (*name == '\0') 1705 name = TZDEFRULESTRING; 1706 if (! (*name == ',' || *name == ';')) 1707 return false; 1708 1709 name = getrule(name + 1, &start); 1710 if (!name) 1711 return false; 1712 if (*name++ != ',') 1713 return false; 1714 name = getrule(name, &end); 1715 if (!name || *name) 1716 return false; 1717 sp->typecnt = 2; /* standard time and DST */ 1718 /* 1719 ** Two transitions per year, from EPOCH_YEAR forward. 1720 */ 1721 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1722 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1723 timecnt = 0; 1724 janfirst = 0; 1725 yearbeg = EPOCH_YEAR; 1726 1727 do { 1728 int_fast32_t yearsecs 1729 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1730 time_t janfirst1 = janfirst; 1731 yearbeg--; 1732 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1733 janoffset = -yearsecs; 1734 break; 1735 } 1736 janfirst = janfirst1; 1737 } while (atlo < janfirst 1738 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1739 1740 while (true) { 1741 int_fast32_t yearsecs 1742 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1743 int yearbeg1 = yearbeg; 1744 time_t janfirst1 = janfirst; 1745 if (increment_overflow_time(&janfirst1, yearsecs) 1746 || increment_overflow(&yearbeg1, 1) 1747 || atlo <= janfirst1) 1748 break; 1749 yearbeg = yearbeg1; 1750 janfirst = janfirst1; 1751 } 1752 1753 yearlim = yearbeg; 1754 if (increment_overflow(&yearlim, years_of_observations)) 1755 yearlim = INT_MAX; 1756 for (year = yearbeg; year < yearlim; year++) { 1757 int_fast32_t 1758 starttime = transtime(year, &start, stdoffset), 1759 endtime = transtime(year, &end, dstoffset), 1760 yearsecs = year_lengths[isleap(year)] * SECSPERDAY; 1761 bool reversed = endtime < starttime; 1762 if (reversed) { 1763 int_fast32_t swap = starttime; 1764 starttime = endtime; 1765 endtime = swap; 1766 } 1767 if (reversed 1768 || (starttime < endtime 1769 && endtime - starttime < yearsecs)) { 1770 if (TZ_MAX_TIMES - 2 < timecnt) 1771 break; 1772 sp->ats[timecnt] = janfirst; 1773 if (! increment_overflow_time(&sp->ats[timecnt], 1774 janoffset + starttime) 1775 && atlo <= sp->ats[timecnt]) 1776 sp->types[timecnt++] = !reversed; 1777 sp->ats[timecnt] = janfirst; 1778 if (! increment_overflow_time(&sp->ats[timecnt], 1779 janoffset + endtime) 1780 && atlo <= sp->ats[timecnt]) { 1781 sp->types[timecnt++] = reversed; 1782 } 1783 } 1784 if (endtime < leaplo) { 1785 yearlim = year; 1786 if (increment_overflow(&yearlim, years_of_observations)) 1787 yearlim = INT_MAX; 1788 } 1789 if (increment_overflow_time(&janfirst, janoffset + yearsecs)) 1790 break; 1791 janoffset = 0; 1792 } 1793 sp->timecnt = timecnt; 1794 if (! timecnt) { 1795 sp->ttis[0] = sp->ttis[1]; 1796 sp->typecnt = 1; /* Perpetual DST. */ 1797 } else if (years_of_observations <= year - yearbeg) 1798 sp->goback = sp->goahead = true; 1799 } else { 1800 dstlen = 0; 1801 sp->typecnt = 1; /* only standard time */ 1802 sp->timecnt = 0; 1803 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1804 } 1805 sp->charcnt = charcnt; 1806 cp = sp->chars; 1807 cp = mempcpy(cp, stdname, stdlen); 1808 *cp++ = '\0'; 1809 if (dstlen != 0) { 1810 cp = mempcpy(cp, dstname, dstlen); 1811 *cp = '\0'; 1812 } 1813 return true; 1814 } 1815 1816 static void 1817 gmtload(struct state *const sp) 1818 { 1819 if (!TZ_RUNTIME_LEAPS || tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0) 1820 tzparse("UTC0", sp, NULL); 1821 } 1822 1823 #if !USE_TIMEX_T || !defined TM_GMTOFF 1824 1825 /* Return true if primary cached time zone data are fresh, 1826 i.e., if this function is known to have recently returned false. 1827 A call is recent if it occurred less than tz_change_interval seconds ago. 1828 NOW should be the current time. */ 1829 static bool 1830 fresh_tzdata(monotime_t now) 1831 { 1832 /* If nonzero, the time of the last false return. */ 1833 static monotime_t last_checked; 1834 1835 if (last_checked && now - last_checked < tz_change_interval) 1836 return true; 1837 last_checked = now; 1838 return false; 1839 } 1840 1841 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1842 Respect TZLOADFLAGS. 1843 Return 0 on success, an errno value on failure. */ 1844 static int 1845 zoneinit(struct state *sp, char const *name, char tzloadflags) 1846 { 1847 if (name && ! name[0]) { 1848 /* 1849 ** User wants it fast rather than right. 1850 */ 1851 set_leapcount(sp, 0); /* so, we're off a little */ 1852 sp->timecnt = 0; 1853 sp->typecnt = 0; 1854 sp->charcnt = 0; 1855 sp->goback = sp->goahead = false; 1856 init_ttinfo(&sp->ttis[0], 0, false, 0); 1857 strcpy(sp->chars, utc); 1858 return 0; 1859 } else { 1860 int err = tzload(name, sp, tzloadflags); 1861 if (err != 0 && name && name[0] != ':' && !(tzloadflags & TZLOAD_TZDIR_SUB) 1862 && tzparse(name, sp, NULL)) 1863 err = 0; 1864 if (err == 0) 1865 err = scrub_abbrs(sp); 1866 return err; 1867 } 1868 } 1869 1870 /* If THREADED, upgrade a read lock to a write lock. 1871 Return 0 on success, a positive errno value otherwise. */ 1872 static int 1873 rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) 1874 { 1875 # if THREAD_RWLOCK 1876 if (threaded) { 1877 dounlock(); 1878 return pthread_rwlock_wrlock(&locallock); 1879 } 1880 # endif 1881 return 0; 1882 } 1883 1884 /* Like tzset(), but in a critical section. 1885 If THREADED && THREAD_RWLOCK the caller has a read lock, 1886 and this function might upgrade it to a write lock. 1887 If WALL, act as if TZ is unset; although always false in this file, 1888 a wrapper .c file's obsolete and ineffective tzsetwall function can use it. 1889 If tz_change_interval is positive the time is NOW; otherwise ignore NOW. */ 1890 static void 1891 tzset_unlocked(bool threaded, bool wall, monotime_t now) 1892 { 1893 char const *name; 1894 struct state *sp; 1895 char tzloadflags; 1896 size_t namelen; 1897 bool writing = false; 1898 1899 for (;;) { 1900 name = wall ? NULL : getenv("TZ"); 1901 sp = lclptr; 1902 tzloadflags = TZLOAD_FROMENV | TZLOAD_TZSTRING; 1903 namelen = sizeof lcl_TZname + 1; /* placeholder for no name */ 1904 1905 if (name) { 1906 namelen = strnlen(name, sizeof lcl_TZname); 1907 1908 /* Abbreviate a string like "/usr/share/zoneinfo/America/Los_Angeles" 1909 to its shorter equivalent "America/Los_Angeles". */ 1910 if (!SUPPRESS_TZDIR && tzdirslashlen < namelen 1911 && memcmp(name, tzdirslash, tzdirslashlen) == 0) { 1912 char const *p = name + tzdirslashlen; 1913 while (*p == '/') 1914 p++; 1915 if (*p && *p != ':') { 1916 name = p; 1917 namelen = strnlen(name, sizeof lcl_TZname); 1918 tzloadflags |= TZLOAD_TZDIR_SUB; 1919 } 1920 } 1921 } 1922 1923 if ((tz_change_interval <= 0 ? tz_change_interval < 0 : fresh_tzdata(now)) 1924 && (name 1925 ? 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0 1926 : lcl_is_set < 0)) 1927 return; 1928 1929 if (!THREAD_RWLOCK || writing) 1930 break; 1931 if (rd2wrlock(threaded) != 0) 1932 return; 1933 writing = true; 1934 } 1935 1936 # if ALL_STATE 1937 if (! sp) 1938 lclptr = sp = malloc(sizeof *lclptr); 1939 # endif 1940 if (sp) { 1941 int err = zoneinit(sp, name, tzloadflags); 1942 if (err != 0) { 1943 zoneinit(sp, "", 0); 1944 /* Abbreviate with "-00" if there was an error. 1945 Do not treat a missing TZDEFAULT file as an error. */ 1946 if (name || err != ENOENT) 1947 strcpy(sp->chars, UNSPEC); 1948 } 1949 if (namelen < sizeof lcl_TZname) { 1950 char *cp = lcl_TZname; 1951 cp = mempcpy(cp, name, namelen); 1952 *cp = '\0'; 1953 } 1954 } 1955 settzname(); 1956 lcl_is_set = (sizeof lcl_TZname > namelen) - (sizeof lcl_TZname < namelen); 1957 } 1958 1959 #endif 1960 1961 #if !defined TM_GMTOFF || !USE_TIMEX_T 1962 1963 /* If tz_change_interval is positive, 1964 return the current time as a monotonically nondecreasing value. 1965 Otherwise the return value does not matter. */ 1966 static monotime_t 1967 get_monotonic_time(void) 1968 { 1969 struct timespec now; 1970 now.tv_sec = 0; 1971 if (0 < tz_change_interval) 1972 clock_gettime(CLOCK_MONOTONIC_COARSE, &now); 1973 return now.tv_sec; 1974 } 1975 #endif 1976 1977 #if !USE_TIMEX_T 1978 1979 void 1980 tzset(void) 1981 { 1982 monotime_t now = get_monotonic_time(); 1983 int err = lock(); 1984 if (0 < err) { 1985 errno = err; 1986 return; 1987 } 1988 tzset_unlocked(!err, false, now); 1989 unlock(!err); 1990 } 1991 #endif 1992 1993 #ifdef __FreeBSD__ 1994 void 1995 freebsd13_tzsetwall(void) 1996 { 1997 monotime_t now = get_monotonic_time(); 1998 int err = lock(); 1999 if (0 < err) { 2000 errno = err; 2001 return; 2002 } 2003 tzset_unlocked(!err, true, now); 2004 unlock(!err); 2005 } 2006 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 2007 __warn_references(tzsetwall, 2008 "warning: tzsetwall() is deprecated, use tzset() instead."); 2009 #endif /* __FreeBSD__ */ 2010 static void 2011 gmtcheck1(void) 2012 { 2013 #if ALL_STATE 2014 gmtptr = malloc(sizeof *gmtptr); 2015 #endif 2016 if (gmtptr) 2017 gmtload(gmtptr); 2018 } 2019 2020 static void 2021 gmtcheck(void) 2022 { 2023 static once_t gmt_once = ONCE_INIT; 2024 once(&gmt_once, gmtcheck1); 2025 } 2026 2027 #if NETBSD_INSPIRED && !USE_TIMEX_T 2028 2029 timezone_t 2030 tzalloc(char const *name) 2031 { 2032 timezone_t sp = malloc(sizeof *sp); 2033 if (sp) { 2034 int err = zoneinit(sp, name, TZLOAD_TZSTRING); 2035 if (err != 0) { 2036 free(sp); 2037 errno = err; 2038 return NULL; 2039 } 2040 } else if (!HAVE_MALLOC_ERRNO) 2041 errno = ENOMEM; 2042 return sp; 2043 } 2044 2045 #ifndef FREE_PRESERVES_ERRNO 2046 # if ((defined _POSIX_VERSION && 202405 <= _POSIX_VERSION) \ 2047 || (defined __GLIBC__ && 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__)) \ 2048 || defined __OpenBSD__ || defined __sun) 2049 # define FREE_PRESERVES_ERRNO 1 2050 # else 2051 # define FREE_PRESERVES_ERRNO 0 2052 # endif 2053 #endif 2054 2055 void 2056 tzfree(timezone_t sp) 2057 { 2058 int err; 2059 if (!FREE_PRESERVES_ERRNO) 2060 err = errno; 2061 free(sp); 2062 if (!FREE_PRESERVES_ERRNO) 2063 errno = err; 2064 } 2065 2066 /* 2067 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 2068 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 2069 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 2070 ** 2071 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 2072 ** in zones with three or more time zone abbreviations. 2073 ** Callers can instead use localtime_rz + strftime. 2074 */ 2075 2076 #endif 2077 2078 #if !USE_TIMEX_T || !defined TM_GMTOFF 2079 2080 /* 2081 ** The easy way to behave "as if no library function calls" localtime 2082 ** is to not call it, so we drop its guts into "localsub", which can be 2083 ** freely called. (And no, the PANS doesn't require the above behavior, 2084 ** but it *is* desirable.) 2085 ** 2086 ** If successful and SETNAME is nonzero, 2087 ** set the applicable parts of tzname, timezone and altzone; 2088 ** however, it's OK to omit this step for proleptic TZ strings 2089 ** since in that case tzset should have already done this step correctly. 2090 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 2091 ** but it is actually a boolean and its value should be 0 or 1. 2092 */ 2093 2094 /*ARGSUSED*/ 2095 static struct tm * 2096 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 2097 struct tm *const tmp) 2098 { 2099 register const struct ttinfo * ttisp; 2100 register int i; 2101 register struct tm * result; 2102 const time_t t = *timep; 2103 2104 if (sp == NULL) { 2105 /* Don't bother to set tzname etc.; tzset has already done it. */ 2106 return gmtsub(gmtptr, timep, 0, tmp); 2107 } 2108 if ((sp->goback && t < sp->ats[0]) || 2109 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 2110 time_t newt; 2111 register time_t seconds; 2112 register time_t years; 2113 2114 if (t < sp->ats[0]) 2115 seconds = sp->ats[0] - t; 2116 else seconds = t - sp->ats[sp->timecnt - 1]; 2117 --seconds; 2118 2119 /* Beware integer overflow, as SECONDS might 2120 be close to the maximum time_t. */ 2121 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 2122 seconds = years * AVGSECSPERYEAR; 2123 years += YEARSPERREPEAT; 2124 if (t < sp->ats[0]) 2125 newt = t + seconds + SECSPERREPEAT; 2126 else 2127 newt = t - seconds - SECSPERREPEAT; 2128 2129 if (newt < sp->ats[0] || 2130 newt > sp->ats[sp->timecnt - 1]) 2131 return NULL; /* "cannot happen" */ 2132 result = localsub(sp, &newt, setname, tmp); 2133 if (result) { 2134 # if defined ckd_add && defined ckd_sub 2135 if (t < sp->ats[0] 2136 ? ckd_sub(&result->tm_year, 2137 result->tm_year, years) 2138 : ckd_add(&result->tm_year, 2139 result->tm_year, years)) 2140 return NULL; 2141 # else 2142 register int_fast64_t newy; 2143 2144 newy = result->tm_year; 2145 if (t < sp->ats[0]) 2146 newy -= years; 2147 else newy += years; 2148 if (! (INT_MIN <= newy && newy <= INT_MAX)) 2149 return NULL; 2150 result->tm_year = newy; 2151 # endif 2152 } 2153 return result; 2154 } 2155 if (sp->timecnt == 0 || t < sp->ats[0]) { 2156 i = 0; 2157 } else { 2158 register int lo = 1; 2159 register int hi = sp->timecnt; 2160 2161 while (lo < hi) { 2162 register int mid = (lo + hi) >> 1; 2163 2164 if (t < sp->ats[mid]) 2165 hi = mid; 2166 else lo = mid + 1; 2167 } 2168 i = sp->types[lo - 1]; 2169 } 2170 ttisp = &sp->ttis[i]; 2171 /* 2172 ** To get (wrong) behavior that's compatible with System V Release 2.0 2173 ** you'd replace the statement below with 2174 ** t += ttisp->tt_utoff; 2175 ** timesub(&t, 0, sp, tmp); 2176 */ 2177 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 2178 if (result) { 2179 result->tm_isdst = ttisp->tt_isdst; 2180 # ifdef TM_ZONE 2181 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 2182 # endif 2183 if (setname) 2184 update_tzname_etc(sp, ttisp); 2185 } 2186 return result; 2187 } 2188 #endif 2189 2190 #if !USE_TIMEX_T 2191 2192 /* Return TMP, or a thread-specific struct tm * selected by WHICH. */ 2193 static struct tm * 2194 tm_multi(struct tm *tmp, ATTRIBUTE_MAYBE_UNUSED enum tm_multi which) 2195 { 2196 # if THREAD_SAFE && THREAD_TM_MULTI 2197 /* It is OK to check is_threaded() separately here; even if it 2198 returns a different value in other places in the caller, 2199 this function's behavior is still valid. */ 2200 if (is_threaded()) { 2201 /* Try to get a thread-specific struct tm *. 2202 Fall back on TMP if this fails. */ 2203 static pthread_once_t tm_multi_once = PTHREAD_ONCE_INIT; 2204 pthread_once(&tm_multi_once, tm_multi_key_init); 2205 if (!tm_multi_key_err) { 2206 struct tm *p = pthread_getspecific(tm_multi_key); 2207 if (!p) { 2208 p = malloc(N_TM_MULTI * sizeof *p); 2209 if (p && pthread_setspecific(tm_multi_key, p) != 0) { 2210 free(p); 2211 p = NULL; 2212 } 2213 } 2214 if (p) 2215 return &p[which]; 2216 } 2217 } 2218 # endif 2219 return tmp; 2220 } 2221 2222 # if NETBSD_INSPIRED 2223 struct tm * 2224 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 2225 struct tm *restrict tmp) 2226 { 2227 return localsub(sp, timep, 0, tmp); 2228 } 2229 # endif 2230 2231 static struct tm * 2232 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 2233 { 2234 monotime_t now = get_monotonic_time(); 2235 int err = lock(); 2236 if (0 < err) { 2237 errno = err; 2238 return NULL; 2239 } 2240 if (0 <= tz_change_interval || setname || !lcl_is_set) 2241 tzset_unlocked(!err, false, now); 2242 tmp = localsub(lclptr, timep, setname, tmp); 2243 unlock(!err); 2244 return tmp; 2245 } 2246 2247 struct tm * 2248 localtime(const time_t *timep) 2249 { 2250 # if !SUPPORT_C89 2251 static struct tm tm; 2252 # endif 2253 return localtime_tzset(timep, tm_multi(&tm, LOCALTIME_TM_MULTI), true); 2254 } 2255 2256 struct tm * 2257 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 2258 { 2259 return localtime_tzset(timep, tmp, false); 2260 } 2261 #endif 2262 2263 /* 2264 ** gmtsub is to gmtime as localsub is to localtime. 2265 */ 2266 2267 static struct tm * 2268 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 2269 int_fast32_t offset, struct tm *tmp) 2270 { 2271 register struct tm * result; 2272 2273 result = timesub(timep, offset, gmtptr, tmp); 2274 #ifdef TM_ZONE 2275 /* 2276 ** Could get fancy here and deliver something such as 2277 ** "+xx" or "-xx" if offset is non-zero, 2278 ** but this is no time for a treasure hunt. 2279 */ 2280 tmp->TM_ZONE = UNCONST(offset ? wildabbr 2281 : gmtptr ? gmtptr->chars : utc); 2282 #endif /* defined TM_ZONE */ 2283 return result; 2284 } 2285 2286 #if !USE_TIMEX_T 2287 2288 /* 2289 * Re-entrant version of gmtime. 2290 */ 2291 2292 struct tm * 2293 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 2294 { 2295 gmtcheck(); 2296 return gmtsub(gmtptr, timep, 0, tmp); 2297 } 2298 2299 struct tm * 2300 gmtime(const time_t *timep) 2301 { 2302 # if !SUPPORT_C89 2303 static struct tm tm; 2304 # endif 2305 return gmtime_r(timep, tm_multi(&tm, GMTIME_TM_MULTI)); 2306 } 2307 2308 # if STD_INSPIRED 2309 2310 /* This function is obsolescent and may disappear in future releases. 2311 Callers can instead use localtime_rz with a fixed-offset zone. */ 2312 2313 struct tm * 2314 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 2315 { 2316 gmtcheck(); 2317 return gmtsub(gmtptr, timep, offset, tmp); 2318 } 2319 2320 struct tm * 2321 offtime(time_t const *timep, long offset) 2322 { 2323 # if !SUPPORT_C89 2324 static struct tm tm; 2325 # endif 2326 return offtime_r(timep, offset, tm_multi(&tm, OFFTIME_TM_MULTI)); 2327 } 2328 2329 # endif 2330 #endif 2331 2332 /* 2333 ** Return the number of leap years through the end of the given year 2334 ** where, to make the math easy, the answer for year zero is defined as zero. 2335 */ 2336 2337 static time_t 2338 leaps_thru_end_of_nonneg(time_t y) 2339 { 2340 return y / 4 - y / 100 + y / 400; 2341 } 2342 2343 static time_t 2344 leaps_thru_end_of(time_t y) 2345 { 2346 return (y < 0 2347 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 2348 : leaps_thru_end_of_nonneg(y)); 2349 } 2350 2351 static struct tm * 2352 timesub(const time_t *timep, int_fast32_t offset, 2353 const struct state *sp, struct tm *tmp) 2354 { 2355 register time_t tdays; 2356 register const int * ip; 2357 int_fast32_2s corr; 2358 register int i; 2359 int_fast32_t idays, rem, dayoff, dayrem; 2360 time_t y; 2361 2362 /* If less than SECSPERMIN, the number of seconds since the 2363 most recent positive leap second; otherwise, do not add 1 2364 to localtime tm_sec because of leap seconds. */ 2365 time_t secs_since_posleap = SECSPERMIN; 2366 2367 corr = 0; 2368 i = sp ? leapcount(sp) : 0; 2369 while (--i >= 0) { 2370 struct lsinfo ls = lsinfo(sp, i); 2371 if (ls.ls_trans <= *timep) { 2372 corr = ls.ls_corr; 2373 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr) 2374 secs_since_posleap = *timep - ls.ls_trans; 2375 break; 2376 } 2377 } 2378 2379 /* Calculate the year, avoiding integer overflow even if 2380 time_t is unsigned. */ 2381 tdays = *timep / SECSPERDAY; 2382 rem = *timep % SECSPERDAY; 2383 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 2384 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 2385 rem %= SECSPERDAY; 2386 /* y = (EPOCH_YEAR 2387 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 2388 sans overflow. But calculate against 1570 (EPOCH_YEAR - 2389 YEARSPERREPEAT) instead of against 1970 so that things work 2390 for localtime values before 1970 when time_t is unsigned. */ 2391 dayrem = tdays % DAYSPERREPEAT; 2392 dayrem += dayoff % DAYSPERREPEAT; 2393 y = (EPOCH_YEAR - YEARSPERREPEAT 2394 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 2395 - ((dayrem % DAYSPERREPEAT) < 0) 2396 + tdays / DAYSPERREPEAT) 2397 * YEARSPERREPEAT)); 2398 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 2399 idays = tdays % DAYSPERREPEAT; 2400 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 2401 idays %= DAYSPERREPEAT; 2402 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 2403 while (year_lengths[isleap(y)] <= idays) { 2404 int tdelta = idays / DAYSPERLYEAR; 2405 int_fast32_t ydelta = tdelta + !tdelta; 2406 time_t newy = y + ydelta; 2407 register int leapdays; 2408 leapdays = leaps_thru_end_of(newy - 1) - 2409 leaps_thru_end_of(y - 1); 2410 idays -= ydelta * DAYSPERNYEAR; 2411 idays -= leapdays; 2412 y = newy; 2413 } 2414 2415 #ifdef ckd_add 2416 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 2417 errno = EOVERFLOW; 2418 return NULL; 2419 } 2420 #else 2421 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 2422 int signed_y = y; 2423 tmp->tm_year = signed_y - TM_YEAR_BASE; 2424 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2425 && y - TM_YEAR_BASE <= INT_MAX) 2426 tmp->tm_year = y - TM_YEAR_BASE; 2427 else { 2428 errno = EOVERFLOW; 2429 return NULL; 2430 } 2431 #endif 2432 tmp->tm_yday = idays; 2433 /* 2434 ** The "extra" mods below avoid overflow problems. 2435 */ 2436 tmp->tm_wday = (TM_WDAY_BASE 2437 + ((tmp->tm_year % DAYSPERWEEK) 2438 * (DAYSPERNYEAR % DAYSPERWEEK)) 2439 + leaps_thru_end_of(y - 1) 2440 - leaps_thru_end_of(TM_YEAR_BASE - 1) 2441 + idays); 2442 tmp->tm_wday %= DAYSPERWEEK; 2443 if (tmp->tm_wday < 0) 2444 tmp->tm_wday += DAYSPERWEEK; 2445 tmp->tm_hour = rem / SECSPERHOUR; 2446 rem %= SECSPERHOUR; 2447 tmp->tm_min = rem / SECSPERMIN; 2448 tmp->tm_sec = rem % SECSPERMIN; 2449 2450 /* Use "... ??:??:60" at the end of the localtime minute containing 2451 the second just before the positive leap second. */ 2452 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2453 2454 ip = mon_lengths[isleap(y)]; 2455 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2456 idays -= ip[tmp->tm_mon]; 2457 tmp->tm_mday = idays + 1; 2458 tmp->tm_isdst = 0; 2459 #ifdef TM_GMTOFF 2460 tmp->TM_GMTOFF = offset; 2461 #endif /* defined TM_GMTOFF */ 2462 return tmp; 2463 } 2464 2465 /* 2466 ** Adapted from code provided by Robert Elz, who writes: 2467 ** The "best" way to do mktime I think is based on an idea of Bob 2468 ** Kridle's (so its said...) from a long time ago. 2469 ** It does a binary search of the time_t space. Since time_t's are 2470 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2471 ** would still be very reasonable). 2472 */ 2473 2474 #ifndef WRONG 2475 # define WRONG (-1) 2476 #endif /* !defined WRONG */ 2477 2478 /* 2479 ** Normalize logic courtesy Paul Eggert. 2480 */ 2481 2482 static bool 2483 increment_overflow(int *ip, int j) 2484 { 2485 #ifdef ckd_add 2486 return ckd_add(ip, *ip, j); 2487 #else 2488 register int const i = *ip; 2489 2490 /* 2491 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2492 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2493 ** If i < 0 there can only be overflow if i + j < INT_MIN 2494 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2495 */ 2496 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2497 return true; 2498 *ip += j; 2499 return false; 2500 #endif 2501 } 2502 2503 static bool 2504 increment_overflow_64(int *ip, int_fast64_t j) 2505 { 2506 #ifdef ckd_add 2507 return ckd_add(ip, *ip, j); 2508 #else 2509 if (j < 0 ? *ip < INT_MIN - j : INT_MAX - j < *ip) 2510 return true; 2511 *ip += j; 2512 return false; 2513 #endif 2514 } 2515 2516 static bool 2517 increment_overflow_time_iinntt(time_t *tp, iinntt j) 2518 { 2519 #ifdef ckd_add 2520 return ckd_add(tp, *tp, j); 2521 #else 2522 if (j < 0 2523 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2524 : TIME_T_MAX - j < *tp) 2525 return true; 2526 *tp += j; 2527 return false; 2528 #endif 2529 } 2530 2531 static bool 2532 increment_overflow_time_64(time_t *tp, int_fast64_t j) 2533 { 2534 #ifdef ckd_add 2535 return ckd_add(tp, *tp, j); 2536 #else 2537 if (j < 0 2538 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2539 : TIME_T_MAX - j < *tp) 2540 return true; 2541 *tp += j; 2542 return false; 2543 #endif 2544 } 2545 2546 static bool 2547 increment_overflow_time(time_t *tp, int_fast32_2s j) 2548 { 2549 #ifdef ckd_add 2550 return ckd_add(tp, *tp, j); 2551 #else 2552 /* 2553 ** This is like 2554 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2555 ** except that it does the right thing even if *tp + j would overflow. 2556 */ 2557 if (! (j < 0 2558 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2559 : *tp <= TIME_T_MAX - j)) 2560 return true; 2561 *tp += j; 2562 return false; 2563 #endif 2564 } 2565 2566 /* Return A - B, where both are in the range -2**31 + 1 .. 2**31 - 1. 2567 The result cannot overflow. */ 2568 static int_fast64_t 2569 utoff_diff (int_fast32_t a, int_fast32_t b) 2570 { 2571 int_fast64_t aa = a; 2572 return aa - b; 2573 } 2574 2575 static int 2576 tmcomp(register const struct tm *const atmp, 2577 register const struct tm *const btmp) 2578 { 2579 register int result; 2580 2581 if (atmp->tm_year != btmp->tm_year) 2582 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2583 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2584 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2585 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2586 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2587 result = atmp->tm_sec - btmp->tm_sec; 2588 return result; 2589 } 2590 2591 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2592 as other members might not be initialized. */ 2593 static void 2594 mktmcpy(struct tm *dest, struct tm const *src) 2595 { 2596 dest->tm_sec = src->tm_sec; 2597 dest->tm_min = src->tm_min; 2598 dest->tm_hour = src->tm_hour; 2599 dest->tm_mday = src->tm_mday; 2600 dest->tm_mon = src->tm_mon; 2601 dest->tm_year = src->tm_year; 2602 dest->tm_isdst = src->tm_isdst; 2603 #if defined TM_GMTOFF && ! UNINIT_TRAP 2604 dest->TM_GMTOFF = src->TM_GMTOFF; 2605 #endif 2606 } 2607 2608 static time_t 2609 time2sub(struct tm *const tmp, 2610 struct tm *funcp(struct state const *, time_t const *, 2611 int_fast32_t, struct tm *), 2612 struct state const *sp, 2613 const int_fast32_t offset, 2614 bool *okayp, 2615 bool do_norm_secs) 2616 { 2617 register int dir; 2618 register int i, j; 2619 register time_t lo; 2620 register time_t hi; 2621 iinntt y, mday, hour, min, saved_seconds; 2622 time_t newt; 2623 time_t t; 2624 struct tm yourtm, mytm; 2625 2626 *okayp = false; 2627 mktmcpy(&yourtm, tmp); 2628 2629 min = yourtm.tm_min; 2630 if (do_norm_secs) { 2631 min += yourtm.tm_sec / SECSPERMIN; 2632 yourtm.tm_sec %= SECSPERMIN; 2633 if (yourtm.tm_sec < 0) { 2634 yourtm.tm_sec += SECSPERMIN; 2635 min--; 2636 } 2637 } 2638 2639 hour = yourtm.tm_hour; 2640 hour += min / MINSPERHOUR; 2641 yourtm.tm_min = min % MINSPERHOUR; 2642 if (yourtm.tm_min < 0) { 2643 yourtm.tm_min += MINSPERHOUR; 2644 hour--; 2645 } 2646 2647 mday = yourtm.tm_mday; 2648 mday += hour / HOURSPERDAY; 2649 yourtm.tm_hour = hour % HOURSPERDAY; 2650 if (yourtm.tm_hour < 0) { 2651 yourtm.tm_hour += HOURSPERDAY; 2652 mday--; 2653 } 2654 2655 y = yourtm.tm_year; 2656 y += yourtm.tm_mon / MONSPERYEAR; 2657 yourtm.tm_mon %= MONSPERYEAR; 2658 if (yourtm.tm_mon < 0) { 2659 yourtm.tm_mon += MONSPERYEAR; 2660 y--; 2661 } 2662 2663 /* 2664 ** Turn y into an actual year number for now. 2665 ** It is converted back to an offset from TM_YEAR_BASE later. 2666 */ 2667 y += TM_YEAR_BASE; 2668 2669 while (mday <= 0) { 2670 iinntt li = y - (yourtm.tm_mon <= 1); 2671 mday += year_lengths[isleap(li)]; 2672 y--; 2673 } 2674 while (DAYSPERLYEAR < mday) { 2675 iinntt li = y + (1 < yourtm.tm_mon); 2676 mday -= year_lengths[isleap(li)]; 2677 y++; 2678 } 2679 yourtm.tm_mday = mday; 2680 for ( ; ; ) { 2681 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2682 if (yourtm.tm_mday <= i) 2683 break; 2684 yourtm.tm_mday -= i; 2685 if (++yourtm.tm_mon >= MONSPERYEAR) { 2686 yourtm.tm_mon = 0; 2687 y++; 2688 } 2689 } 2690 #ifdef ckd_add 2691 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2692 return WRONG; 2693 #else 2694 y -= TM_YEAR_BASE; 2695 if (! (INT_MIN <= y && y <= INT_MAX)) 2696 return WRONG; 2697 yourtm.tm_year = y; 2698 #endif 2699 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2700 saved_seconds = 0; 2701 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2702 /* 2703 ** We can't set tm_sec to 0, because that might push the 2704 ** time below the minimum representable time. 2705 ** Set tm_sec to 59 instead. 2706 ** This assumes that the minimum representable time is 2707 ** not in the same minute that a leap second was deleted from, 2708 ** which is a safer assumption than using 58 would be. 2709 */ 2710 saved_seconds = yourtm.tm_sec; 2711 saved_seconds -= SECSPERMIN - 1; 2712 yourtm.tm_sec = SECSPERMIN - 1; 2713 } else { 2714 saved_seconds = yourtm.tm_sec; 2715 yourtm.tm_sec = 0; 2716 } 2717 /* 2718 ** Do a binary search (this works whatever time_t's type is). 2719 */ 2720 lo = TIME_T_MIN; 2721 hi = TIME_T_MAX; 2722 for ( ; ; ) { 2723 t = lo / 2 + hi / 2; 2724 if (t < lo) 2725 t = lo; 2726 else if (t > hi) 2727 t = hi; 2728 if (! funcp(sp, &t, offset, &mytm)) { 2729 /* 2730 ** Assume that t is too extreme to be represented in 2731 ** a struct tm; arrange things so that it is less 2732 ** extreme on the next pass. 2733 */ 2734 dir = (t > 0) ? 1 : -1; 2735 } else dir = tmcomp(&mytm, &yourtm); 2736 if (dir != 0) { 2737 if (t == lo) { 2738 if (t == TIME_T_MAX) 2739 return WRONG; 2740 ++t; 2741 ++lo; 2742 } else if (t == hi) { 2743 if (t == TIME_T_MIN) 2744 return WRONG; 2745 --t; 2746 --hi; 2747 } 2748 if (lo > hi) 2749 return WRONG; 2750 if (dir > 0) 2751 hi = t; 2752 else lo = t; 2753 continue; 2754 } 2755 #if defined TM_GMTOFF && ! UNINIT_TRAP 2756 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2757 && (yourtm.TM_GMTOFF < 0 2758 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2759 && (mytm.TM_GMTOFF <= 2760 (min(INT_FAST32_MAX, LONG_MAX) 2761 + yourtm.TM_GMTOFF))) 2762 : (yourtm.TM_GMTOFF <= SECSPERDAY 2763 && ((max(INT_FAST32_MIN, LONG_MIN) 2764 + yourtm.TM_GMTOFF) 2765 <= mytm.TM_GMTOFF)))) { 2766 /* MYTM matches YOURTM except with the wrong UT offset. 2767 YOURTM.TM_GMTOFF is plausible, so try it instead. 2768 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2769 since the guess gets checked. */ 2770 time_t altt = t; 2771 int_fast64_t offdiff; 2772 bool v; 2773 # ifdef ckd_sub 2774 v = ckd_sub(&offdiff, mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2775 # else 2776 /* A ckd_sub approximation that is good enough here. */ 2777 v = !(-TWO_31_MINUS_1 <= yourtm.TM_GMTOFF 2778 && yourtm.TM_GMTOFF <= TWO_31_MINUS_1); 2779 if (!v) 2780 offdiff = utoff_diff(mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2781 # endif 2782 if (!v && !increment_overflow_time_64(&altt, offdiff)) { 2783 struct tm alttm; 2784 if (funcp(sp, &altt, offset, &alttm) 2785 && alttm.tm_isdst == mytm.tm_isdst 2786 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2787 && tmcomp(&alttm, &yourtm) == 0) { 2788 t = altt; 2789 mytm = alttm; 2790 } 2791 } 2792 } 2793 #endif 2794 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2795 break; 2796 /* 2797 ** Right time, wrong type. 2798 ** Hunt for right time, right type. 2799 ** It's okay to guess wrong since the guess 2800 ** gets checked. 2801 */ 2802 if (sp == NULL) 2803 return WRONG; 2804 for (i = sp->typecnt - 1; i >= 0; --i) { 2805 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2806 continue; 2807 for (j = sp->typecnt - 1; j >= 0; --j) { 2808 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2809 continue; 2810 if (ttunspecified(sp, j)) 2811 continue; 2812 newt = t; 2813 if (increment_overflow_time_64 2814 (&newt, 2815 utoff_diff(sp->ttis[j].tt_utoff, 2816 sp->ttis[i].tt_utoff))) 2817 continue; 2818 if (! funcp(sp, &newt, offset, &mytm)) 2819 continue; 2820 if (tmcomp(&mytm, &yourtm) != 0) 2821 continue; 2822 if (mytm.tm_isdst != yourtm.tm_isdst) 2823 continue; 2824 /* 2825 ** We have a match. 2826 */ 2827 t = newt; 2828 goto label; 2829 } 2830 } 2831 return WRONG; 2832 } 2833 label: 2834 if (increment_overflow_time_iinntt(&t, saved_seconds)) 2835 return WRONG; 2836 if (funcp(sp, &t, offset, tmp)) 2837 *okayp = true; 2838 return t; 2839 } 2840 2841 static time_t 2842 time2(struct tm * const tmp, 2843 struct tm *funcp(struct state const *, time_t const *, 2844 int_fast32_t, struct tm *), 2845 struct state const *sp, 2846 const int_fast32_t offset, 2847 bool *okayp) 2848 { 2849 time_t t; 2850 2851 /* 2852 ** First try without normalization of seconds 2853 ** (in case tm_sec contains a value associated with a leap second). 2854 ** If that fails, try with normalization of seconds. 2855 */ 2856 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2857 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2858 } 2859 2860 static time_t 2861 time1(struct tm *const tmp, 2862 struct tm *funcp(struct state const *, time_t const *, 2863 int_fast32_t, struct tm *), 2864 struct state const *sp, 2865 const int_fast32_t offset) 2866 { 2867 register time_t t; 2868 register int samei, otheri; 2869 register int sameind, otherind; 2870 register int i; 2871 register int nseen; 2872 char seen[TZ_MAX_TYPES]; 2873 unsigned char types[TZ_MAX_TYPES]; 2874 bool okay; 2875 2876 if (tmp == NULL) { 2877 errno = EINVAL; 2878 return WRONG; 2879 } 2880 if (tmp->tm_isdst > 1) 2881 tmp->tm_isdst = 1; 2882 t = time2(tmp, funcp, sp, offset, &okay); 2883 if (okay) 2884 return t; 2885 if (tmp->tm_isdst < 0) 2886 #ifdef PCTS 2887 /* 2888 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2889 */ 2890 tmp->tm_isdst = 0; /* reset to std and try again */ 2891 #else 2892 return t; 2893 #endif /* !defined PCTS */ 2894 /* 2895 ** We're supposed to assume that somebody took a time of one type 2896 ** and did some math on it that yielded a "struct tm" that's bad. 2897 ** We try to divine the type they started from and adjust to the 2898 ** type they need. 2899 */ 2900 if (sp == NULL) 2901 return WRONG; 2902 for (i = 0; i < sp->typecnt; ++i) 2903 seen[i] = false; 2904 nseen = 0; 2905 for (i = sp->timecnt - 1; i >= 0; --i) 2906 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2907 seen[sp->types[i]] = true; 2908 types[nseen++] = sp->types[i]; 2909 } 2910 for (sameind = 0; sameind < nseen; ++sameind) { 2911 samei = types[sameind]; 2912 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2913 continue; 2914 for (otherind = 0; otherind < nseen; ++otherind) { 2915 otheri = types[otherind]; 2916 if (sp->ttis[otheri].tt_isdst != tmp->tm_isdst) { 2917 int sec = tmp->tm_sec; 2918 if (!increment_overflow_64 2919 (&tmp->tm_sec, 2920 utoff_diff(sp->ttis[otheri].tt_utoff, 2921 sp->ttis[samei].tt_utoff))) { 2922 tmp->tm_isdst = !tmp->tm_isdst; 2923 t = time2(tmp, funcp, sp, offset, &okay); 2924 if (okay) 2925 return t; 2926 tmp->tm_isdst = !tmp->tm_isdst; 2927 } 2928 tmp->tm_sec = sec; 2929 } 2930 } 2931 } 2932 return WRONG; 2933 } 2934 2935 #if !defined TM_GMTOFF || !USE_TIMEX_T 2936 2937 static time_t 2938 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2939 { 2940 if (sp) 2941 return time1(tmp, localsub, sp, setname); 2942 else { 2943 gmtcheck(); 2944 return time1(tmp, gmtsub, gmtptr, 0); 2945 } 2946 } 2947 2948 # if USE_TIMEX_T 2949 static 2950 # endif 2951 time_t 2952 mktime(struct tm *tmp) 2953 { 2954 monotime_t now = get_monotonic_time(); 2955 time_t t; 2956 int err = lock(); 2957 if (0 < err) { 2958 errno = err; 2959 return -1; 2960 } 2961 tzset_unlocked(!err, false, now); 2962 t = mktime_tzname(lclptr, tmp, true); 2963 unlock(!err); 2964 return t; 2965 } 2966 2967 #endif 2968 2969 #if NETBSD_INSPIRED && !USE_TIMEX_T 2970 time_t 2971 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2972 { 2973 return mktime_tzname(sp, tmp, false); 2974 } 2975 #endif 2976 2977 #if STD_INSPIRED && !USE_TIMEX_T 2978 /* This function is obsolescent and may disappear in future releases. 2979 Callers can instead use mktime. */ 2980 time_t 2981 timelocal(struct tm *tmp) 2982 { 2983 if (tmp != NULL) 2984 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2985 return mktime(tmp); 2986 } 2987 #endif 2988 2989 #if defined TM_GMTOFF || !USE_TIMEX_T 2990 2991 # ifndef EXTERN_TIMEOFF 2992 # ifndef timeoff 2993 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2994 # endif 2995 # define EXTERN_TIMEOFF static 2996 # endif 2997 2998 /* This function is obsolescent and may disappear in future releases. 2999 Callers can instead use mktime_z with a fixed-offset zone. */ 3000 EXTERN_TIMEOFF time_t 3001 timeoff(struct tm *tmp, long offset) 3002 { 3003 if (tmp) 3004 tmp->tm_isdst = 0; 3005 gmtcheck(); 3006 return time1(tmp, gmtsub, gmtptr, offset); 3007 } 3008 #endif 3009 3010 #if !USE_TIMEX_T 3011 time_t 3012 timegm(struct tm *tmp) 3013 { 3014 time_t t; 3015 struct tm tmcpy; 3016 mktmcpy(&tmcpy, tmp); 3017 tmcpy.tm_wday = -1; 3018 t = timeoff(&tmcpy, 0); 3019 if (0 <= tmcpy.tm_wday) 3020 *tmp = tmcpy; 3021 return t; 3022 } 3023 #endif 3024 3025 static int_fast32_2s 3026 leapcorr(struct state const *sp, time_t t) 3027 { 3028 register int i; 3029 3030 i = leapcount(sp); 3031 while (--i >= 0) { 3032 struct lsinfo ls = lsinfo(sp, i); 3033 if (ls.ls_trans <= t) 3034 return ls.ls_corr; 3035 } 3036 return 0; 3037 } 3038 3039 /* 3040 ** XXX--is the below the right way to conditionalize?? 3041 */ 3042 3043 #if !USE_TIMEX_T 3044 # if STD_INSPIRED 3045 3046 static bool 3047 decrement_overflow_time(time_t *tp, int_fast32_2s j) 3048 { 3049 #ifdef ckd_sub 3050 return ckd_sub(tp, *tp, j); 3051 #else 3052 if (! (j < 0 3053 ? *tp <= TIME_T_MAX + j 3054 : (TYPE_SIGNED(time_t) ? TIME_T_MIN + j <= *tp : j <= *tp))) 3055 return true; 3056 *tp -= j; 3057 return false; 3058 #endif 3059 } 3060 3061 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 3062 NETBSD_INSPIRED is defined, and are private otherwise. */ 3063 # if NETBSD_INSPIRED 3064 # define NETBSD_INSPIRED_EXTERN 3065 # else 3066 # define NETBSD_INSPIRED_EXTERN static 3067 # endif 3068 3069 /* 3070 ** IEEE Std 1003.1 (POSIX) says that 536457599 3071 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 3072 ** is not the case if we are accounting for leap seconds. 3073 ** So, we provide the following conversion routines for use 3074 ** when exchanging timestamps with POSIX conforming systems. 3075 */ 3076 3077 NETBSD_INSPIRED_EXTERN time_t 3078 time2posix_z(struct state *sp, time_t t) 3079 { 3080 if (decrement_overflow_time(&t, leapcorr(sp, t))) { 3081 /* Overflow near maximum time_t value with negative correction. 3082 This can happen with unrealistic-but-valid TZif files. */ 3083 errno = EOVERFLOW; 3084 return -1; 3085 } 3086 return t; 3087 } 3088 3089 time_t 3090 time2posix(time_t t) 3091 { 3092 monotime_t now = get_monotonic_time(); 3093 int err = lock(); 3094 if (0 < err) { 3095 errno = err; 3096 return -1; 3097 } 3098 if (0 <= tz_change_interval || !lcl_is_set) 3099 tzset_unlocked(!err, false, now); 3100 if (lclptr) 3101 t = time2posix_z(lclptr, t); 3102 unlock(!err); 3103 return t; 3104 } 3105 3106 NETBSD_INSPIRED_EXTERN time_t 3107 posix2time_z(struct state *sp, time_t t) 3108 { 3109 int i; 3110 for (i = leapcount(sp); 0 <= --i; ) { 3111 struct lsinfo ls = lsinfo(sp, i); 3112 time_t t_corr = t; 3113 3114 if (increment_overflow_time(&t_corr, ls.ls_corr)) { 3115 if (0 <= ls.ls_corr) { 3116 /* Overflow near maximum time_t value with positive correction. 3117 This can happen with ordinary TZif files with leap seconds. */ 3118 errno = EOVERFLOW; 3119 return -1; 3120 } else { 3121 /* A negative correction overflowed, so keep going. 3122 This can happen with unrealistic-but-valid TZif files. */ 3123 } 3124 } else if (ls.ls_trans <= t_corr) 3125 return (t_corr 3126 - (ls.ls_trans == t_corr 3127 && (i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < ls.ls_corr)); 3128 } 3129 return t; 3130 } 3131 3132 time_t 3133 posix2time(time_t t) 3134 { 3135 monotime_t now = get_monotonic_time(); 3136 int err = lock(); 3137 if (0 < err) { 3138 errno = err; 3139 return -1; 3140 } 3141 if (0 <= tz_change_interval || !lcl_is_set) 3142 tzset_unlocked(!err, false, now); 3143 if (lclptr) 3144 t = posix2time_z(lclptr, t); 3145 unlock(!err); 3146 return t; 3147 } 3148 3149 # endif /* STD_INSPIRED */ 3150 3151 # if TZ_TIME_T 3152 3153 # if !USG_COMPAT 3154 # define timezone 0 3155 # endif 3156 3157 /* Convert from the underlying system's time_t to the ersatz time_tz, 3158 which is called 'time_t' in this file. Typically, this merely 3159 converts the time's integer width. On some platforms, the system 3160 time is local time not UT, or uses some epoch other than the POSIX 3161 epoch. 3162 3163 Although this code appears to define a function named 'time' that 3164 returns time_t, the macros in private.h cause this code to actually 3165 define a function named 'tz_time' that returns tz_time_t. The call 3166 to sys_time invokes the underlying system's 'time' function. */ 3167 3168 time_t 3169 time(time_t *p) 3170 { 3171 time_t r = sys_time(NULL); 3172 if (r != (time_t) -1) { 3173 iinntt offset = EPOCH_LOCAL ? timezone : 0; 3174 if (offset < IINNTT_MIN + EPOCH_OFFSET 3175 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 3176 errno = EOVERFLOW; 3177 r = -1; 3178 } 3179 } 3180 if (p) 3181 *p = r; 3182 return r; 3183 } 3184 3185 # endif 3186 #endif 3187