1/* $NetBSD: localtime.c,v 1.143 2024/03/11 23:03:35 christos Exp $ */ 2 3/* Convert timestamp from time_t to struct tm. */ 4 5/* 6** This file is in the public domain, so clarified as of 7** 1996-06-05 by Arthur David Olson. 8*/ 9 10#include <sys/cdefs.h> 11#if defined(LIBC_SCCS) && !defined(lint) 12#if 0 13static char elsieid[] = "@(#)localtime.c 8.17"; 14#else 15__RCSID("$NetBSD: localtime.c,v 1.143 2024/03/11 23:03:35 christos Exp $"); 16#endif 17#endif /* LIBC_SCCS and not lint */ 18 19/* 20** Leap second handling from Bradley White. 21** POSIX.1-1988 style TZ environment variable handling from Guy Harris. 22*/ 23 24/*LINTLIBRARY*/ 25 26#include "namespace.h" 27#include <assert.h> 28#define LOCALTIME_IMPLEMENTATION 29#include "private.h" 30 31#include "tzfile.h" 32#include <fcntl.h> 33 34#if defined(__weak_alias) 35__weak_alias(daylight,_daylight) 36__weak_alias(tzname,_tzname) 37#endif 38 39#ifndef TZ_ABBR_CHAR_SET 40# define TZ_ABBR_CHAR_SET \ 41 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" 42#endif /* !defined TZ_ABBR_CHAR_SET */ 43 44#ifndef TZ_ABBR_ERR_CHAR 45# define TZ_ABBR_ERR_CHAR '_' 46#endif /* !defined TZ_ABBR_ERR_CHAR */ 47 48/* 49** Support non-POSIX platforms that distinguish between text and binary files. 50*/ 51 52#ifndef O_BINARY 53# define O_BINARY 0 54#endif 55 56#ifndef WILDABBR 57/* 58** Someone might make incorrect use of a time zone abbreviation: 59** 1. They might reference tzname[0] before calling tzset (explicitly 60** or implicitly). 61** 2. They might reference tzname[1] before calling tzset (explicitly 62** or implicitly). 63** 3. They might reference tzname[1] after setting to a time zone 64** in which Daylight Saving Time is never observed. 65** 4. They might reference tzname[0] after setting to a time zone 66** in which Standard Time is never observed. 67** 5. They might reference tm.TM_ZONE after calling offtime. 68** What's best to do in the above cases is open to debate; 69** for now, we just set things up so that in any of the five cases 70** WILDABBR is used. Another possibility: initialize tzname[0] to the 71** string "tzname[0] used before set", and similarly for the other cases. 72** And another: initialize tzname[0] to "ERA", with an explanation in the 73** manual page of what this "time zone abbreviation" means (doing this so 74** that tzname[0] has the "normal" length of three characters). 75*/ 76# define WILDABBR " " 77#endif /* !defined WILDABBR */ 78 79static const char wildabbr[] = WILDABBR; 80 81static char const etc_utc[] = "Etc/UTC"; 82static char const *utc = etc_utc + sizeof "Etc/" - 1; 83 84/* 85** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. 86** Default to US rules as of 2017-05-07. 87** POSIX does not specify the default DST rules; 88** for historical reasons, US rules are a common default. 89*/ 90#ifndef TZDEFRULESTRING 91# define TZDEFRULESTRING ",M3.2.0,M11.1.0" 92#endif 93 94typedef int_fast64_t __time_t; 95 96struct ttinfo { /* time type information */ 97 int_fast32_t tt_utoff; /* UT offset in seconds */ 98 bool tt_isdst; /* used to set tm_isdst */ 99 int tt_desigidx; /* abbreviation list index */ 100 bool tt_ttisstd; /* transition is std time */ 101 bool tt_ttisut; /* transition is UT */ 102}; 103 104struct lsinfo { /* leap second information */ 105 __time_t ls_trans; /* transition time */ 106 int_fast32_t ls_corr; /* correction to apply */ 107}; 108 109/* This abbreviation means local time is unspecified. */ 110static char const UNSPEC[] = "-00"; 111 112/* How many extra bytes are needed at the end of struct state's chars array. 113 This needs to be at least 1 for null termination in case the input 114 data isn't properly terminated, and it also needs to be big enough 115 for ttunspecified to work without crashing. */ 116enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; 117 118/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings. 119 This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */ 120#ifndef TZNAME_MAXIMUM 121# define TZNAME_MAXIMUM 255 122#endif 123 124#define state __state 125/* A representation of the contents of a TZif file. Ideally this 126 would have no size limits; the following sizes should suffice for 127 practical use. This struct should not be too large, as instances 128 are put on the stack and stacks are relatively small on some platforms. 129 See tzfile.h for more about the sizes. */ 130struct state { 131 int leapcnt; 132 int timecnt; 133 int typecnt; 134 int charcnt; 135 bool goback; 136 bool goahead; 137 __time_t ats[TZ_MAX_TIMES]; 138 unsigned char types[TZ_MAX_TIMES]; 139 struct ttinfo ttis[TZ_MAX_TYPES]; 140 /*CONSTCOND*/ 141 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"), 142 2 * (TZNAME_MAXIMUM + 1))]; 143 struct lsinfo lsis[TZ_MAX_LEAPS]; 144 145 /* The time type to use for early times or if no transitions. 146 It is always zero for recent tzdb releases. 147 It might be nonzero for data from tzdb 2018e or earlier. */ 148 int defaulttype; 149}; 150 151enum r_type { 152 JULIAN_DAY, /* Jn = Julian day */ 153 DAY_OF_YEAR, /* n = day of year */ 154 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 155}; 156 157struct rule { 158 enum r_type r_type; /* type of rule */ 159 int r_day; /* day number of rule */ 160 int r_week; /* week number of rule */ 161 int r_mon; /* month number of rule */ 162 int_fast32_t r_time; /* transition time of rule */ 163}; 164 165static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 166 struct tm *); 167static bool increment_overflow(int *, int); 168static bool increment_overflow_time(__time_t *, int_fast32_t); 169static int_fast32_t leapcorr(struct state const *, __time_t); 170static bool normalize_overflow32(int_fast32_t *, int *, int); 171static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 172 struct tm *); 173static bool tzparse(char const *, struct state *, struct state const *); 174 175static timezone_t gmtptr; 176 177#ifndef TZ_STRLEN_MAX 178# define TZ_STRLEN_MAX 255 179#endif /* !defined TZ_STRLEN_MAX */ 180 181static char lcl_TZname[TZ_STRLEN_MAX + 1]; 182static int lcl_is_set; 183 184 185#if !defined(__LIBC12_SOURCE__) 186timezone_t __lclptr; 187#ifdef _REENTRANT 188rwlock_t __lcl_lock = RWLOCK_INITIALIZER; 189#endif 190#endif 191 192/* 193** Section 4.12.3 of X3.159-1989 requires that 194** Except for the strftime function, these functions [asctime, 195** ctime, gmtime, localtime] return values in one of two static 196** objects: a broken-down time structure and an array of char. 197** Thanks to Paul Eggert for noting this. 198** 199** This requirement was removed in C99, so support it only if requested, 200** as support is more likely to lead to bugs in badly written programs. 201*/ 202 203#if SUPPORT_C89 204static struct tm tm; 205#endif 206 207#if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__) 208# if !defined(__LIBC12_SOURCE__) 209 210__aconst char * tzname[2] = { 211 (__aconst char *)__UNCONST(wildabbr), 212 (__aconst char *)__UNCONST(wildabbr) 213}; 214 215# else 216 217extern __aconst char * tzname[2]; 218 219# endif /* __LIBC12_SOURCE__ */ 220#endif 221 222#if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__) 223# if !defined(__LIBC12_SOURCE__) 224long timezone = 0; 225int daylight = 0; 226# endif /* __LIBC12_SOURCE__ */ 227#endif /* 2<= USG_COMPAT + TZ_TIME_T */ 228 229#if 2 <= ALTZONE + TZ_TIME_T 230long altzone = 0; 231#endif /* 2 <= ALTZONE + TZ_TIME_T */ 232 233/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ 234static void 235init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx) 236{ 237 s->tt_utoff = utoff; 238 s->tt_isdst = isdst; 239 s->tt_desigidx = desigidx; 240 s->tt_ttisstd = false; 241 s->tt_ttisut = false; 242} 243 244/* Return true if SP's time type I does not specify local time. */ 245static bool 246ttunspecified(struct state const *sp, int i) 247{ 248 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; 249 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ 250 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; 251} 252 253static int_fast32_t 254detzcode(const char *const codep) 255{ 256 register int_fast32_t result; 257 register int i; 258 int_fast32_t one = 1; 259 int_fast32_t halfmaxval = one << (32 - 2); 260 int_fast32_t maxval = halfmaxval - 1 + halfmaxval; 261 int_fast32_t minval = -1 - maxval; 262 263 result = codep[0] & 0x7f; 264 for (i = 1; i < 4; ++i) 265 result = (result << 8) | (codep[i] & 0xff); 266 267 if (codep[0] & 0x80) { 268 /* Do two's-complement negation even on non-two's-complement machines. 269 If the result would be minval - 1, return minval. */ 270 result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0; 271 result += minval; 272 } 273 return result; 274} 275 276static int_fast64_t 277detzcode64(const char *const codep) 278{ 279 register int_fast64_t result; 280 register int i; 281 int_fast64_t one = 1; 282 int_fast64_t halfmaxval = one << (64 - 2); 283 int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 284 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 285 286 result = codep[0] & 0x7f; 287 for (i = 1; i < 8; ++i) 288 result = (result << 8) | (codep[i] & 0xff); 289 290 if (codep[0] & 0x80) { 291 /* Do two's-complement negation even on non-two's-complement machines. 292 If the result would be minval - 1, return minval. */ 293 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 294 result += minval; 295 } 296 return result; 297} 298 299#include <stdio.h> 300 301const char * 302tzgetname(const timezone_t sp, int isdst) 303{ 304 int i; 305 const char *name = NULL; 306 for (i = 0; i < sp->typecnt; ++i) { 307 const struct ttinfo *const ttisp = &sp->ttis[i]; 308 if (ttisp->tt_isdst == isdst) 309 name = &sp->chars[ttisp->tt_desigidx]; 310 } 311 if (name != NULL) 312 return name; 313 errno = ESRCH; 314 return NULL; 315} 316 317long 318tzgetgmtoff(const timezone_t sp, int isdst) 319{ 320 int i; 321 long l = -1; 322 for (i = 0; i < sp->typecnt; ++i) { 323 const struct ttinfo *const ttisp = &sp->ttis[i]; 324 325 if (ttisp->tt_isdst == isdst) { 326 l = ttisp->tt_utoff; 327 } 328 } 329 if (l == -1) 330 errno = ESRCH; 331 return l; 332} 333 334static void 335update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) 336{ 337#if HAVE_TZNAME 338 tzname[ttisp->tt_isdst] = __UNCONST(&sp->chars[ttisp->tt_desigidx]); 339#endif 340#if USG_COMPAT 341 if (!ttisp->tt_isdst) 342 timezone = - ttisp->tt_utoff; 343#endif 344#if ALTZONE 345 if (ttisp->tt_isdst) 346 altzone = - ttisp->tt_utoff; 347#endif 348} 349 350/* If STDDST_MASK indicates that SP's TYPE provides useful info, 351 update tzname, timezone, and/or altzone and return STDDST_MASK, 352 diminished by the provided info if it is a specified local time. 353 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */ 354static int 355may_update_tzname_etc(int stddst_mask, struct state *sp, int type) 356{ 357 struct ttinfo *ttisp = &sp->ttis[type]; 358 int this_bit = 1 << ttisp->tt_isdst; 359 if (stddst_mask & this_bit) { 360 update_tzname_etc(sp, ttisp); 361 if (!ttunspecified(sp, type)) 362 return stddst_mask & ~this_bit; 363 } 364 return stddst_mask; 365} 366 367static void 368settzname(void) 369{ 370 register timezone_t const sp = __lclptr; 371 register int i; 372 373 /* If STDDST_MASK & 1 we need info about a standard time. 374 If STDDST_MASK & 2 we need info about a daylight saving time. 375 When STDDST_MASK becomes zero we can stop looking. */ 376 int stddst_mask = 0; 377 378#if HAVE_TZNAME 379 tzname[0] = tzname[1] = __UNCONST(sp ? wildabbr : utc); 380 stddst_mask = 3; 381#endif 382#if USG_COMPAT 383 timezone = 0; 384 stddst_mask = 3; 385#endif 386#if ALTZONE 387 altzone = 0; 388 stddst_mask |= 2; 389#endif 390 /* 391 ** And to get the latest time zone abbreviations into tzname. . . 392 */ 393 if (sp) { 394 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--) 395 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]); 396 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--) 397 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i); 398 } 399 400#if USG_COMPAT 401 daylight = (unsigned int)stddst_mask >> 1 ^ 1; 402#endif 403} 404 405/* Replace bogus characters in time zone abbreviations. 406 Return 0 on success, an errno value if a time zone abbreviation is 407 too long. */ 408static int 409scrub_abbrs(struct state *sp) 410{ 411 int i; 412 413 /* Reject overlong abbreviations. */ 414 for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) { 415 int len = (int)strlen(&sp->chars[i]); 416 if (TZNAME_MAXIMUM < len) 417 return EOVERFLOW; 418 i += len + 1; 419 } 420 421 /* Replace bogus characters. */ 422 for (i = 0; i < sp->charcnt; ++i) 423 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) 424 sp->chars[i] = TZ_ABBR_ERR_CHAR; 425 426 return 0; 427} 428 429/* Input buffer for data read from a compiled tz file. */ 430union input_buffer { 431 /* The first part of the buffer, interpreted as a header. */ 432 struct tzhead tzhead; 433 434 /* The entire buffer. Ideally this would have no size limits; 435 the following should suffice for practical use. */ 436 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 437 + 4 * TZ_MAX_TIMES]; 438}; 439 440/* TZDIR with a trailing '/' rather than a trailing '\0'. */ 441static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; 442 443/* Local storage needed for 'tzloadbody'. */ 444union local_storage { 445 /* The results of analyzing the file's contents after it is opened. */ 446 struct file_analysis { 447 /* The input buffer. */ 448 union input_buffer u; 449 450 /* A temporary state used for parsing a TZ string in the file. */ 451 struct state st; 452 } u; 453 454 /* The name of the file to be opened. Ideally this would have no 455 size limits, to support arbitrarily long Zone names. 456 Limiting Zone names to 1024 bytes should suffice for practical use. 457 However, there is no need for this to be smaller than struct 458 file_analysis as that struct is allocated anyway, as the other 459 union member. */ 460 char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)]; 461}; 462 463/* Load tz data from the file named NAME into *SP. Read extended 464 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on 465 success, an errno value on failure. */ 466static int 467tzloadbody(char const *name, struct state *sp, bool doextend, 468 union local_storage *lsp) 469{ 470 register int i; 471 register int fid; 472 register int stored; 473 register ssize_t nread; 474 register bool doaccess; 475 register union input_buffer *up = &lsp->u.u; 476 register size_t tzheadsize = sizeof(struct tzhead); 477 478 sp->goback = sp->goahead = false; 479 480 if (! name) { 481 name = TZDEFAULT; 482 if (! name) 483 return EINVAL; 484 } 485 486 if (name[0] == ':') 487 ++name; 488#ifdef SUPPRESS_TZDIR 489 /* Do not prepend TZDIR. This is intended for specialized 490 applications only, due to its security implications. */ 491 doaccess = true; 492#else 493 doaccess = name[0] == '/'; 494#endif 495 if (!doaccess) { 496 char const *dot; 497 if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name)) 498 return ENAMETOOLONG; 499 500 /* Create a string "TZDIR/NAME". Using sprintf here 501 would pull in stdio (and would fail if the 502 resulting string length exceeded INT_MAX!). */ 503 memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); 504 strcpy(lsp->fullname + sizeof tzdirslash, name); 505 506 /* Set doaccess if NAME contains a ".." file name 507 component, as such a name could read a file outside 508 the TZDIR virtual subtree. */ 509 for (dot = name; (dot = strchr(dot, '.')); dot++) 510 if ((dot == name || dot[-1] == '/') && dot[1] == '.' 511 && (dot[2] == '/' || !dot[2])) { 512 doaccess = true; 513 break; 514 } 515 516 name = lsp->fullname; 517 } 518 if (doaccess && access(name, R_OK) != 0) 519 return errno; 520 fid = open(name, O_RDONLY | O_BINARY); 521 if (fid < 0) 522 return errno; 523 524 nread = read(fid, up->buf, sizeof up->buf); 525 if (nread < (ssize_t)tzheadsize) { 526 int err = nread < 0 ? errno : EINVAL; 527 close(fid); 528 return err; 529 } 530 if (close(fid) < 0) 531 return errno; 532 for (stored = 4; stored <= 8; stored *= 2) { 533 char version = up->tzhead.tzh_version[0]; 534 bool skip_datablock = stored == 4 && version; 535 int_fast32_t datablock_size; 536 int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); 537 int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); 538 int_fast64_t prevtr = -1; 539 int_fast32_t prevcorr = 0; 540 int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); 541 int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); 542 int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); 543 int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); 544 char const *p = up->buf + tzheadsize; 545 /* Although tzfile(5) currently requires typecnt to be nonzero, 546 support future formats that may allow zero typecnt 547 in files that have a TZ string and no transitions. */ 548 if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS 549 && 0 <= typecnt && typecnt < TZ_MAX_TYPES 550 && 0 <= timecnt && timecnt < TZ_MAX_TIMES 551 && 0 <= charcnt && charcnt < TZ_MAX_CHARS 552 && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES 553 && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES)) 554 return EINVAL; 555 datablock_size 556 = (timecnt * stored /* ats */ 557 + timecnt /* types */ 558 + typecnt * 6 /* ttinfos */ 559 + charcnt /* chars */ 560 + leapcnt * (stored + 4) /* lsinfos */ 561 + ttisstdcnt /* ttisstds */ 562 + ttisutcnt); /* ttisuts */ 563 if (nread < (ssize_t)(tzheadsize + datablock_size)) 564 return EINVAL; 565 if (skip_datablock) 566 p += datablock_size; 567 else { 568 if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 569 && (ttisutcnt == typecnt || ttisutcnt == 0))) 570 return EINVAL; 571 572 sp->leapcnt = (int)leapcnt; 573 sp->timecnt = (int)timecnt; 574 sp->typecnt = (int)typecnt; 575 sp->charcnt = (int)charcnt; 576 577 /* Read transitions, discarding those out of time_t range. 578 But pretend the last transition before TIME_T_MIN 579 occurred at TIME_T_MIN. */ 580 timecnt = 0; 581 for (i = 0; i < sp->timecnt; ++i) { 582 int_fast64_t at 583 = stored == 4 ? detzcode(p) : detzcode64(p); 584 sp->types[i] = at <= TIME_T_MAX; 585 if (sp->types[i]) { 586 time_t attime 587 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 588 ? TIME_T_MIN : (time_t)at); 589 if (timecnt && attime <= sp->ats[timecnt - 1]) { 590 if (attime < sp->ats[timecnt - 1]) 591 return EINVAL; 592 sp->types[i - 1] = 0; 593 timecnt--; 594 } 595 sp->ats[timecnt++] = attime; 596 } 597 p += stored; 598 } 599 600 timecnt = 0; 601 for (i = 0; i < sp->timecnt; ++i) { 602 unsigned char typ = *p++; 603 if (sp->typecnt <= typ) 604 return EINVAL; 605 if (sp->types[i]) 606 sp->types[timecnt++] = typ; 607 } 608 sp->timecnt = (int)timecnt; 609 for (i = 0; i < sp->typecnt; ++i) { 610 register struct ttinfo * ttisp; 611 unsigned char isdst, desigidx; 612 613 ttisp = &sp->ttis[i]; 614 ttisp->tt_utoff = detzcode(p); 615 p += 4; 616 isdst = *p++; 617 if (! (isdst < 2)) 618 return EINVAL; 619 ttisp->tt_isdst = isdst; 620 desigidx = *p++; 621 if (! (desigidx < sp->charcnt)) 622 return EINVAL; 623 ttisp->tt_desigidx = desigidx; 624 } 625 for (i = 0; i < sp->charcnt; ++i) 626 sp->chars[i] = *p++; 627 /* Ensure '\0'-terminated, and make it safe to call 628 ttunspecified later. */ 629 memset(&sp->chars[i], 0, CHARS_EXTRA); 630 631 /* Read leap seconds, discarding those out of time_t range. */ 632 leapcnt = 0; 633 for (i = 0; i < sp->leapcnt; ++i) { 634 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 635 int_fast32_t corr = detzcode(p + stored); 636 p += stored + 4; 637 638 /* Leap seconds cannot occur before the Epoch, 639 or out of order. */ 640 if (tr <= prevtr) 641 return EINVAL; 642 643 /* To avoid other botches in this code, each leap second's 644 correction must differ from the previous one's by 1 645 second or less, except that the first correction can be 646 any value; these requirements are more generous than 647 RFC 8536, to allow future RFC extensions. */ 648 if (! (i == 0 649 || (prevcorr < corr 650 ? corr == prevcorr + 1 651 : (corr == prevcorr 652 || corr == prevcorr - 1)))) 653 return EINVAL; 654 prevtr = tr; 655 prevcorr = corr; 656 657 if (tr <= TIME_T_MAX) { 658 sp->lsis[leapcnt].ls_trans = (time_t)tr; 659 sp->lsis[leapcnt].ls_corr = corr; 660 leapcnt++; 661 } 662 } 663 sp->leapcnt = (int)leapcnt; 664 665 for (i = 0; i < sp->typecnt; ++i) { 666 register struct ttinfo * ttisp; 667 668 ttisp = &sp->ttis[i]; 669 if (ttisstdcnt == 0) 670 ttisp->tt_ttisstd = false; 671 else { 672 if (*p != true && *p != false) 673 return EINVAL; 674 ttisp->tt_ttisstd = *p++; 675 } 676 } 677 for (i = 0; i < sp->typecnt; ++i) { 678 register struct ttinfo * ttisp; 679 680 ttisp = &sp->ttis[i]; 681 if (ttisutcnt == 0) 682 ttisp->tt_ttisut = false; 683 else { 684 if (*p != true && *p != false) 685 return EINVAL; 686 ttisp->tt_ttisut = *p++; 687 } 688 } 689 } 690 691 nread -= p - up->buf; 692 memmove(up->buf, p, (size_t)nread); 693 694 /* If this is an old file, we're done. */ 695 if (!version) 696 break; 697 } 698 if (doextend && nread > 2 && 699 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 700 sp->typecnt + 2 <= TZ_MAX_TYPES) { 701 struct state *ts = &lsp->u.st; 702 703 up->buf[nread - 1] = '\0'; 704 if (tzparse(&up->buf[1], ts, sp)) { 705 706 /* Attempt to reuse existing abbreviations. 707 Without this, America/Anchorage would be right on 708 the edge after 2037 when TZ_MAX_CHARS is 50, as 709 sp->charcnt equals 40 (for LMT AST AWT APT AHST 710 AHDT YST AKDT AKST) and ts->charcnt equals 10 711 (for AKST AKDT). Reusing means sp->charcnt can 712 stay 40 in this example. */ 713 int gotabbr = 0; 714 int charcnt = sp->charcnt; 715 for (i = 0; i < ts->typecnt; i++) { 716 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 717 int j; 718 for (j = 0; j < charcnt; j++) 719 if (strcmp(sp->chars + j, tsabbr) == 0) { 720 ts->ttis[i].tt_desigidx = j; 721 gotabbr++; 722 break; 723 } 724 if (! (j < charcnt)) { 725 size_t tsabbrlen = strlen(tsabbr); 726 if (j + tsabbrlen < TZ_MAX_CHARS) { 727 strcpy(sp->chars + j, tsabbr); 728 charcnt = (int)(j + tsabbrlen + 1); 729 ts->ttis[i].tt_desigidx = j; 730 gotabbr++; 731 } 732 } 733 } 734 if (gotabbr == ts->typecnt) { 735 sp->charcnt = charcnt; 736 737 /* Ignore any trailing, no-op transitions generated 738 by zic as they don't help here and can run afoul 739 of bugs in zic 2016j or earlier. */ 740 while (1 < sp->timecnt 741 && (sp->types[sp->timecnt - 1] 742 == sp->types[sp->timecnt - 2])) 743 sp->timecnt--; 744 745 sp->goahead = ts->goahead; 746 747 for (i = 0; i < ts->timecnt; i++) { 748 __time_t t = ts->ats[i]; 749 if (increment_overflow_time(&t, leapcorr(sp, t)) 750 || (0 < sp->timecnt 751 && t <= sp->ats[sp->timecnt - 1])) 752 continue; 753 if (TZ_MAX_TIMES <= sp->timecnt) { 754 sp->goahead = false; 755 break; 756 } 757 sp->ats[sp->timecnt] = t; 758 sp->types[sp->timecnt] = (sp->typecnt 759 + ts->types[i]); 760 sp->timecnt++; 761 } 762 for (i = 0; i < ts->typecnt; i++) 763 sp->ttis[sp->typecnt++] = ts->ttis[i]; 764 } 765 } 766 } 767 if (sp->typecnt == 0) 768 return EINVAL; 769 770 /* Infer sp->defaulttype from the data. Although this default 771 type is always zero for data from recent tzdb releases, 772 things are trickier for data from tzdb 2018e or earlier. 773 774 The first set of heuristics work around bugs in 32-bit data 775 generated by tzdb 2013c or earlier. The workaround is for 776 zones like Australia/Macquarie where timestamps before the 777 first transition have a time type that is not the earliest 778 standard-time type. See: 779 https://mm.icann.org/pipermail/tz/2013-May/019368.html */ 780 /* 781 ** If type 0 does not specify local time, or is unused in transitions, 782 ** it's the type to use for early times. 783 */ 784 for (i = 0; i < sp->timecnt; ++i) 785 if (sp->types[i] == 0) 786 break; 787 i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0; 788 /* 789 ** Absent the above, 790 ** if there are transition times 791 ** and the first transition is to a daylight time 792 ** find the standard type less than and closest to 793 ** the type of the first transition. 794 */ 795 if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) { 796 i = sp->types[0]; 797 while (--i >= 0) 798 if (!sp->ttis[i].tt_isdst) 799 break; 800 } 801 /* The next heuristics are for data generated by tzdb 2018e or 802 earlier, for zones like EST5EDT where the first transition 803 is to DST. */ 804 /* 805 ** If no result yet, find the first standard type. 806 ** If there is none, punt to type zero. 807 */ 808 if (i < 0) { 809 i = 0; 810 while (sp->ttis[i].tt_isdst) 811 if (++i >= sp->typecnt) { 812 i = 0; 813 break; 814 } 815 } 816 /* A simple 'sp->defaulttype = 0;' would suffice here if we 817 didn't have to worry about 2018e-or-earlier data. Even 818 simpler would be to remove the defaulttype member and just 819 use 0 in its place. */ 820 sp->defaulttype = i; 821 822 return 0; 823} 824 825/* Load tz data from the file named NAME into *SP. Read extended 826 format if DOEXTEND. Return 0 on success, an errno value on failure. */ 827static int 828tzload(char const *name, struct state *sp, bool doextend) 829{ 830 union local_storage *lsp = malloc(sizeof *lsp); 831 if (!lsp) { 832 return /*CONSTCOND*/HAVE_MALLOC_ERRNO ? errno : ENOMEM; 833 } else { 834 int err = tzloadbody(name, sp, doextend, lsp); 835 free(lsp); 836 return err; 837 } 838} 839 840static const int mon_lengths[2][MONSPERYEAR] = { 841 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 842 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 843}; 844 845static const int year_lengths[2] = { 846 DAYSPERNYEAR, DAYSPERLYEAR 847}; 848 849/* Is C an ASCII digit? */ 850static bool 851is_digit(char c) 852{ 853 return '0' <= c && c <= '9'; 854} 855 856/* 857** Given a pointer into a timezone string, scan until a character that is not 858** a valid character in a time zone abbreviation is found. 859** Return a pointer to that character. 860*/ 861 862ATTRIBUTE_REPRODUCIBLE static const char * 863getzname(register const char *strp) 864{ 865 register char c; 866 867 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 868 c != '+') 869 ++strp; 870 return strp; 871} 872 873/* 874** Given a pointer into an extended timezone string, scan until the ending 875** delimiter of the time zone abbreviation is located. 876** Return a pointer to the delimiter. 877** 878** As with getzname above, the legal character set is actually quite 879** restricted, with other characters producing undefined results. 880** We don't do any checking here; checking is done later in common-case code. 881*/ 882 883ATTRIBUTE_REPRODUCIBLE static const char * 884getqzname(register const char *strp, const int delim) 885{ 886 register int c; 887 888 while ((c = *strp) != '\0' && c != delim) 889 ++strp; 890 return strp; 891} 892 893/* 894** Given a pointer into a timezone string, extract a number from that string. 895** Check that the number is within a specified range; if it is not, return 896** NULL. 897** Otherwise, return a pointer to the first character not part of the number. 898*/ 899 900static const char * 901getnum(register const char *strp, int *const nump, const int min, const int max) 902{ 903 register char c; 904 register int num; 905 906 if (strp == NULL || !is_digit(c = *strp)) { 907 errno = EINVAL; 908 return NULL; 909 } 910 num = 0; 911 do { 912 num = num * 10 + (c - '0'); 913 if (num > max) { 914 errno = EOVERFLOW; 915 return NULL; /* illegal value */ 916 } 917 c = *++strp; 918 } while (is_digit(c)); 919 if (num < min) { 920 errno = EINVAL; 921 return NULL; /* illegal value */ 922 } 923 *nump = num; 924 return strp; 925} 926 927/* 928** Given a pointer into a timezone string, extract a number of seconds, 929** in hh[:mm[:ss]] form, from the string. 930** If any error occurs, return NULL. 931** Otherwise, return a pointer to the first character not part of the number 932** of seconds. 933*/ 934 935static const char * 936getsecs(register const char *strp, int_fast32_t *const secsp) 937{ 938 int num; 939 int_fast32_t secsperhour = SECSPERHOUR; 940 941 /* 942 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 943 ** "M10.4.6/26", which does not conform to POSIX, 944 ** but which specifies the equivalent of 945 ** "02:00 on the first Sunday on or after 23 Oct". 946 */ 947 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 948 if (strp == NULL) 949 return NULL; 950 *secsp = num * secsperhour; 951 if (*strp == ':') { 952 ++strp; 953 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 954 if (strp == NULL) 955 return NULL; 956 *secsp += num * SECSPERMIN; 957 if (*strp == ':') { 958 ++strp; 959 /* 'SECSPERMIN' allows for leap seconds. */ 960 strp = getnum(strp, &num, 0, SECSPERMIN); 961 if (strp == NULL) 962 return NULL; 963 *secsp += num; 964 } 965 } 966 return strp; 967} 968 969/* 970** Given a pointer into a timezone string, extract an offset, in 971** [+-]hh[:mm[:ss]] form, from the string. 972** If any error occurs, return NULL. 973** Otherwise, return a pointer to the first character not part of the time. 974*/ 975 976static const char * 977getoffset(register const char *strp, int_fast32_t *const offsetp) 978{ 979 register bool neg = false; 980 981 if (*strp == '-') { 982 neg = true; 983 ++strp; 984 } else if (*strp == '+') 985 ++strp; 986 strp = getsecs(strp, offsetp); 987 if (strp == NULL) 988 return NULL; /* illegal time */ 989 if (neg) 990 *offsetp = -*offsetp; 991 return strp; 992} 993 994/* 995** Given a pointer into a timezone string, extract a rule in the form 996** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 997** for the format of "date" and "time". 998** If a valid rule is not found, return NULL. 999** Otherwise, return a pointer to the first character not part of the rule. 1000*/ 1001 1002static const char * 1003getrule(const char *strp, register struct rule *const rulep) 1004{ 1005 if (*strp == 'J') { 1006 /* 1007 ** Julian day. 1008 */ 1009 rulep->r_type = JULIAN_DAY; 1010 ++strp; 1011 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1012 } else if (*strp == 'M') { 1013 /* 1014 ** Month, week, day. 1015 */ 1016 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1017 ++strp; 1018 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1019 if (strp == NULL) 1020 return NULL; 1021 if (*strp++ != '.') 1022 return NULL; 1023 strp = getnum(strp, &rulep->r_week, 1, 5); 1024 if (strp == NULL) 1025 return NULL; 1026 if (*strp++ != '.') 1027 return NULL; 1028 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1029 } else if (is_digit(*strp)) { 1030 /* 1031 ** Day of year. 1032 */ 1033 rulep->r_type = DAY_OF_YEAR; 1034 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1035 } else return NULL; /* invalid format */ 1036 if (strp == NULL) 1037 return NULL; 1038 if (*strp == '/') { 1039 /* 1040 ** Time specified. 1041 */ 1042 ++strp; 1043 strp = getoffset(strp, &rulep->r_time); 1044 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1045 return strp; 1046} 1047 1048/* 1049** Given a year, a rule, and the offset from UT at the time that rule takes 1050** effect, calculate the year-relative time that rule takes effect. 1051*/ 1052 1053static int_fast32_t 1054transtime(const int year, register const struct rule *const rulep, 1055 const int_fast32_t offset) 1056{ 1057 register bool leapyear; 1058 register int_fast32_t value; 1059 register int i; 1060 int d, m1, yy0, yy1, yy2, dow; 1061 1062 leapyear = isleap(year); 1063 switch (rulep->r_type) { 1064 1065 case JULIAN_DAY: 1066 /* 1067 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1068 ** years. 1069 ** In non-leap years, or if the day number is 59 or less, just 1070 ** add SECSPERDAY times the day number-1 to the time of 1071 ** January 1, midnight, to get the day. 1072 */ 1073 value = (rulep->r_day - 1) * SECSPERDAY; 1074 if (leapyear && rulep->r_day >= 60) 1075 value += SECSPERDAY; 1076 break; 1077 1078 case DAY_OF_YEAR: 1079 /* 1080 ** n - day of year. 1081 ** Just add SECSPERDAY times the day number to the time of 1082 ** January 1, midnight, to get the day. 1083 */ 1084 value = rulep->r_day * SECSPERDAY; 1085 break; 1086 1087 case MONTH_NTH_DAY_OF_WEEK: 1088 /* 1089 ** Mm.n.d - nth "dth day" of month m. 1090 */ 1091 1092 /* 1093 ** Use Zeller's Congruence to get day-of-week of first day of 1094 ** month. 1095 */ 1096 m1 = (rulep->r_mon + 9) % 12 + 1; 1097 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1098 yy1 = yy0 / 100; 1099 yy2 = yy0 % 100; 1100 dow = ((26 * m1 - 2) / 10 + 1101 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1102 if (dow < 0) 1103 dow += DAYSPERWEEK; 1104 1105 /* 1106 ** "dow" is the day-of-week of the first day of the month. Get 1107 ** the day-of-month (zero-origin) of the first "dow" day of the 1108 ** month. 1109 */ 1110 d = rulep->r_day - dow; 1111 if (d < 0) 1112 d += DAYSPERWEEK; 1113 for (i = 1; i < rulep->r_week; ++i) { 1114 if (d + DAYSPERWEEK >= 1115 mon_lengths[leapyear][rulep->r_mon - 1]) 1116 break; 1117 d += DAYSPERWEEK; 1118 } 1119 1120 /* 1121 ** "d" is the day-of-month (zero-origin) of the day we want. 1122 */ 1123 value = d * SECSPERDAY; 1124 for (i = 0; i < rulep->r_mon - 1; ++i) 1125 value += mon_lengths[leapyear][i] * SECSPERDAY; 1126 break; 1127 1128 default: unreachable(); 1129 } 1130 1131 /* 1132 ** "value" is the year-relative time of 00:00:00 UT on the day in 1133 ** question. To get the year-relative time of the specified local 1134 ** time on that day, add the transition time and the current offset 1135 ** from UT. 1136 */ 1137 return value + rulep->r_time + offset; 1138} 1139 1140/* 1141** Given a POSIX.1-2017-style TZ string, fill in the rule tables as 1142** appropriate. 1143*/ 1144 1145static bool 1146tzparse(const char *name, struct state *sp, struct state const *basep) 1147{ 1148 const char * stdname; 1149 const char * dstname; 1150 int_fast32_t stdoffset; 1151 int_fast32_t dstoffset; 1152 register char * cp; 1153 register bool load_ok; 1154 ptrdiff_t stdlen, dstlen, charcnt; 1155 __time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1156 1157 dstname = NULL; /* XXX gcc */ 1158 stdname = name; 1159 if (*name == '<') { 1160 name++; 1161 stdname = name; 1162 name = getqzname(name, '>'); 1163 if (*name != '>') 1164 return false; 1165 stdlen = name - stdname; 1166 name++; 1167 } else { 1168 name = getzname(name); 1169 stdlen = name - stdname; 1170 } 1171 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1172 return false; 1173 name = getoffset(name, &stdoffset); 1174 if (name == NULL) 1175 return false; 1176 charcnt = stdlen + 1; 1177 if (basep) { 1178 if (0 < basep->timecnt) 1179 atlo = basep->ats[basep->timecnt - 1]; 1180 load_ok = false; 1181 sp->leapcnt = basep->leapcnt; 1182 memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); 1183 } else { 1184 load_ok = tzload(TZDEFRULES, sp, false) == 0; 1185 if (!load_ok) 1186 sp->leapcnt = 0; /* So, we're off a little. */ 1187 } 1188 if (0 < sp->leapcnt) 1189 leaplo = sp->lsis[sp->leapcnt - 1].ls_trans; 1190 sp->goback = sp->goahead = false; 1191 if (*name != '\0') { 1192 if (*name == '<') { 1193 dstname = ++name; 1194 name = getqzname(name, '>'); 1195 if (*name != '>') 1196 return false; 1197 dstlen = name - dstname; 1198 name++; 1199 } else { 1200 dstname = name; 1201 name = getzname(name); 1202 dstlen = name - dstname; /* length of DST abbr. */ 1203 } 1204 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1205 return false; 1206 charcnt += dstlen + 1; 1207 if (*name != '\0' && *name != ',' && *name != ';') { 1208 name = getoffset(name, &dstoffset); 1209 if (name == NULL) 1210 return false; 1211 } else dstoffset = stdoffset - SECSPERHOUR; 1212 if (*name == '\0' && !load_ok) 1213 name = TZDEFRULESTRING; 1214 if (*name == ',' || *name == ';') { 1215 struct rule start; 1216 struct rule end; 1217 register int year; 1218 register int timecnt; 1219 __time_t janfirst; 1220 int_fast32_t janoffset = 0; 1221 int yearbeg, yearlim; 1222 1223 ++name; 1224 if ((name = getrule(name, &start)) == NULL) 1225 return false; 1226 if (*name++ != ',') 1227 return false; 1228 if ((name = getrule(name, &end)) == NULL) 1229 return false; 1230 if (*name != '\0') 1231 return false; 1232 sp->typecnt = 2; /* standard time and DST */ 1233 /* 1234 ** Two transitions per year, from EPOCH_YEAR forward. 1235 */ 1236 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1237 init_ttinfo(&sp->ttis[1], -dstoffset, true, 1238 (int)(stdlen + 1)); 1239 timecnt = 0; 1240 janfirst = 0; 1241 yearbeg = EPOCH_YEAR; 1242 1243 do { 1244 int_fast32_t yearsecs 1245 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1246 yearbeg--; 1247 if (increment_overflow_time(&janfirst, -yearsecs)) { 1248 janoffset = -yearsecs; 1249 break; 1250 } 1251 } while (atlo < janfirst 1252 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1253 1254 for (;;) { 1255 int_fast32_t yearsecs 1256 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1257 int yearbeg1 = yearbeg; 1258 __time_t janfirst1 = janfirst; 1259 if (increment_overflow_time(&janfirst1, yearsecs) 1260 || increment_overflow(&yearbeg1, 1) 1261 || atlo <= janfirst1) 1262 break; 1263 yearbeg = yearbeg1; 1264 janfirst = janfirst1; 1265 } 1266 1267 yearlim = yearbeg; 1268 if (increment_overflow(&yearlim, years_of_observations)) 1269 yearlim = INT_MAX; 1270 for (year = yearbeg; year < yearlim; year++) { 1271 int_fast32_t 1272 starttime = transtime(year, &start, stdoffset), 1273 endtime = transtime(year, &end, dstoffset); 1274 int_fast32_t 1275 yearsecs = (year_lengths[isleap(year)] 1276 * SECSPERDAY); 1277 bool reversed = endtime < starttime; 1278 if (reversed) { 1279 int_fast32_t swap = starttime; 1280 starttime = endtime; 1281 endtime = swap; 1282 } 1283 if (reversed 1284 || (starttime < endtime 1285 && endtime - starttime < yearsecs)) { 1286 if (TZ_MAX_TIMES - 2 < timecnt) 1287 break; 1288 sp->ats[timecnt] = janfirst; 1289 if (! increment_overflow_time 1290 (&sp->ats[timecnt], 1291 janoffset + starttime) 1292 && atlo <= sp->ats[timecnt]) 1293 sp->types[timecnt++] = !reversed; 1294 sp->ats[timecnt] = janfirst; 1295 if (! increment_overflow_time 1296 (&sp->ats[timecnt], 1297 janoffset + endtime) 1298 && atlo <= sp->ats[timecnt]) { 1299 sp->types[timecnt++] = reversed; 1300 } 1301 } 1302 if (endtime < leaplo) { 1303 yearlim = year; 1304 if (increment_overflow(&yearlim, 1305 years_of_observations)) 1306 yearlim = INT_MAX; 1307 } 1308 if (increment_overflow_time 1309 (&janfirst, janoffset + yearsecs)) 1310 break; 1311 janoffset = 0; 1312 } 1313 sp->timecnt = timecnt; 1314 if (! timecnt) { 1315 sp->ttis[0] = sp->ttis[1]; 1316 sp->typecnt = 1; /* Perpetual DST. */ 1317 } else if (years_of_observations <= year - yearbeg) 1318 sp->goback = sp->goahead = true; 1319 } else { 1320 register int_fast32_t theirstdoffset; 1321 register int_fast32_t theirdstoffset; 1322 register int_fast32_t theiroffset; 1323 register bool isdst; 1324 register int i; 1325 register int j; 1326 1327 if (*name != '\0') 1328 return false; 1329 /* 1330 ** Initial values of theirstdoffset and theirdstoffset. 1331 */ 1332 theirstdoffset = 0; 1333 for (i = 0; i < sp->timecnt; ++i) { 1334 j = sp->types[i]; 1335 if (!sp->ttis[j].tt_isdst) { 1336 theirstdoffset = 1337 - sp->ttis[j].tt_utoff; 1338 break; 1339 } 1340 } 1341 theirdstoffset = 0; 1342 for (i = 0; i < sp->timecnt; ++i) { 1343 j = sp->types[i]; 1344 if (sp->ttis[j].tt_isdst) { 1345 theirdstoffset = 1346 - sp->ttis[j].tt_utoff; 1347 break; 1348 } 1349 } 1350 /* 1351 ** Initially we're assumed to be in standard time. 1352 */ 1353 isdst = false; 1354 /* 1355 ** Now juggle transition times and types 1356 ** tracking offsets as you do. 1357 */ 1358 for (i = 0; i < sp->timecnt; ++i) { 1359 j = sp->types[i]; 1360 sp->types[i] = sp->ttis[j].tt_isdst; 1361 if (sp->ttis[j].tt_ttisut) { 1362 /* No adjustment to transition time */ 1363 } else { 1364 /* 1365 ** If daylight saving time is in 1366 ** effect, and the transition time was 1367 ** not specified as standard time, add 1368 ** the daylight saving time offset to 1369 ** the transition time; otherwise, add 1370 ** the standard time offset to the 1371 ** transition time. 1372 */ 1373 /* 1374 ** Transitions from DST to DDST 1375 ** will effectively disappear since 1376 ** POSIX.1-2017 provides for only one 1377 ** DST offset. 1378 */ 1379 if (isdst && !sp->ttis[j].tt_ttisstd) { 1380 sp->ats[i] += (time_t) 1381 (dstoffset - theirdstoffset); 1382 } else { 1383 sp->ats[i] += (time_t) 1384 (stdoffset - theirstdoffset); 1385 } 1386 } 1387 theiroffset = -sp->ttis[j].tt_utoff; 1388 if (sp->ttis[j].tt_isdst) 1389 theirstdoffset = theiroffset; 1390 else theirdstoffset = theiroffset; 1391 } 1392 /* 1393 ** Finally, fill in ttis. 1394 */ 1395 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1396 init_ttinfo(&sp->ttis[1], -dstoffset, true, 1397 (int)(stdlen + 1)); 1398 sp->typecnt = 2; 1399 } 1400 } else { 1401 dstlen = 0; 1402 sp->typecnt = 1; /* only standard time */ 1403 sp->timecnt = 0; 1404 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1405 init_ttinfo(&sp->ttis[1], 0, false, 0); 1406 } 1407 sp->defaulttype = 0; 1408 sp->charcnt = (int)charcnt; 1409 cp = sp->chars; 1410 memcpy(cp, stdname, stdlen); 1411 cp += stdlen; 1412 *cp++ = '\0'; 1413 if (dstlen != 0) { 1414 (void) memcpy(cp, dstname, dstlen); 1415 *(cp + dstlen) = '\0'; 1416 } 1417 return true; 1418} 1419 1420static void 1421gmtload(struct state *const sp) 1422{ 1423 if (tzload(etc_utc, sp, true) != 0) 1424 (void)tzparse("UTC0", sp, NULL); 1425} 1426 1427/* Initialize *SP to a value appropriate for the TZ setting NAME. 1428 Return 0 on success, an errno value on failure. */ 1429static int 1430zoneinit(struct state *sp, char const *name) 1431{ 1432 if (name && ! name[0]) { 1433 /* 1434 ** User wants it fast rather than right. 1435 */ 1436 sp->leapcnt = 0; /* so, we're off a little */ 1437 sp->timecnt = 0; 1438 sp->typecnt = 1; 1439 sp->charcnt = 0; 1440 sp->goback = sp->goahead = false; 1441 init_ttinfo(&sp->ttis[0], 0, false, 0); 1442 strcpy(sp->chars, utc); 1443 sp->defaulttype = 0; 1444 return 0; 1445 } else { 1446 int err = tzload(name, sp, true); 1447 if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) 1448 err = 0; 1449 if (err == 0) 1450 err = scrub_abbrs(sp); 1451 return err; 1452 } 1453} 1454 1455static void 1456tzsetlcl(char const *name) 1457{ 1458 struct state *sp = __lclptr; 1459 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1460 if (lcl < 0 1461 ? lcl_is_set < 0 1462 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1463 return; 1464 1465 if (! sp) 1466 __lclptr = sp = malloc(sizeof *__lclptr); 1467 if (sp) { 1468 if (zoneinit(sp, name) != 0) 1469 zoneinit(sp, ""); 1470 if (0 < lcl) 1471 strcpy(lcl_TZname, name); 1472 } 1473 settzname(); 1474 lcl_is_set = lcl; 1475} 1476 1477#ifdef STD_INSPIRED 1478void 1479tzsetwall(void) 1480{ 1481 rwlock_wrlock(&__lcl_lock); 1482 tzsetlcl(NULL); 1483 rwlock_unlock(&__lcl_lock); 1484} 1485#endif 1486 1487void 1488tzset_unlocked(void) 1489{ 1490 tzsetlcl(getenv("TZ")); 1491} 1492 1493void 1494tzset(void) 1495{ 1496 rwlock_wrlock(&__lcl_lock); 1497 tzset_unlocked(); 1498 rwlock_unlock(&__lcl_lock); 1499} 1500 1501static void 1502gmtcheck(void) 1503{ 1504 static bool gmt_is_set; 1505 rwlock_wrlock(&__lcl_lock); 1506 if (! gmt_is_set) { 1507 gmtptr = malloc(sizeof *gmtptr); 1508 if (gmtptr) 1509 gmtload(gmtptr); 1510 gmt_is_set = true; 1511 } 1512 rwlock_unlock(&__lcl_lock); 1513} 1514 1515#if NETBSD_INSPIRED 1516 1517timezone_t 1518tzalloc(char const *name) 1519{ 1520 timezone_t sp = malloc(sizeof *sp); 1521 if (sp) { 1522 int err = zoneinit(sp, name); 1523 if (err != 0) { 1524 free(sp); 1525 errno = err; 1526 return NULL; 1527 } 1528 } else if (/*CONSTCOND*/!HAVE_MALLOC_ERRNO) 1529 /*NOTREACHED*/ 1530 errno = ENOMEM; 1531 return sp; 1532} 1533 1534void 1535tzfree(timezone_t sp) 1536{ 1537 free(sp); 1538} 1539 1540/* 1541** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and 1542** ctime_r are obsolescent and have potential security problems that 1543** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1544** 1545** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1546** in zones with three or more time zone abbreviations. 1547** Callers can instead use localtime_rz + strftime. 1548*/ 1549 1550#endif 1551 1552/* 1553** The easy way to behave "as if no library function calls" localtime 1554** is to not call it, so we drop its guts into "localsub", which can be 1555** freely called. (And no, the PANS doesn't require the above behavior, 1556** but it *is* desirable.) 1557** 1558** If successful and SETNAME is nonzero, 1559** set the applicable parts of tzname, timezone and altzone; 1560** however, it's OK to omit this step 1561** if the timezone is compatible with POSIX.1-2017 1562** since in that case tzset should have already done this step correctly. 1563** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1564** but it is actually a boolean and its value should be 0 or 1. 1565*/ 1566 1567/*ARGSUSED*/ 1568static struct tm * 1569localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1570 struct tm *const tmp) 1571{ 1572 register const struct ttinfo * ttisp; 1573 register int i; 1574 register struct tm * result; 1575 const time_t t = *timep; 1576 1577 if (sp == NULL) { 1578 /* Don't bother to set tzname etc.; tzset has already done it. */ 1579 return gmtsub(gmtptr, timep, 0, tmp); 1580 } 1581 if ((sp->goback && t < sp->ats[0]) || 1582 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1583 time_t newt; 1584 register __time_t seconds; 1585 register time_t years; 1586 1587 if (t < sp->ats[0]) 1588 seconds = sp->ats[0] - t; 1589 else seconds = t - sp->ats[sp->timecnt - 1]; 1590 --seconds; 1591 1592 /* Beware integer overflow, as SECONDS might 1593 be close to the maximum time_t. */ 1594 years = (time_t)(seconds / SECSPERREPEAT 1595 * YEARSPERREPEAT); 1596 seconds = (time_t)(years * AVGSECSPERYEAR); 1597 years += YEARSPERREPEAT; 1598 if (t < sp->ats[0]) 1599 newt = (time_t)(t + seconds + SECSPERREPEAT); 1600 else 1601 newt = (time_t)(t - seconds - SECSPERREPEAT); 1602 1603 if (newt < sp->ats[0] || 1604 newt > sp->ats[sp->timecnt - 1]) { 1605 errno = EINVAL; 1606 return NULL; /* "cannot happen" */ 1607 } 1608 result = localsub(sp, &newt, setname, tmp); 1609 if (result) { 1610#if defined ckd_add && defined ckd_sub 1611 if (t < sp->ats[0] 1612 ? ckd_sub(&result->tm_year, 1613 result->tm_year, years) 1614 : ckd_add(&result->tm_year, 1615 result->tm_year, years)) 1616 return NULL; 1617#else 1618 register int_fast64_t newy; 1619 1620 newy = result->tm_year; 1621 if (t < sp->ats[0]) 1622 newy -= years; 1623 else newy += years; 1624 if (! (INT_MIN <= newy && newy <= INT_MAX)) { 1625 errno = EOVERFLOW; 1626 return NULL; 1627 } 1628 result->tm_year = (int)newy; 1629#endif 1630 } 1631 return result; 1632 } 1633 if (sp->timecnt == 0 || t < sp->ats[0]) { 1634 i = sp->defaulttype; 1635 } else { 1636 register int lo = 1; 1637 register int hi = sp->timecnt; 1638 1639 while (lo < hi) { 1640 register int mid = (lo + hi) / 2; 1641 1642 if (t < sp->ats[mid]) 1643 hi = mid; 1644 else lo = mid + 1; 1645 } 1646 i = sp->types[lo - 1]; 1647 } 1648 ttisp = &sp->ttis[i]; 1649 /* 1650 ** To get (wrong) behavior that's compatible with System V Release 2.0 1651 ** you'd replace the statement below with 1652 ** t += ttisp->tt_utoff; 1653 ** timesub(&t, 0L, sp, tmp); 1654 */ 1655 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1656 if (result) { 1657 result->tm_isdst = ttisp->tt_isdst; 1658#ifdef TM_ZONE 1659 result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_desigidx]); 1660#endif /* defined TM_ZONE */ 1661 if (setname) 1662 update_tzname_etc(sp, ttisp); 1663 } 1664 return result; 1665} 1666 1667#if NETBSD_INSPIRED 1668 1669struct tm * 1670localtime_rz(struct state *__restrict sp, time_t const *__restrict timep, 1671 struct tm *__restrict tmp) 1672{ 1673 return localsub(sp, timep, 0, tmp); 1674} 1675 1676#endif 1677 1678static struct tm * 1679localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1680{ 1681 rwlock_wrlock(&__lcl_lock); 1682 if (setname || !lcl_is_set) 1683 tzset_unlocked(); 1684 tmp = localsub(__lclptr, timep, setname, tmp); 1685 rwlock_unlock(&__lcl_lock); 1686 return tmp; 1687} 1688 1689struct tm * 1690localtime(const time_t *timep) 1691{ 1692#if !SUPPORT_C89 1693 static struct tm tm; 1694#endif 1695 return localtime_tzset(timep, &tm, true); 1696} 1697 1698struct tm * 1699localtime_r(const time_t *__restrict timep, struct tm *__restrict tmp) 1700{ 1701 return localtime_tzset(timep, tmp, true); 1702} 1703 1704/* 1705** gmtsub is to gmtime as localsub is to localtime. 1706*/ 1707 1708static struct tm * 1709gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1710 int_fast32_t offset, struct tm *tmp) 1711{ 1712 register struct tm * result; 1713 1714 result = timesub(timep, offset, gmtptr, tmp); 1715#ifdef TM_ZONE 1716 /* 1717 ** Could get fancy here and deliver something such as 1718 ** "+xx" or "-xx" if offset is non-zero, 1719 ** but this is no time for a treasure hunt. 1720 */ 1721 if (result) 1722 result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ? 1723 gmtptr->chars : __UNCONST(utc); 1724#endif /* defined TM_ZONE */ 1725 return result; 1726} 1727 1728/* 1729* Re-entrant version of gmtime. 1730*/ 1731 1732struct tm * 1733gmtime_r(time_t const *__restrict timep, struct tm *__restrict tmp) 1734{ 1735 gmtcheck(); 1736 return gmtsub(NULL, timep, 0, tmp); 1737} 1738 1739struct tm * 1740gmtime(const time_t *timep) 1741{ 1742#if !SUPPORT_C89 1743 static struct tm tm; 1744#endif 1745 return gmtime_r(timep, &tm); 1746} 1747 1748#if STD_INSPIRED 1749 1750/* This function is obsolescent and may disappear in future releases. 1751 Callers can instead use localtime_rz with a fixed-offset zone. */ 1752 1753struct tm * 1754offtime(const time_t *timep, long offset) 1755{ 1756 gmtcheck(); 1757 1758#if !SUPPORT_C89 1759 static struct tm tm; 1760#endif 1761 return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm); 1762} 1763 1764struct tm * 1765offtime_r(const time_t *timep, long offset, struct tm *tmp) 1766{ 1767 gmtcheck(); 1768 return gmtsub(NULL, timep, (int_fast32_t)offset, tmp); 1769} 1770 1771#endif /* STD_INSPIRED */ 1772 1773#if TZ_TIME_T 1774 1775# if USG_COMPAT 1776# define daylight 0 1777# define timezone 0 1778# endif 1779# if !ALTZONE 1780# define altzone 0 1781# endif 1782 1783/* Convert from the underlying system's time_t to the ersatz time_tz, 1784 which is called 'time_t' in this file. Typically, this merely 1785 converts the time's integer width. On some platforms, the system 1786 time is local time not UT, or uses some epoch other than the POSIX 1787 epoch. 1788 1789 Although this code appears to define a function named 'time' that 1790 returns time_t, the macros in private.h cause this code to actually 1791 define a function named 'tz_time' that returns tz_time_t. The call 1792 to sys_time invokes the underlying system's 'time' function. */ 1793 1794time_t 1795time(time_t *p) 1796{ 1797 __time_t r = sys_time(0); 1798 if (r != (time_t) -1) { 1799 int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0; 1800 if (increment_overflow32(&offset, -EPOCH_OFFSET) 1801 || increment_overflow_time(&r, offset)) { 1802 errno = EOVERFLOW; 1803 r = -1; 1804 } 1805 } 1806 if (p) 1807 *p = (time_t)r; 1808 return (time_t)r; 1809} 1810#endif 1811 1812/* 1813** Return the number of leap years through the end of the given year 1814** where, to make the math easy, the answer for year zero is defined as zero. 1815*/ 1816 1817static time_t 1818leaps_thru_end_of_nonneg(time_t y) 1819{ 1820 return y / 4 - y / 100 + y / 400; 1821} 1822 1823static time_t 1824leaps_thru_end_of(time_t y) 1825{ 1826 return (y < 0 1827 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 1828 : leaps_thru_end_of_nonneg(y)); 1829} 1830 1831static struct tm * 1832timesub(const time_t *timep, int_fast32_t offset, 1833 const struct state *sp, struct tm *tmp) 1834{ 1835 register const struct lsinfo * lp; 1836 register time_t tdays; 1837 register const int * ip; 1838 register int_fast32_t corr; 1839 register int i; 1840 int_fast32_t idays, rem, dayoff, dayrem; 1841 time_t y; 1842 1843 /* If less than SECSPERMIN, the number of seconds since the 1844 most recent positive leap second; otherwise, do not add 1 1845 to localtime tm_sec because of leap seconds. */ 1846 __time_t secs_since_posleap = SECSPERMIN; 1847 1848 corr = 0; 1849 i = (sp == NULL) ? 0 : sp->leapcnt; 1850 while (--i >= 0) { 1851 lp = &sp->lsis[i]; 1852 if (*timep >= lp->ls_trans) { 1853 corr = lp->ls_corr; 1854 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 1855 secs_since_posleap = *timep - lp->ls_trans; 1856 break; 1857 } 1858 } 1859 1860 /* Calculate the year, avoiding integer overflow even if 1861 time_t is unsigned. */ 1862 tdays = (time_t)(*timep / SECSPERDAY); 1863 rem = (int)(*timep % SECSPERDAY); 1864 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 1865 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 1866 rem %= SECSPERDAY; 1867 /* y = (EPOCH_YEAR 1868 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 1869 sans overflow. But calculate against 1570 (EPOCH_YEAR - 1870 YEARSPERREPEAT) instead of against 1970 so that things work 1871 for localtime values before 1970 when time_t is unsigned. */ 1872 dayrem = (int)(tdays % DAYSPERREPEAT); 1873 dayrem += dayoff % DAYSPERREPEAT; 1874 y = (time_t)(EPOCH_YEAR - YEARSPERREPEAT 1875 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 1876 - ((dayrem % DAYSPERREPEAT) < 0) 1877 + tdays / DAYSPERREPEAT) 1878 * YEARSPERREPEAT)); 1879 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 1880 idays = (int)(tdays % DAYSPERREPEAT); 1881 idays += (dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT); 1882 idays %= DAYSPERREPEAT; 1883 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 1884 while (year_lengths[isleap(y)] <= idays) { 1885 int_fast32_t tdelta = idays / DAYSPERLYEAR; 1886 int_fast32_t ydelta = tdelta + !tdelta; 1887 time_t newy = (time_t)(y + ydelta); 1888 register int leapdays; 1889 leapdays = (int)(leaps_thru_end_of(newy - 1) - 1890 leaps_thru_end_of(y - 1)); 1891 idays -= ydelta * DAYSPERNYEAR; 1892 idays -= leapdays; 1893 y = newy; 1894 } 1895 1896#ifdef ckd_add 1897 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 1898 errno = EOVERFLOW; 1899 return NULL; 1900 } 1901#else 1902 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 1903 int signed_y = (int)y; 1904 tmp->tm_year = signed_y - TM_YEAR_BASE; 1905 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 1906 && y - TM_YEAR_BASE <= INT_MAX) 1907 tmp->tm_year = (int)(y - TM_YEAR_BASE); 1908 else { 1909 errno = EOVERFLOW; 1910 return NULL; 1911 } 1912#endif 1913 tmp->tm_yday = (int)idays; 1914 /* 1915 ** The "extra" mods below avoid overflow problems. 1916 */ 1917 tmp->tm_wday = (int)(TM_WDAY_BASE 1918 + ((tmp->tm_year % DAYSPERWEEK) 1919 * (DAYSPERNYEAR % DAYSPERWEEK)) 1920 + leaps_thru_end_of(y - 1) 1921 - leaps_thru_end_of(TM_YEAR_BASE - 1) 1922 + idays); 1923 tmp->tm_wday %= DAYSPERWEEK; 1924 if (tmp->tm_wday < 0) 1925 tmp->tm_wday += DAYSPERWEEK; 1926 tmp->tm_hour = (int) (rem / SECSPERHOUR); 1927 rem %= SECSPERHOUR; 1928 tmp->tm_min = (int)(rem / SECSPERMIN); 1929 tmp->tm_sec = (int)(rem % SECSPERMIN); 1930 1931 /* Use "... ??:??:60" at the end of the localtime minute containing 1932 the second just before the positive leap second. */ 1933 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 1934 1935 ip = mon_lengths[isleap(y)]; 1936 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 1937 idays -= ip[tmp->tm_mon]; 1938 tmp->tm_mday = (int)(idays + 1); 1939 tmp->tm_isdst = 0; 1940#ifdef TM_GMTOFF 1941 tmp->TM_GMTOFF = offset; 1942#endif /* defined TM_GMTOFF */ 1943 return tmp; 1944} 1945 1946/* 1947** Adapted from code provided by Robert Elz, who writes: 1948** The "best" way to do mktime I think is based on an idea of Bob 1949** Kridle's (so its said...) from a long time ago. 1950** It does a binary search of the time_t space. Since time_t's are 1951** just 32 bits, its a max of 32 iterations (even at 64 bits it 1952** would still be very reasonable). 1953*/ 1954 1955#ifndef WRONG 1956# define WRONG ((time_t)-1) 1957#endif /* !defined WRONG */ 1958 1959/* 1960** Normalize logic courtesy Paul Eggert. 1961*/ 1962 1963static bool 1964increment_overflow(int *ip, int j) 1965{ 1966#ifdef ckd_add 1967 return ckd_add(ip, *ip, j); 1968#else 1969 register int const i = *ip; 1970 1971 /* 1972 ** If i >= 0 there can only be overflow if i + j > INT_MAX 1973 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 1974 ** If i < 0 there can only be overflow if i + j < INT_MIN 1975 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 1976 */ 1977 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 1978 return true; 1979 *ip += j; 1980 return false; 1981#endif 1982} 1983 1984static bool 1985increment_overflow32(int_fast32_t *const lp, int const m) 1986{ 1987#ifdef ckd_add 1988 return ckd_add(lp, *lp, m); 1989#else 1990 register int_fast32_t const l = *lp; 1991 1992 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) 1993 return true; 1994 *lp += m; 1995 return false; 1996#endif 1997} 1998 1999static bool 2000increment_overflow_time(__time_t *tp, int_fast32_t j) 2001{ 2002#ifdef ckd_add 2003 return ckd_add(tp, *tp, j); 2004#else 2005 /* 2006 ** This is like 2007 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2008 ** except that it does the right thing even if *tp + j would overflow. 2009 */ 2010 if (! (j < 0 2011 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2012 : *tp <= TIME_T_MAX - j)) 2013 return true; 2014 *tp += j; 2015 return false; 2016#endif 2017} 2018 2019static bool 2020normalize_overflow(int *const tensptr, int *const unitsptr, const int base) 2021{ 2022 register int tensdelta; 2023 2024 tensdelta = (*unitsptr >= 0) ? 2025 (*unitsptr / base) : 2026 (-1 - (-1 - *unitsptr) / base); 2027 *unitsptr -= tensdelta * base; 2028 return increment_overflow(tensptr, tensdelta); 2029} 2030 2031static bool 2032normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base) 2033{ 2034 register int tensdelta; 2035 2036 tensdelta = (*unitsptr >= 0) ? 2037 (*unitsptr / base) : 2038 (-1 - (-1 - *unitsptr) / base); 2039 *unitsptr -= tensdelta * base; 2040 return increment_overflow32(tensptr, tensdelta); 2041} 2042 2043static int 2044tmcomp(register const struct tm *const atmp, 2045 register const struct tm *const btmp) 2046{ 2047 register int result; 2048 2049 if (atmp->tm_year != btmp->tm_year) 2050 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2051 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2052 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2053 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2054 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2055 result = atmp->tm_sec - btmp->tm_sec; 2056 return result; 2057} 2058 2059/* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2060 as other members might not be initialized. */ 2061static void 2062mktmcpy(struct tm *dest, struct tm const *src) 2063{ 2064 dest->tm_sec = src->tm_sec; 2065 dest->tm_min = src->tm_min; 2066 dest->tm_hour = src->tm_hour; 2067 dest->tm_mday = src->tm_mday; 2068 dest->tm_mon = src->tm_mon; 2069 dest->tm_year = src->tm_year; 2070 dest->tm_isdst = src->tm_isdst; 2071#if defined TM_GMTOFF && ! UNINIT_TRAP 2072 dest->TM_GMTOFF = src->TM_GMTOFF; 2073#endif 2074} 2075 2076static time_t 2077time2sub(struct tm *const tmp, 2078 struct tm *(*funcp)(struct state const *, time_t const *, 2079 int_fast32_t, struct tm *), 2080 struct state const *sp, 2081 const int_fast32_t offset, 2082 bool *okayp, 2083 bool do_norm_secs) 2084{ 2085 register int dir; 2086 register int i, j; 2087 register int saved_seconds; 2088 register int_fast32_t li; 2089 register time_t lo; 2090 register time_t hi; 2091#ifdef NO_ERROR_IN_DST_GAP 2092 time_t ilo; 2093#endif 2094 int_fast32_t y; 2095 time_t newt; 2096 time_t t; 2097 struct tm yourtm, mytm; 2098 2099 *okayp = false; 2100 mktmcpy(&yourtm, tmp); 2101 2102#ifdef NO_ERROR_IN_DST_GAP 2103again: 2104#endif 2105 if (do_norm_secs) { 2106 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 2107 SECSPERMIN)) 2108 goto out_of_range; 2109 } 2110 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 2111 goto out_of_range; 2112 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 2113 goto out_of_range; 2114 y = yourtm.tm_year; 2115 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) 2116 goto out_of_range; 2117 /* 2118 ** Turn y into an actual year number for now. 2119 ** It is converted back to an offset from TM_YEAR_BASE later. 2120 */ 2121 if (increment_overflow32(&y, TM_YEAR_BASE)) 2122 goto out_of_range; 2123 while (yourtm.tm_mday <= 0) { 2124 if (increment_overflow32(&y, -1)) 2125 goto out_of_range; 2126 li = y + (1 < yourtm.tm_mon); 2127 yourtm.tm_mday += year_lengths[isleap(li)]; 2128 } 2129 while (yourtm.tm_mday > DAYSPERLYEAR) { 2130 li = y + (1 < yourtm.tm_mon); 2131 yourtm.tm_mday -= year_lengths[isleap(li)]; 2132 if (increment_overflow32(&y, 1)) 2133 goto out_of_range; 2134 } 2135 for ( ; ; ) { 2136 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2137 if (yourtm.tm_mday <= i) 2138 break; 2139 yourtm.tm_mday -= i; 2140 if (++yourtm.tm_mon >= MONSPERYEAR) { 2141 yourtm.tm_mon = 0; 2142 if (increment_overflow32(&y, 1)) 2143 goto out_of_range; 2144 } 2145 } 2146#ifdef ckd_add 2147 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2148 return WRONG; 2149#else 2150 if (increment_overflow32(&y, -TM_YEAR_BASE)) 2151 goto out_of_range; 2152 if (! (INT_MIN <= y && y <= INT_MAX)) 2153 goto out_of_range; 2154 yourtm.tm_year = (int)y; 2155#endif 2156 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2157 saved_seconds = 0; 2158 else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { 2159 /* 2160 ** We can't set tm_sec to 0, because that might push the 2161 ** time below the minimum representable time. 2162 ** Set tm_sec to 59 instead. 2163 ** This assumes that the minimum representable time is 2164 ** not in the same minute that a leap second was deleted from, 2165 ** which is a safer assumption than using 58 would be. 2166 */ 2167 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 2168 goto out_of_range; 2169 saved_seconds = yourtm.tm_sec; 2170 yourtm.tm_sec = SECSPERMIN - 1; 2171 } else { 2172 saved_seconds = yourtm.tm_sec; 2173 yourtm.tm_sec = 0; 2174 } 2175 /* 2176 ** Do a binary search (this works whatever time_t's type is). 2177 */ 2178 lo = TIME_T_MIN; 2179 hi = TIME_T_MAX; 2180#ifdef NO_ERROR_IN_DST_GAP 2181 ilo = lo; 2182#endif 2183 for ( ; ; ) { 2184 t = lo / 2 + hi / 2; 2185 if (t < lo) 2186 t = lo; 2187 else if (t > hi) 2188 t = hi; 2189 if (! funcp(sp, &t, offset, &mytm)) { 2190 /* 2191 ** Assume that t is too extreme to be represented in 2192 ** a struct tm; arrange things so that it is less 2193 ** extreme on the next pass. 2194 */ 2195 dir = (t > 0) ? 1 : -1; 2196 } else dir = tmcomp(&mytm, &yourtm); 2197 if (dir != 0) { 2198 if (t == lo) { 2199 if (t == TIME_T_MAX) 2200 goto out_of_range; 2201 ++t; 2202 ++lo; 2203 } else if (t == hi) { 2204 if (t == TIME_T_MIN) 2205 goto out_of_range; 2206 --t; 2207 --hi; 2208 } 2209#ifdef NO_ERROR_IN_DST_GAP 2210 if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 && 2211 do_norm_secs) { 2212 for (i = sp->typecnt - 1; i >= 0; --i) { 2213 for (j = sp->typecnt - 1; j >= 0; --j) { 2214 time_t off; 2215 if (sp->ttis[j].tt_isdst == 2216 sp->ttis[i].tt_isdst) 2217 continue; 2218 if (ttunspecified(sp, j)) 2219 continue; 2220 off = sp->ttis[j].tt_utoff - 2221 sp->ttis[i].tt_utoff; 2222 yourtm.tm_sec += off < 0 ? 2223 -off : off; 2224 goto again; 2225 } 2226 } 2227 } 2228#endif 2229 if (lo > hi) 2230 goto invalid; 2231 if (dir > 0) 2232 hi = t; 2233 else lo = t; 2234 continue; 2235 } 2236#if defined TM_GMTOFF && ! UNINIT_TRAP 2237 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2238 && (yourtm.TM_GMTOFF < 0 2239 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2240 && (mytm.TM_GMTOFF <= 2241 /*CONSTCOND*/ 2242 (min(INT_FAST32_MAX, LONG_MAX) 2243 + yourtm.TM_GMTOFF))) 2244 : (yourtm.TM_GMTOFF <= SECSPERDAY 2245 /*CONSTCOND*/ 2246 && ((max(INT_FAST32_MIN, LONG_MIN) 2247 + yourtm.TM_GMTOFF) 2248 <= mytm.TM_GMTOFF)))) { 2249 /* MYTM matches YOURTM except with the wrong UT offset. 2250 YOURTM.TM_GMTOFF is plausible, so try it instead. 2251 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2252 since the guess gets checked. */ 2253 __time_t altt = t; 2254 int_fast32_t diff = (int_fast32_t) 2255 (mytm.TM_GMTOFF - yourtm.TM_GMTOFF); 2256 if (!increment_overflow_time(&altt, diff)) { 2257 struct tm alttm; 2258 time_t xaltt = (time_t)altt; 2259 if (funcp(sp, &xaltt, offset, &alttm) 2260 && alttm.tm_isdst == mytm.tm_isdst 2261 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2262 && tmcomp(&alttm, &yourtm) == 0) { 2263 t = xaltt; 2264 mytm = alttm; 2265 } 2266 } 2267 } 2268#endif 2269 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2270 break; 2271 /* 2272 ** Right time, wrong type. 2273 ** Hunt for right time, right type. 2274 ** It's okay to guess wrong since the guess 2275 ** gets checked. 2276 */ 2277 if (sp == NULL) 2278 goto invalid; 2279 for (i = sp->typecnt - 1; i >= 0; --i) { 2280 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2281 continue; 2282 for (j = sp->typecnt - 1; j >= 0; --j) { 2283 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2284 continue; 2285 newt = (time_t)(t + sp->ttis[j].tt_utoff - 2286 sp->ttis[i].tt_utoff); 2287 if (! funcp(sp, &newt, offset, &mytm)) 2288 continue; 2289 if (tmcomp(&mytm, &yourtm) != 0) 2290 continue; 2291 if (mytm.tm_isdst != yourtm.tm_isdst) 2292 continue; 2293 /* 2294 ** We have a match. 2295 */ 2296 t = newt; 2297 goto label; 2298 } 2299 } 2300 goto invalid; 2301 } 2302label: 2303 newt = t + saved_seconds; 2304 if ((newt < t) != (saved_seconds < 0)) 2305 goto out_of_range; 2306 t = newt; 2307 if (funcp(sp, &t, offset, tmp)) { 2308 *okayp = true; 2309 return t; 2310 } 2311out_of_range: 2312 errno = EOVERFLOW; 2313 return WRONG; 2314invalid: 2315 errno = EINVAL; 2316 return WRONG; 2317} 2318 2319static time_t 2320time2(struct tm * const tmp, 2321 struct tm *(*funcp)(struct state const *, time_t const *, 2322 int_fast32_t, struct tm *), 2323 struct state const *sp, 2324 const int_fast32_t offset, 2325 bool *okayp) 2326{ 2327 time_t t; 2328 2329 /* 2330 ** First try without normalization of seconds 2331 ** (in case tm_sec contains a value associated with a leap second). 2332 ** If that fails, try with normalization of seconds. 2333 */ 2334 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2335 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2336} 2337 2338static time_t 2339time1(struct tm *const tmp, 2340 struct tm *(*funcp)(struct state const *, time_t const *, 2341 int_fast32_t, struct tm *), 2342 struct state const *sp, 2343 const int_fast32_t offset) 2344{ 2345 register time_t t; 2346 register int samei, otheri; 2347 register int sameind, otherind; 2348 register int i; 2349 register int nseen; 2350 int save_errno; 2351 char seen[TZ_MAX_TYPES]; 2352 unsigned char types[TZ_MAX_TYPES]; 2353 bool okay; 2354 2355 if (tmp == NULL) { 2356 errno = EINVAL; 2357 return WRONG; 2358 } 2359 if (tmp->tm_isdst > 1) 2360 tmp->tm_isdst = 1; 2361 save_errno = errno; 2362 t = time2(tmp, funcp, sp, offset, &okay); 2363 if (okay) { 2364 errno = save_errno; 2365 return t; 2366 } 2367 if (tmp->tm_isdst < 0) 2368#ifdef PCTS 2369 /* 2370 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2371 */ 2372 tmp->tm_isdst = 0; /* reset to std and try again */ 2373#else 2374 return t; 2375#endif /* !defined PCTS */ 2376 /* 2377 ** We're supposed to assume that somebody took a time of one type 2378 ** and did some math on it that yielded a "struct tm" that's bad. 2379 ** We try to divine the type they started from and adjust to the 2380 ** type they need. 2381 */ 2382 if (sp == NULL) { 2383 errno = EINVAL; 2384 return WRONG; 2385 } 2386 for (i = 0; i < sp->typecnt; ++i) 2387 seen[i] = false; 2388 nseen = 0; 2389 for (i = sp->timecnt - 1; i >= 0; --i) 2390 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2391 seen[sp->types[i]] = true; 2392 types[nseen++] = sp->types[i]; 2393 } 2394 for (sameind = 0; sameind < nseen; ++sameind) { 2395 samei = types[sameind]; 2396 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2397 continue; 2398 for (otherind = 0; otherind < nseen; ++otherind) { 2399 otheri = types[otherind]; 2400 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2401 continue; 2402 tmp->tm_sec += (int)(sp->ttis[otheri].tt_utoff 2403 - sp->ttis[samei].tt_utoff); 2404 tmp->tm_isdst = !tmp->tm_isdst; 2405 t = time2(tmp, funcp, sp, offset, &okay); 2406 if (okay) { 2407 errno = save_errno; 2408 return t; 2409 } 2410 tmp->tm_sec -= (int)(sp->ttis[otheri].tt_utoff 2411 - sp->ttis[samei].tt_utoff); 2412 tmp->tm_isdst = !tmp->tm_isdst; 2413 } 2414 } 2415 errno = EOVERFLOW; 2416 return WRONG; 2417} 2418 2419static time_t 2420mktime_tzname(timezone_t sp, struct tm *tmp, bool setname) 2421{ 2422 if (sp) 2423 return time1(tmp, localsub, sp, setname); 2424 else { 2425 gmtcheck(); 2426 return time1(tmp, gmtsub, gmtptr, 0); 2427 } 2428} 2429 2430#if NETBSD_INSPIRED 2431 2432time_t 2433mktime_z(struct state *__restrict sp, struct tm *__restrict tmp) 2434{ 2435 return mktime_tzname(sp, tmp, false); 2436} 2437 2438#endif 2439 2440time_t 2441mktime(struct tm *tmp) 2442{ 2443 time_t t; 2444 2445 rwlock_wrlock(&__lcl_lock); 2446 tzset_unlocked(); 2447 t = mktime_tzname(__lclptr, tmp, true); 2448 rwlock_unlock(&__lcl_lock); 2449 return t; 2450} 2451 2452#if STD_INSPIRED 2453/* This function is obsolescent and may disapper in future releases. 2454 Callers can instead use mktime. */ 2455time_t 2456timelocal_z(const timezone_t sp, struct tm *const tmp) 2457{ 2458 if (tmp != NULL) 2459 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2460 return mktime_z(sp, tmp); 2461} 2462 2463time_t 2464timelocal(struct tm *tmp) 2465{ 2466 if (tmp != NULL) 2467 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2468 return mktime(tmp); 2469} 2470#endif 2471 2472#ifndef EXTERN_TIMEOFF 2473# ifndef timeoff 2474# define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2475# endif 2476# define EXTERN_TIMEOFF static 2477#endif 2478 2479/* This function is obsolescent and may disapper in future releases. 2480 Callers can instead use mktime_z with a fixed-offset zone. */ 2481EXTERN_TIMEOFF time_t 2482timeoff(struct tm *tmp, long offset) 2483{ 2484 if (tmp) 2485 tmp->tm_isdst = 0; 2486 gmtcheck(); 2487 return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset); 2488} 2489 2490time_t 2491timegm(struct tm *tmp) 2492{ 2493 time_t t; 2494 struct tm tmcpy; 2495 mktmcpy(&tmcpy, tmp); 2496 tmcpy.tm_wday = -1; 2497 t = timeoff(&tmcpy, 0); 2498 if (0 <= tmcpy.tm_wday) 2499 *tmp = tmcpy; 2500 return t; 2501} 2502 2503static int_fast32_t 2504leapcorr(struct state const *sp, __time_t t) 2505{ 2506 register struct lsinfo const * lp; 2507 register int i; 2508 2509 i = sp->leapcnt; 2510 while (--i >= 0) { 2511 lp = &sp->lsis[i]; 2512 if (t >= lp->ls_trans) 2513 return lp->ls_corr; 2514 } 2515 return 0; 2516} 2517 2518/* NETBSD_INSPIRED_EXTERN functions are exported to callers if 2519 NETBSD_INSPIRED is defined, and are private otherwise. */ 2520# if NETBSD_INSPIRED 2521# define NETBSD_INSPIRED_EXTERN 2522# else 2523# define NETBSD_INSPIRED_EXTERN static 2524# endif 2525 2526/* 2527** IEEE Std 1003.1 (POSIX) says that 536457599 2528** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2529** is not the case if we are accounting for leap seconds. 2530** So, we provide the following conversion routines for use 2531** when exchanging timestamps with POSIX conforming systems. 2532*/ 2533 2534NETBSD_INSPIRED_EXTERN time_t 2535time2posix_z(timezone_t sp, time_t t) 2536{ 2537 return (time_t)(t - leapcorr(sp, t)); 2538} 2539 2540time_t 2541time2posix(time_t t) 2542{ 2543 rwlock_wrlock(&__lcl_lock); 2544 if (!lcl_is_set) 2545 tzset_unlocked(); 2546 if (__lclptr) 2547 t = (time_t)(t - leapcorr(__lclptr, t)); 2548 rwlock_unlock(&__lcl_lock); 2549 return t; 2550} 2551 2552/* 2553** XXX--is the below the right way to conditionalize?? 2554*/ 2555 2556#if STD_INSPIRED 2557 2558NETBSD_INSPIRED_EXTERN time_t 2559posix2time_z(timezone_t sp, time_t t) 2560{ 2561 time_t x; 2562 time_t y; 2563 /* 2564 ** For a positive leap second hit, the result 2565 ** is not unique. For a negative leap second 2566 ** hit, the corresponding time doesn't exist, 2567 ** so we return an adjacent second. 2568 */ 2569 x = (time_t)(t + leapcorr(sp, t)); 2570 y = (time_t)(x - leapcorr(sp, x)); 2571 if (y < t) { 2572 do { 2573 x++; 2574 y = (time_t)(x - leapcorr(sp, x)); 2575 } while (y < t); 2576 x -= y != t; 2577 } else if (y > t) { 2578 do { 2579 --x; 2580 y = (time_t)(x - leapcorr(sp, x)); 2581 } while (y > t); 2582 x += y != t; 2583 } 2584 return x; 2585} 2586 2587time_t 2588posix2time(time_t t) 2589{ 2590 rwlock_wrlock(&__lcl_lock); 2591 if (!lcl_is_set) 2592 tzset_unlocked(); 2593 if (__lclptr) 2594 t = posix2time_z(__lclptr, t); 2595 rwlock_unlock(&__lcl_lock); 2596 return t; 2597} 2598 2599#endif /* defined STD_INSPIRED */ 2600