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