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 time_t janfirst1 = janfirst; 1250 yearbeg--; 1251 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1252 janoffset = -yearsecs; 1253 break; 1254 } 1255 janfirst = janfirst1; 1256 } while (atlo < janfirst 1257 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1258 1259 while (true) { 1260 int_fast32_t yearsecs 1261 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1262 int yearbeg1 = yearbeg; 1263 time_t janfirst1 = janfirst; 1264 if (increment_overflow_time(&janfirst1, yearsecs) 1265 || increment_overflow(&yearbeg1, 1) 1266 || atlo <= janfirst1) 1267 break; 1268 yearbeg = yearbeg1; 1269 janfirst = janfirst1; 1270 } 1271 1272 yearlim = yearbeg; 1273 if (increment_overflow(&yearlim, years_of_observations)) 1274 yearlim = INT_MAX; 1275 for (year = yearbeg; year < yearlim; year++) { 1276 int_fast32_t 1277 starttime = transtime(year, &start, stdoffset), 1278 endtime = transtime(year, &end, dstoffset); 1279 int_fast32_t 1280 yearsecs = (year_lengths[isleap(year)] 1281 * SECSPERDAY); 1282 bool reversed = endtime < starttime; 1283 if (reversed) { 1284 int_fast32_t swap = starttime; 1285 starttime = endtime; 1286 endtime = swap; 1287 } 1288 if (reversed 1289 || (starttime < endtime 1290 && endtime - starttime < yearsecs)) { 1291 if (TZ_MAX_TIMES - 2 < timecnt) 1292 break; 1293 sp->ats[timecnt] = janfirst; 1294 if (! increment_overflow_time 1295 (&sp->ats[timecnt], 1296 janoffset + starttime) 1297 && atlo <= sp->ats[timecnt]) 1298 sp->types[timecnt++] = !reversed; 1299 sp->ats[timecnt] = janfirst; 1300 if (! increment_overflow_time 1301 (&sp->ats[timecnt], 1302 janoffset + endtime) 1303 && atlo <= sp->ats[timecnt]) { 1304 sp->types[timecnt++] = reversed; 1305 } 1306 } 1307 if (endtime < leaplo) { 1308 yearlim = year; 1309 if (increment_overflow(&yearlim, 1310 years_of_observations)) 1311 yearlim = INT_MAX; 1312 } 1313 if (increment_overflow_time 1314 (&janfirst, janoffset + yearsecs)) 1315 break; 1316 janoffset = 0; 1317 } 1318 sp->timecnt = timecnt; 1319 if (! timecnt) { 1320 sp->ttis[0] = sp->ttis[1]; 1321 sp->typecnt = 1; /* Perpetual DST. */ 1322 } else if (years_of_observations <= year - yearbeg) 1323 sp->goback = sp->goahead = true; 1324 } else { 1325 register int_fast32_t theirstdoffset; 1326 register int_fast32_t theirdstoffset; 1327 register int_fast32_t theiroffset; 1328 register bool isdst; 1329 register int i; 1330 register int j; 1331 1332 if (*name != '\0') 1333 return false; 1334 /* 1335 ** Initial values of theirstdoffset and theirdstoffset. 1336 */ 1337 theirstdoffset = 0; 1338 for (i = 0; i < sp->timecnt; ++i) { 1339 j = sp->types[i]; 1340 if (!sp->ttis[j].tt_isdst) { 1341 theirstdoffset = 1342 - sp->ttis[j].tt_utoff; 1343 break; 1344 } 1345 } 1346 theirdstoffset = 0; 1347 for (i = 0; i < sp->timecnt; ++i) { 1348 j = sp->types[i]; 1349 if (sp->ttis[j].tt_isdst) { 1350 theirdstoffset = 1351 - sp->ttis[j].tt_utoff; 1352 break; 1353 } 1354 } 1355 /* 1356 ** Initially we're assumed to be in standard time. 1357 */ 1358 isdst = false; 1359 /* 1360 ** Now juggle transition times and types 1361 ** tracking offsets as you do. 1362 */ 1363 for (i = 0; i < sp->timecnt; ++i) { 1364 j = sp->types[i]; 1365 sp->types[i] = sp->ttis[j].tt_isdst; 1366 if (sp->ttis[j].tt_ttisut) { 1367 /* No adjustment to transition time */ 1368 } else { 1369 /* 1370 ** If daylight saving time is in 1371 ** effect, and the transition time was 1372 ** not specified as standard time, add 1373 ** the daylight saving time offset to 1374 ** the transition time; otherwise, add 1375 ** the standard time offset to the 1376 ** transition time. 1377 */ 1378 /* 1379 ** Transitions from DST to DDST 1380 ** will effectively disappear since 1381 ** POSIX.1-2017 provides for only one 1382 ** DST offset. 1383 */ 1384 if (isdst && !sp->ttis[j].tt_ttisstd) { 1385 sp->ats[i] += dstoffset - 1386 theirdstoffset; 1387 } else { 1388 sp->ats[i] += stdoffset - 1389 theirstdoffset; 1390 } 1391 } 1392 theiroffset = -sp->ttis[j].tt_utoff; 1393 if (sp->ttis[j].tt_isdst) 1394 theirdstoffset = theiroffset; 1395 else theirstdoffset = theiroffset; 1396 } 1397 /* 1398 ** Finally, fill in ttis. 1399 */ 1400 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1401 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1402 sp->typecnt = 2; 1403 } 1404 } else { 1405 dstlen = 0; 1406 sp->typecnt = 1; /* only standard time */ 1407 sp->timecnt = 0; 1408 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1409 } 1410 sp->defaulttype = 0; 1411 sp->charcnt = charcnt; 1412 cp = sp->chars; 1413 memcpy(cp, stdname, stdlen); 1414 cp += stdlen; 1415 *cp++ = '\0'; 1416 if (dstlen != 0) { 1417 memcpy(cp, dstname, dstlen); 1418 *(cp + dstlen) = '\0'; 1419 } 1420 return true; 1421 } 1422 1423 static void 1424 gmtload(struct state *const sp) 1425 { 1426 if (tzload(etc_utc, sp, true) != 0) 1427 tzparse("UTC0", sp, NULL); 1428 } 1429 1430 #ifdef DETECT_TZ_CHANGES 1431 static int 1432 recheck_tzdata() 1433 { 1434 static time_t last_checked; 1435 struct timespec now; 1436 time_t current_time; 1437 int error; 1438 1439 /* 1440 * We want to recheck the timezone file every 61 sec. 1441 */ 1442 error = clock_gettime(CLOCK_MONOTONIC, &now); 1443 if (error < 0) { 1444 /* XXX: Can we somehow report this? */ 1445 return 0; 1446 } 1447 1448 current_time = now.tv_sec; 1449 if ((current_time - last_checked > DETECT_TZ_CHANGES_INTERVAL) || 1450 (last_checked > current_time)) { 1451 last_checked = current_time; 1452 return 1; 1453 } 1454 1455 return 0; 1456 } 1457 #else /* !DETECT_TZ_CHANGES */ 1458 #define recheck_tzdata() 0 1459 #endif /* !DETECT_TZ_CHANGES */ 1460 1461 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1462 Return 0 on success, an errno value on failure. */ 1463 static int 1464 zoneinit(struct state *sp, char const *name) 1465 { 1466 if (name && ! name[0]) { 1467 /* 1468 ** User wants it fast rather than right. 1469 */ 1470 sp->leapcnt = 0; /* so, we're off a little */ 1471 sp->timecnt = 0; 1472 sp->typecnt = 0; 1473 sp->charcnt = 0; 1474 sp->goback = sp->goahead = false; 1475 init_ttinfo(&sp->ttis[0], 0, false, 0); 1476 strcpy(sp->chars, utc); 1477 sp->defaulttype = 0; 1478 return 0; 1479 } else { 1480 int err = tzload(name, sp, true); 1481 if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) 1482 err = 0; 1483 if (err == 0) 1484 err = scrub_abbrs(sp); 1485 return err; 1486 } 1487 } 1488 1489 static void 1490 tzset_unlocked_name(char const *name) 1491 { 1492 struct state *sp = lclptr; 1493 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1494 if (lcl < 0 1495 ? lcl_is_set < 0 1496 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1497 if (recheck_tzdata() == 0) 1498 return; 1499 #ifdef ALL_STATE 1500 if (! sp) 1501 lclptr = sp = malloc(sizeof *lclptr); 1502 #endif /* defined ALL_STATE */ 1503 if (sp) { 1504 if (zoneinit(sp, name) != 0) 1505 zoneinit(sp, ""); 1506 if (0 < lcl) 1507 strcpy(lcl_TZname, name); 1508 } 1509 settzname(); 1510 lcl_is_set = lcl; 1511 } 1512 1513 static void 1514 tzset_unlocked(void) 1515 { 1516 tzset_unlocked_name(getenv("TZ")); 1517 } 1518 1519 void 1520 tzset(void) 1521 { 1522 if (lock() != 0) 1523 return; 1524 tzset_unlocked(); 1525 unlock(); 1526 } 1527 1528 void 1529 freebsd13_tzsetwall(void) 1530 { 1531 if (lock() != 0) 1532 return; 1533 tzset_unlocked_name(NULL); 1534 unlock(); 1535 } 1536 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 1537 __warn_references(tzsetwall, 1538 "warning: tzsetwall() is deprecated, use tzset() instead."); 1539 1540 static void 1541 gmtcheck(void) 1542 { 1543 static bool gmt_is_set; 1544 if (lock() != 0) 1545 return; 1546 if (! gmt_is_set) { 1547 #ifdef ALL_STATE 1548 gmtptr = malloc(sizeof *gmtptr); 1549 #endif 1550 if (gmtptr) 1551 gmtload(gmtptr); 1552 gmt_is_set = true; 1553 } 1554 unlock(); 1555 } 1556 1557 #if NETBSD_INSPIRED 1558 1559 timezone_t 1560 tzalloc(char const *name) 1561 { 1562 timezone_t sp = malloc(sizeof *sp); 1563 if (sp) { 1564 int err = zoneinit(sp, name); 1565 if (err != 0) { 1566 free(sp); 1567 errno = err; 1568 return NULL; 1569 } 1570 } else if (!HAVE_MALLOC_ERRNO) 1571 errno = ENOMEM; 1572 return sp; 1573 } 1574 1575 void 1576 tzfree(timezone_t sp) 1577 { 1578 free(sp); 1579 } 1580 1581 /* 1582 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and 1583 ** ctime_r are obsolescent and have potential security problems that 1584 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1585 ** 1586 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1587 ** in zones with three or more time zone abbreviations. 1588 ** Callers can instead use localtime_rz + strftime. 1589 */ 1590 1591 #endif 1592 1593 /* 1594 ** The easy way to behave "as if no library function calls" localtime 1595 ** is to not call it, so we drop its guts into "localsub", which can be 1596 ** freely called. (And no, the PANS doesn't require the above behavior, 1597 ** but it *is* desirable.) 1598 ** 1599 ** If successful and SETNAME is nonzero, 1600 ** set the applicable parts of tzname, timezone and altzone; 1601 ** however, it's OK to omit this step 1602 ** if the timezone is compatible with POSIX.1-2017 1603 ** since in that case tzset should have already done this step correctly. 1604 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1605 ** but it is actually a boolean and its value should be 0 or 1. 1606 */ 1607 1608 /*ARGSUSED*/ 1609 static struct tm * 1610 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1611 struct tm *const tmp) 1612 { 1613 register const struct ttinfo * ttisp; 1614 register int i; 1615 register struct tm * result; 1616 const time_t t = *timep; 1617 1618 if (sp == NULL) { 1619 /* Don't bother to set tzname etc.; tzset has already done it. */ 1620 return gmtsub(gmtptr, timep, 0, tmp); 1621 } 1622 if ((sp->goback && t < sp->ats[0]) || 1623 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1624 time_t newt; 1625 register time_t seconds; 1626 register time_t years; 1627 1628 if (t < sp->ats[0]) 1629 seconds = sp->ats[0] - t; 1630 else seconds = t - sp->ats[sp->timecnt - 1]; 1631 --seconds; 1632 1633 /* Beware integer overflow, as SECONDS might 1634 be close to the maximum time_t. */ 1635 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 1636 seconds = years * AVGSECSPERYEAR; 1637 years += YEARSPERREPEAT; 1638 if (t < sp->ats[0]) 1639 newt = t + seconds + SECSPERREPEAT; 1640 else 1641 newt = t - seconds - SECSPERREPEAT; 1642 1643 if (newt < sp->ats[0] || 1644 newt > sp->ats[sp->timecnt - 1]) 1645 return NULL; /* "cannot happen" */ 1646 result = localsub(sp, &newt, setname, tmp); 1647 if (result) { 1648 #if defined ckd_add && defined ckd_sub 1649 if (t < sp->ats[0] 1650 ? ckd_sub(&result->tm_year, 1651 result->tm_year, years) 1652 : ckd_add(&result->tm_year, 1653 result->tm_year, years)) 1654 return NULL; 1655 #else 1656 register int_fast64_t newy; 1657 1658 newy = result->tm_year; 1659 if (t < sp->ats[0]) 1660 newy -= years; 1661 else newy += years; 1662 if (! (INT_MIN <= newy && newy <= INT_MAX)) 1663 return NULL; 1664 result->tm_year = newy; 1665 #endif 1666 } 1667 return result; 1668 } 1669 if (sp->timecnt == 0 || t < sp->ats[0]) { 1670 i = sp->defaulttype; 1671 } else { 1672 register int lo = 1; 1673 register int hi = sp->timecnt; 1674 1675 while (lo < hi) { 1676 register int mid = (lo + hi) >> 1; 1677 1678 if (t < sp->ats[mid]) 1679 hi = mid; 1680 else lo = mid + 1; 1681 } 1682 i = sp->types[lo - 1]; 1683 } 1684 ttisp = &sp->ttis[i]; 1685 /* 1686 ** To get (wrong) behavior that's compatible with System V Release 2.0 1687 ** you'd replace the statement below with 1688 ** t += ttisp->tt_utoff; 1689 ** timesub(&t, 0L, sp, tmp); 1690 */ 1691 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1692 if (result) { 1693 result->tm_isdst = ttisp->tt_isdst; 1694 #ifdef TM_ZONE 1695 result->TM_ZONE = (char *) &sp->chars[ttisp->tt_desigidx]; 1696 #endif /* defined TM_ZONE */ 1697 if (setname) 1698 update_tzname_etc(sp, ttisp); 1699 } 1700 return result; 1701 } 1702 1703 #if NETBSD_INSPIRED 1704 1705 struct tm * 1706 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 1707 struct tm *restrict tmp) 1708 { 1709 return localsub(sp, timep, 0, tmp); 1710 } 1711 1712 #endif 1713 1714 static struct tm * 1715 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1716 { 1717 int err = lock(); 1718 if (err) { 1719 errno = err; 1720 return NULL; 1721 } 1722 #ifndef DETECT_TZ_CHANGES 1723 if (setname || !lcl_is_set) 1724 #endif 1725 tzset_unlocked(); 1726 tmp = localsub(lclptr, timep, setname, tmp); 1727 unlock(); 1728 return tmp; 1729 } 1730 1731 static void 1732 localtime_key_init(void) 1733 { 1734 1735 localtime_key_error = _pthread_key_create(&localtime_key, free); 1736 } 1737 1738 struct tm * 1739 localtime(const time_t *timep) 1740 { 1741 #if !SUPPORT_C89 1742 static struct tm tm; 1743 #endif 1744 struct tm *p_tm = &tm; 1745 1746 if (__isthreaded != 0) { 1747 _pthread_once(&localtime_once, localtime_key_init); 1748 if (localtime_key_error != 0) { 1749 errno = localtime_key_error; 1750 return (NULL); 1751 } 1752 if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { 1753 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1754 return (NULL); 1755 } 1756 if (_pthread_setspecific(localtime_key, p_tm) != 0) { 1757 free(p_tm); 1758 return (NULL); 1759 } 1760 } 1761 } 1762 return localtime_tzset(timep, p_tm, true); 1763 } 1764 1765 struct tm * 1766 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 1767 { 1768 return localtime_tzset(timep, tmp, false); 1769 } 1770 1771 /* 1772 ** gmtsub is to gmtime as localsub is to localtime. 1773 */ 1774 1775 static struct tm * 1776 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1777 int_fast32_t offset, struct tm *tmp) 1778 { 1779 register struct tm * result; 1780 1781 result = timesub(timep, offset, gmtptr, tmp); 1782 #ifdef TM_ZONE 1783 /* 1784 ** Could get fancy here and deliver something such as 1785 ** "+xx" or "-xx" if offset is non-zero, 1786 ** but this is no time for a treasure hunt. 1787 */ 1788 tmp->TM_ZONE = ((char *) 1789 (offset ? wildabbr : gmtptr ? gmtptr->chars : utc)); 1790 #endif /* defined TM_ZONE */ 1791 return result; 1792 } 1793 1794 /* 1795 * Re-entrant version of gmtime. 1796 */ 1797 1798 struct tm * 1799 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 1800 { 1801 _once(&gmt_once, gmtcheck); 1802 return gmtsub(gmtptr, timep, 0, tmp); 1803 } 1804 1805 static void 1806 gmtime_key_init(void) 1807 { 1808 1809 gmtime_key_error = _pthread_key_create(&gmtime_key, free); 1810 } 1811 1812 struct tm * 1813 gmtime(const time_t *timep) 1814 { 1815 #if !SUPPORT_C89 1816 static struct tm tm; 1817 #endif 1818 struct tm *p_tm = &tm; 1819 1820 if (__isthreaded != 0) { 1821 _pthread_once(&gmtime_once, gmtime_key_init); 1822 if (gmtime_key_error != 0) { 1823 errno = gmtime_key_error; 1824 return (NULL); 1825 } 1826 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { 1827 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1828 return (NULL); 1829 } 1830 if (_pthread_setspecific(gmtime_key, p_tm) != 0) { 1831 free(p_tm); 1832 return (NULL); 1833 } 1834 } 1835 } 1836 return gmtime_r(timep, p_tm); 1837 } 1838 1839 #if STD_INSPIRED 1840 1841 /* This function is obsolescent and may disappear in future releases. 1842 Callers can instead use localtime_rz with a fixed-offset zone. */ 1843 1844 struct tm * 1845 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 1846 { 1847 _once(&gmt_once, gmtcheck); 1848 return gmtsub(gmtptr, timep, offset, tmp); 1849 } 1850 1851 static void 1852 offtime_key_init(void) 1853 { 1854 1855 offtime_key_error = _pthread_key_create(&offtime_key, free); 1856 } 1857 1858 struct tm * 1859 offtime(const time_t *timep, long offset) 1860 { 1861 #if !SUPPORT_C89 1862 static struct tm tm; 1863 #endif 1864 struct tm *p_tm = &tm; 1865 1866 if (__isthreaded != 0) { 1867 _pthread_once(&offtime_once, offtime_key_init); 1868 if (offtime_key_error != 0) { 1869 errno = offtime_key_error; 1870 return (NULL); 1871 } 1872 if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) { 1873 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1874 return (NULL); 1875 } 1876 if (_pthread_setspecific(offtime_key, p_tm) != 0) { 1877 free(p_tm); 1878 return (NULL); 1879 } 1880 } 1881 } 1882 return offtime_r(timep, offset, p_tm); 1883 } 1884 1885 #endif 1886 1887 /* 1888 ** Return the number of leap years through the end of the given year 1889 ** where, to make the math easy, the answer for year zero is defined as zero. 1890 */ 1891 1892 static time_t 1893 leaps_thru_end_of_nonneg(time_t y) 1894 { 1895 return y / 4 - y / 100 + y / 400; 1896 } 1897 1898 static time_t 1899 leaps_thru_end_of(time_t y) 1900 { 1901 return (y < 0 1902 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 1903 : leaps_thru_end_of_nonneg(y)); 1904 } 1905 1906 static struct tm * 1907 timesub(const time_t *timep, int_fast32_t offset, 1908 const struct state *sp, struct tm *tmp) 1909 { 1910 register const struct lsinfo * lp; 1911 register time_t tdays; 1912 register const int * ip; 1913 register int_fast32_t corr; 1914 register int i; 1915 int_fast32_t idays, rem, dayoff, dayrem; 1916 time_t y; 1917 1918 /* If less than SECSPERMIN, the number of seconds since the 1919 most recent positive leap second; otherwise, do not add 1 1920 to localtime tm_sec because of leap seconds. */ 1921 time_t secs_since_posleap = SECSPERMIN; 1922 1923 corr = 0; 1924 i = (sp == NULL) ? 0 : sp->leapcnt; 1925 while (--i >= 0) { 1926 lp = &sp->lsis[i]; 1927 if (*timep >= lp->ls_trans) { 1928 corr = lp->ls_corr; 1929 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 1930 secs_since_posleap = *timep - lp->ls_trans; 1931 break; 1932 } 1933 } 1934 1935 /* Calculate the year, avoiding integer overflow even if 1936 time_t is unsigned. */ 1937 tdays = *timep / SECSPERDAY; 1938 rem = *timep % SECSPERDAY; 1939 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 1940 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 1941 rem %= SECSPERDAY; 1942 /* y = (EPOCH_YEAR 1943 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 1944 sans overflow. But calculate against 1570 (EPOCH_YEAR - 1945 YEARSPERREPEAT) instead of against 1970 so that things work 1946 for localtime values before 1970 when time_t is unsigned. */ 1947 dayrem = tdays % DAYSPERREPEAT; 1948 dayrem += dayoff % DAYSPERREPEAT; 1949 y = (EPOCH_YEAR - YEARSPERREPEAT 1950 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 1951 - ((dayrem % DAYSPERREPEAT) < 0) 1952 + tdays / DAYSPERREPEAT) 1953 * YEARSPERREPEAT)); 1954 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 1955 idays = tdays % DAYSPERREPEAT; 1956 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 1957 idays %= DAYSPERREPEAT; 1958 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 1959 while (year_lengths[isleap(y)] <= idays) { 1960 int tdelta = idays / DAYSPERLYEAR; 1961 int_fast32_t ydelta = tdelta + !tdelta; 1962 time_t newy = y + ydelta; 1963 register int leapdays; 1964 leapdays = leaps_thru_end_of(newy - 1) - 1965 leaps_thru_end_of(y - 1); 1966 idays -= ydelta * DAYSPERNYEAR; 1967 idays -= leapdays; 1968 y = newy; 1969 } 1970 1971 #ifdef ckd_add 1972 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 1973 errno = EOVERFLOW; 1974 return NULL; 1975 } 1976 #else 1977 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 1978 int signed_y = y; 1979 tmp->tm_year = signed_y - TM_YEAR_BASE; 1980 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 1981 && y - TM_YEAR_BASE <= INT_MAX) 1982 tmp->tm_year = y - TM_YEAR_BASE; 1983 else { 1984 errno = EOVERFLOW; 1985 return NULL; 1986 } 1987 #endif 1988 tmp->tm_yday = idays; 1989 /* 1990 ** The "extra" mods below avoid overflow problems. 1991 */ 1992 tmp->tm_wday = (TM_WDAY_BASE 1993 + ((tmp->tm_year % DAYSPERWEEK) 1994 * (DAYSPERNYEAR % DAYSPERWEEK)) 1995 + leaps_thru_end_of(y - 1) 1996 - leaps_thru_end_of(TM_YEAR_BASE - 1) 1997 + idays); 1998 tmp->tm_wday %= DAYSPERWEEK; 1999 if (tmp->tm_wday < 0) 2000 tmp->tm_wday += DAYSPERWEEK; 2001 tmp->tm_hour = rem / SECSPERHOUR; 2002 rem %= SECSPERHOUR; 2003 tmp->tm_min = rem / SECSPERMIN; 2004 tmp->tm_sec = rem % SECSPERMIN; 2005 2006 /* Use "... ??:??:60" at the end of the localtime minute containing 2007 the second just before the positive leap second. */ 2008 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2009 2010 ip = mon_lengths[isleap(y)]; 2011 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2012 idays -= ip[tmp->tm_mon]; 2013 tmp->tm_mday = idays + 1; 2014 tmp->tm_isdst = 0; 2015 #ifdef TM_GMTOFF 2016 tmp->TM_GMTOFF = offset; 2017 #endif /* defined TM_GMTOFF */ 2018 return tmp; 2019 } 2020 2021 /* 2022 ** Adapted from code provided by Robert Elz, who writes: 2023 ** The "best" way to do mktime I think is based on an idea of Bob 2024 ** Kridle's (so its said...) from a long time ago. 2025 ** It does a binary search of the time_t space. Since time_t's are 2026 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2027 ** would still be very reasonable). 2028 */ 2029 2030 #ifndef WRONG 2031 # define WRONG (-1) 2032 #endif /* !defined WRONG */ 2033 2034 /* 2035 ** Normalize logic courtesy Paul Eggert. 2036 */ 2037 2038 static bool 2039 increment_overflow(int *ip, int j) 2040 { 2041 #ifdef ckd_add 2042 return ckd_add(ip, *ip, j); 2043 #else 2044 register int const i = *ip; 2045 2046 /* 2047 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2048 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2049 ** If i < 0 there can only be overflow if i + j < INT_MIN 2050 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2051 */ 2052 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2053 return true; 2054 *ip += j; 2055 return false; 2056 #endif 2057 } 2058 2059 static bool 2060 increment_overflow32(int_fast32_t *const lp, int const m) 2061 { 2062 #ifdef ckd_add 2063 return ckd_add(lp, *lp, m); 2064 #else 2065 register int_fast32_t const l = *lp; 2066 2067 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) 2068 return true; 2069 *lp += m; 2070 return false; 2071 #endif 2072 } 2073 2074 static bool 2075 increment_overflow_time(time_t *tp, int_fast32_t j) 2076 { 2077 #ifdef ckd_add 2078 return ckd_add(tp, *tp, j); 2079 #else 2080 /* 2081 ** This is like 2082 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2083 ** except that it does the right thing even if *tp + j would overflow. 2084 */ 2085 if (! (j < 0 2086 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2087 : *tp <= TIME_T_MAX - j)) 2088 return true; 2089 *tp += j; 2090 return false; 2091 #endif 2092 } 2093 2094 static bool 2095 normalize_overflow(int *const tensptr, int *const unitsptr, const int base) 2096 { 2097 register int tensdelta; 2098 2099 tensdelta = (*unitsptr >= 0) ? 2100 (*unitsptr / base) : 2101 (-1 - (-1 - *unitsptr) / base); 2102 *unitsptr -= tensdelta * base; 2103 return increment_overflow(tensptr, tensdelta); 2104 } 2105 2106 static bool 2107 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base) 2108 { 2109 register int tensdelta; 2110 2111 tensdelta = (*unitsptr >= 0) ? 2112 (*unitsptr / base) : 2113 (-1 - (-1 - *unitsptr) / base); 2114 *unitsptr -= tensdelta * base; 2115 return increment_overflow32(tensptr, tensdelta); 2116 } 2117 2118 static int 2119 tmcomp(register const struct tm *const atmp, 2120 register const struct tm *const btmp) 2121 { 2122 register int result; 2123 2124 if (atmp->tm_year != btmp->tm_year) 2125 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2126 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2127 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2128 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2129 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2130 result = atmp->tm_sec - btmp->tm_sec; 2131 return result; 2132 } 2133 2134 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2135 as other members might not be initialized. */ 2136 static void 2137 mktmcpy(struct tm *dest, struct tm const *src) 2138 { 2139 dest->tm_sec = src->tm_sec; 2140 dest->tm_min = src->tm_min; 2141 dest->tm_hour = src->tm_hour; 2142 dest->tm_mday = src->tm_mday; 2143 dest->tm_mon = src->tm_mon; 2144 dest->tm_year = src->tm_year; 2145 dest->tm_isdst = src->tm_isdst; 2146 #if defined TM_GMTOFF && ! UNINIT_TRAP 2147 dest->TM_GMTOFF = src->TM_GMTOFF; 2148 #endif 2149 } 2150 2151 static time_t 2152 time2sub(struct tm *const tmp, 2153 struct tm *(*funcp)(struct state const *, time_t const *, 2154 int_fast32_t, struct tm *), 2155 struct state const *sp, 2156 const int_fast32_t offset, 2157 bool *okayp, 2158 bool do_norm_secs) 2159 { 2160 register int dir; 2161 register int i, j; 2162 register int saved_seconds; 2163 register int_fast32_t li; 2164 register time_t lo; 2165 register time_t hi; 2166 int_fast32_t y; 2167 time_t newt; 2168 time_t t; 2169 struct tm yourtm, mytm; 2170 2171 *okayp = false; 2172 mktmcpy(&yourtm, tmp); 2173 2174 if (do_norm_secs) { 2175 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 2176 SECSPERMIN)) 2177 return WRONG; 2178 } 2179 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 2180 return WRONG; 2181 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 2182 return WRONG; 2183 y = yourtm.tm_year; 2184 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) 2185 return WRONG; 2186 /* 2187 ** Turn y into an actual year number for now. 2188 ** It is converted back to an offset from TM_YEAR_BASE later. 2189 */ 2190 if (increment_overflow32(&y, TM_YEAR_BASE)) 2191 return WRONG; 2192 while (yourtm.tm_mday <= 0) { 2193 if (increment_overflow32(&y, -1)) 2194 return WRONG; 2195 li = y + (1 < yourtm.tm_mon); 2196 yourtm.tm_mday += year_lengths[isleap(li)]; 2197 } 2198 while (yourtm.tm_mday > DAYSPERLYEAR) { 2199 li = y + (1 < yourtm.tm_mon); 2200 yourtm.tm_mday -= year_lengths[isleap(li)]; 2201 if (increment_overflow32(&y, 1)) 2202 return WRONG; 2203 } 2204 for ( ; ; ) { 2205 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2206 if (yourtm.tm_mday <= i) 2207 break; 2208 yourtm.tm_mday -= i; 2209 if (++yourtm.tm_mon >= MONSPERYEAR) { 2210 yourtm.tm_mon = 0; 2211 if (increment_overflow32(&y, 1)) 2212 return WRONG; 2213 } 2214 } 2215 #ifdef ckd_add 2216 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2217 return WRONG; 2218 #else 2219 if (increment_overflow32(&y, -TM_YEAR_BASE)) 2220 return WRONG; 2221 if (! (INT_MIN <= y && y <= INT_MAX)) 2222 return WRONG; 2223 yourtm.tm_year = y; 2224 #endif 2225 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2226 saved_seconds = 0; 2227 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2228 /* 2229 ** We can't set tm_sec to 0, because that might push the 2230 ** time below the minimum representable time. 2231 ** Set tm_sec to 59 instead. 2232 ** This assumes that the minimum representable time is 2233 ** not in the same minute that a leap second was deleted from, 2234 ** which is a safer assumption than using 58 would be. 2235 */ 2236 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 2237 return WRONG; 2238 saved_seconds = yourtm.tm_sec; 2239 yourtm.tm_sec = SECSPERMIN - 1; 2240 } else { 2241 saved_seconds = yourtm.tm_sec; 2242 yourtm.tm_sec = 0; 2243 } 2244 /* 2245 ** Do a binary search (this works whatever time_t's type is). 2246 */ 2247 lo = TIME_T_MIN; 2248 hi = TIME_T_MAX; 2249 for ( ; ; ) { 2250 t = lo / 2 + hi / 2; 2251 if (t < lo) 2252 t = lo; 2253 else if (t > hi) 2254 t = hi; 2255 if (! funcp(sp, &t, offset, &mytm)) { 2256 /* 2257 ** Assume that t is too extreme to be represented in 2258 ** a struct tm; arrange things so that it is less 2259 ** extreme on the next pass. 2260 */ 2261 dir = (t > 0) ? 1 : -1; 2262 } else dir = tmcomp(&mytm, &yourtm); 2263 if (dir != 0) { 2264 if (t == lo) { 2265 if (t == TIME_T_MAX) 2266 return WRONG; 2267 ++t; 2268 ++lo; 2269 } else if (t == hi) { 2270 if (t == TIME_T_MIN) 2271 return WRONG; 2272 --t; 2273 --hi; 2274 } 2275 if (lo > hi) 2276 return WRONG; 2277 if (dir > 0) 2278 hi = t; 2279 else lo = t; 2280 continue; 2281 } 2282 #if defined TM_GMTOFF && ! UNINIT_TRAP 2283 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2284 && (yourtm.TM_GMTOFF < 0 2285 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2286 && (mytm.TM_GMTOFF <= 2287 (min(INT_FAST32_MAX, LONG_MAX) 2288 + yourtm.TM_GMTOFF))) 2289 : (yourtm.TM_GMTOFF <= SECSPERDAY 2290 && ((max(INT_FAST32_MIN, LONG_MIN) 2291 + yourtm.TM_GMTOFF) 2292 <= mytm.TM_GMTOFF)))) { 2293 /* MYTM matches YOURTM except with the wrong UT offset. 2294 YOURTM.TM_GMTOFF is plausible, so try it instead. 2295 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2296 since the guess gets checked. */ 2297 time_t altt = t; 2298 int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF; 2299 if (!increment_overflow_time(&altt, diff)) { 2300 struct tm alttm; 2301 if (funcp(sp, &altt, offset, &alttm) 2302 && alttm.tm_isdst == mytm.tm_isdst 2303 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2304 && tmcomp(&alttm, &yourtm) == 0) { 2305 t = altt; 2306 mytm = alttm; 2307 } 2308 } 2309 } 2310 #endif 2311 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2312 break; 2313 /* 2314 ** Right time, wrong type. 2315 ** Hunt for right time, right type. 2316 ** It's okay to guess wrong since the guess 2317 ** gets checked. 2318 */ 2319 if (sp == NULL) 2320 return WRONG; 2321 for (i = sp->typecnt - 1; i >= 0; --i) { 2322 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2323 continue; 2324 for (j = sp->typecnt - 1; j >= 0; --j) { 2325 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2326 continue; 2327 if (ttunspecified(sp, j)) 2328 continue; 2329 newt = (t + sp->ttis[j].tt_utoff 2330 - sp->ttis[i].tt_utoff); 2331 if (! funcp(sp, &newt, offset, &mytm)) 2332 continue; 2333 if (tmcomp(&mytm, &yourtm) != 0) 2334 continue; 2335 if (mytm.tm_isdst != yourtm.tm_isdst) 2336 continue; 2337 /* 2338 ** We have a match. 2339 */ 2340 t = newt; 2341 goto label; 2342 } 2343 } 2344 return WRONG; 2345 } 2346 label: 2347 newt = t + saved_seconds; 2348 if ((newt < t) != (saved_seconds < 0)) 2349 return WRONG; 2350 t = newt; 2351 if (funcp(sp, &t, offset, tmp)) 2352 *okayp = true; 2353 return t; 2354 } 2355 2356 static time_t 2357 time2(struct tm * const tmp, 2358 struct tm *(*funcp)(struct state const *, time_t const *, 2359 int_fast32_t, struct tm *), 2360 struct state const *sp, 2361 const int_fast32_t offset, 2362 bool *okayp) 2363 { 2364 time_t t; 2365 2366 /* 2367 ** First try without normalization of seconds 2368 ** (in case tm_sec contains a value associated with a leap second). 2369 ** If that fails, try with normalization of seconds. 2370 */ 2371 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2372 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2373 } 2374 2375 static time_t 2376 time1(struct tm *const tmp, 2377 struct tm *(*funcp)(struct state const *, time_t const *, 2378 int_fast32_t, struct tm *), 2379 struct state const *sp, 2380 const int_fast32_t offset) 2381 { 2382 register time_t t; 2383 register int samei, otheri; 2384 register int sameind, otherind; 2385 register int i; 2386 register int nseen; 2387 char seen[TZ_MAX_TYPES]; 2388 unsigned char types[TZ_MAX_TYPES]; 2389 bool okay; 2390 2391 if (tmp == NULL) { 2392 errno = EINVAL; 2393 return WRONG; 2394 } 2395 2396 if (tmp->tm_isdst > 1) 2397 tmp->tm_isdst = 1; 2398 t = time2(tmp, funcp, sp, offset, &okay); 2399 if (okay) 2400 return t; 2401 if (tmp->tm_isdst < 0) 2402 #ifdef PCTS 2403 /* 2404 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2405 */ 2406 tmp->tm_isdst = 0; /* reset to std and try again */ 2407 #else 2408 return t; 2409 #endif /* !defined PCTS */ 2410 /* 2411 ** We're supposed to assume that somebody took a time of one type 2412 ** and did some math on it that yielded a "struct tm" that's bad. 2413 ** We try to divine the type they started from and adjust to the 2414 ** type they need. 2415 */ 2416 if (sp == NULL) 2417 return WRONG; 2418 for (i = 0; i < sp->typecnt; ++i) 2419 seen[i] = false; 2420 nseen = 0; 2421 for (i = sp->timecnt - 1; i >= 0; --i) 2422 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2423 seen[sp->types[i]] = true; 2424 types[nseen++] = sp->types[i]; 2425 } 2426 for (sameind = 0; sameind < nseen; ++sameind) { 2427 samei = types[sameind]; 2428 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2429 continue; 2430 for (otherind = 0; otherind < nseen; ++otherind) { 2431 otheri = types[otherind]; 2432 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2433 continue; 2434 tmp->tm_sec += (sp->ttis[otheri].tt_utoff 2435 - sp->ttis[samei].tt_utoff); 2436 tmp->tm_isdst = !tmp->tm_isdst; 2437 t = time2(tmp, funcp, sp, offset, &okay); 2438 if (okay) 2439 return t; 2440 tmp->tm_sec -= (sp->ttis[otheri].tt_utoff 2441 - sp->ttis[samei].tt_utoff); 2442 tmp->tm_isdst = !tmp->tm_isdst; 2443 } 2444 } 2445 return WRONG; 2446 } 2447 2448 static time_t 2449 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2450 { 2451 if (sp) 2452 return time1(tmp, localsub, sp, setname); 2453 else { 2454 _once(&gmt_once, gmtcheck); 2455 return time1(tmp, gmtsub, gmtptr, 0); 2456 } 2457 } 2458 2459 #if NETBSD_INSPIRED 2460 2461 time_t 2462 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2463 { 2464 return mktime_tzname(sp, tmp, false); 2465 } 2466 2467 #endif 2468 2469 time_t 2470 mktime(struct tm *tmp) 2471 { 2472 time_t t; 2473 int err = lock(); 2474 if (err) { 2475 errno = err; 2476 return -1; 2477 } 2478 tzset_unlocked(); 2479 t = mktime_tzname(lclptr, tmp, true); 2480 unlock(); 2481 return t; 2482 } 2483 2484 #if STD_INSPIRED 2485 /* This function is obsolescent and may disapper in future releases. 2486 Callers can instead use mktime. */ 2487 time_t 2488 timelocal(struct tm *tmp) 2489 { 2490 if (tmp != NULL) 2491 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2492 return mktime(tmp); 2493 } 2494 #endif 2495 2496 #ifndef EXTERN_TIMEOFF 2497 # ifndef timeoff 2498 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2499 # endif 2500 # define EXTERN_TIMEOFF static 2501 #endif 2502 2503 /* This function is obsolescent and may disapper in future releases. 2504 Callers can instead use mktime_z with a fixed-offset zone. */ 2505 EXTERN_TIMEOFF time_t 2506 timeoff(struct tm *tmp, long offset) 2507 { 2508 if (tmp) 2509 tmp->tm_isdst = 0; 2510 _once(&gmt_once, gmtcheck); 2511 return time1(tmp, gmtsub, gmtptr, offset); 2512 } 2513 2514 time_t 2515 timegm(struct tm *tmp) 2516 { 2517 time_t t; 2518 struct tm tmcpy; 2519 mktmcpy(&tmcpy, tmp); 2520 tmcpy.tm_wday = -1; 2521 t = timeoff(&tmcpy, 0); 2522 if (0 <= tmcpy.tm_wday) 2523 *tmp = tmcpy; 2524 return t; 2525 } 2526 2527 static int_fast32_t 2528 leapcorr(struct state const *sp, time_t t) 2529 { 2530 register struct lsinfo const * lp; 2531 register int i; 2532 2533 i = sp->leapcnt; 2534 while (--i >= 0) { 2535 lp = &sp->lsis[i]; 2536 if (t >= lp->ls_trans) 2537 return lp->ls_corr; 2538 } 2539 return 0; 2540 } 2541 2542 /* 2543 ** XXX--is the below the right way to conditionalize?? 2544 */ 2545 2546 #if STD_INSPIRED 2547 2548 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 2549 NETBSD_INSPIRED is defined, and are private otherwise. */ 2550 # if NETBSD_INSPIRED 2551 # define NETBSD_INSPIRED_EXTERN 2552 # else 2553 # define NETBSD_INSPIRED_EXTERN static 2554 # endif 2555 2556 /* 2557 ** IEEE Std 1003.1 (POSIX) says that 536457599 2558 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2559 ** is not the case if we are accounting for leap seconds. 2560 ** So, we provide the following conversion routines for use 2561 ** when exchanging timestamps with POSIX conforming systems. 2562 */ 2563 2564 NETBSD_INSPIRED_EXTERN time_t 2565 time2posix_z(struct state *sp, time_t t) 2566 { 2567 return t - leapcorr(sp, t); 2568 } 2569 2570 time_t 2571 time2posix(time_t t) 2572 { 2573 int err = lock(); 2574 if (err) { 2575 errno = err; 2576 return -1; 2577 } 2578 #ifndef DETECT_TZ_CHANGES 2579 if (!lcl_is_set) 2580 #endif 2581 tzset_unlocked(); 2582 if (lclptr) 2583 t = time2posix_z(lclptr, t); 2584 unlock(); 2585 return t; 2586 } 2587 2588 NETBSD_INSPIRED_EXTERN time_t 2589 posix2time_z(struct state *sp, time_t t) 2590 { 2591 time_t x; 2592 time_t y; 2593 /* 2594 ** For a positive leap second hit, the result 2595 ** is not unique. For a negative leap second 2596 ** hit, the corresponding time doesn't exist, 2597 ** so we return an adjacent second. 2598 */ 2599 x = t + leapcorr(sp, t); 2600 y = x - leapcorr(sp, x); 2601 if (y < t) { 2602 do { 2603 x++; 2604 y = x - leapcorr(sp, x); 2605 } while (y < t); 2606 x -= y != t; 2607 } else if (y > t) { 2608 do { 2609 --x; 2610 y = x - leapcorr(sp, x); 2611 } while (y > t); 2612 x += y != t; 2613 } 2614 return x; 2615 } 2616 2617 time_t 2618 posix2time(time_t t) 2619 { 2620 int err = lock(); 2621 if (err) { 2622 errno = err; 2623 return -1; 2624 } 2625 #ifndef DETECT_TZ_CHANGES 2626 if (!lcl_is_set) 2627 #endif 2628 tzset_unlocked(); 2629 if (lclptr) 2630 t = posix2time_z(lclptr, t); 2631 unlock(); 2632 return t; 2633 } 2634 2635 #endif /* STD_INSPIRED */ 2636 2637 #if TZ_TIME_T 2638 2639 # if !USG_COMPAT 2640 # define daylight 0 2641 # define timezone 0 2642 # endif 2643 # if !ALTZONE 2644 # define altzone 0 2645 # endif 2646 2647 /* Convert from the underlying system's time_t to the ersatz time_tz, 2648 which is called 'time_t' in this file. Typically, this merely 2649 converts the time's integer width. On some platforms, the system 2650 time is local time not UT, or uses some epoch other than the POSIX 2651 epoch. 2652 2653 Although this code appears to define a function named 'time' that 2654 returns time_t, the macros in private.h cause this code to actually 2655 define a function named 'tz_time' that returns tz_time_t. The call 2656 to sys_time invokes the underlying system's 'time' function. */ 2657 2658 time_t 2659 time(time_t *p) 2660 { 2661 time_t r = sys_time(0); 2662 if (r != (time_t) -1) { 2663 int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0; 2664 if (increment_overflow32(&offset, -EPOCH_OFFSET) 2665 || increment_overflow_time(&r, offset)) { 2666 errno = EOVERFLOW; 2667 r = -1; 2668 } 2669 } 2670 if (p) 2671 *p = r; 2672 return r; 2673 } 2674 2675 #endif 2676