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 #ifdef __FreeBSD__ 17 #include "namespace.h" 18 #include <pthread.h> 19 #endif /* __FreeBSD__ */ 20 #ifdef DETECT_TZ_CHANGES 21 # ifndef DETECT_TZ_CHANGES_INTERVAL 22 # define DETECT_TZ_CHANGES_INTERVAL 61 23 # endif 24 int __tz_change_interval = DETECT_TZ_CHANGES_INTERVAL; 25 # include <sys/stat.h> 26 #endif /* DETECT_TZ_CHANGES */ 27 #include "private.h" 28 29 #include "tzdir.h" 30 #include "tzfile.h" 31 #include <fcntl.h> 32 #ifdef __FreeBSD__ 33 #include "libc_private.h" 34 #include "un-namespace.h" 35 #endif /* __FreeBSD__ */ 36 37 #if defined THREAD_SAFE && THREAD_SAFE 38 # include <pthread.h> 39 #ifdef __FreeBSD__ 40 # define pthread_mutex_lock(l) (__isthreaded ? _pthread_mutex_lock(l) : 0) 41 # define pthread_mutex_unlock(l) (__isthreaded ? _pthread_mutex_unlock(l) : 0) 42 #endif /* __FreeBSD__ */ 43 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; 44 static int lock(void) { return pthread_mutex_lock(&locallock); } 45 static void unlock(void) { pthread_mutex_unlock(&locallock); } 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 proleptic 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 154 enum r_type { 155 JULIAN_DAY, /* Jn = Julian day */ 156 DAY_OF_YEAR, /* n = day of year */ 157 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 158 }; 159 160 struct rule { 161 enum r_type r_type; /* type of rule */ 162 int r_day; /* day number of rule */ 163 int r_week; /* week number of rule */ 164 int r_mon; /* month number of rule */ 165 int_fast32_t r_time; /* transition time of rule */ 166 }; 167 168 #ifdef __FreeBSD__ 169 static void tzset_unlocked_name(char const *); 170 #endif /* __FreeBSD__ */ 171 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 172 struct tm *); 173 static bool increment_overflow(int *, int); 174 static bool increment_overflow_time(time_t *, int_fast32_t); 175 static int_fast32_t leapcorr(struct state const *, time_t); 176 static bool normalize_overflow32(int_fast32_t *, int *, int); 177 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 178 struct tm *); 179 static bool tzparse(char const *, struct state *, struct state const *); 180 181 #ifdef ALL_STATE 182 static struct state * lclptr; 183 static struct state * gmtptr; 184 #endif /* defined ALL_STATE */ 185 186 #ifndef ALL_STATE 187 static struct state lclmem; 188 static struct state gmtmem; 189 static struct state *const lclptr = &lclmem; 190 static struct state *const gmtptr = &gmtmem; 191 #endif /* State Farm */ 192 193 #ifndef TZ_STRLEN_MAX 194 # define TZ_STRLEN_MAX 255 195 #endif /* !defined TZ_STRLEN_MAX */ 196 197 static char lcl_TZname[TZ_STRLEN_MAX + 1]; 198 static int lcl_is_set; 199 #ifdef __FreeBSD__ 200 static pthread_once_t gmt_once = PTHREAD_ONCE_INIT; 201 static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT; 202 static pthread_key_t gmtime_key; 203 static int gmtime_key_error; 204 static pthread_once_t offtime_once = PTHREAD_ONCE_INIT; 205 static pthread_key_t offtime_key; 206 static int offtime_key_error; 207 static pthread_once_t localtime_once = PTHREAD_ONCE_INIT; 208 static pthread_key_t localtime_key; 209 static int localtime_key_error; 210 #endif /* __FreeBSD__ */ 211 212 /* 213 ** Section 4.12.3 of X3.159-1989 requires that 214 ** Except for the strftime function, these functions [asctime, 215 ** ctime, gmtime, localtime] return values in one of two static 216 ** objects: a broken-down time structure and an array of char. 217 ** Thanks to Paul Eggert for noting this. 218 ** 219 ** Although this requirement was removed in C99 it is still present in POSIX. 220 ** Follow the requirement if SUPPORT_C89, even though this is more likely to 221 ** trigger latent bugs in 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 * Check whether either the time zone name or the file it refers to has 405 * changed since the last time we checked. 406 * Returns: -1 on error 407 * 0 if the time zone has not changed 408 * 1 if the time zone has changed 409 */ 410 static int 411 tzfile_changed(const char *name, int fd) 412 { 413 static char old_name[PATH_MAX]; 414 static struct stat old_sb; 415 struct stat sb; 416 417 if (_fstat(fd, &sb) != 0) 418 return -1; 419 420 if (strcmp(name, old_name) != 0) { 421 strlcpy(old_name, name, sizeof(old_name)); 422 old_sb = sb; 423 return 1; 424 } 425 426 if (sb.st_dev != old_sb.st_dev || 427 sb.st_ino != old_sb.st_ino || 428 sb.st_ctime != old_sb.st_ctime || 429 sb.st_mtime != old_sb.st_mtime) { 430 old_sb = sb; 431 return 1; 432 } 433 434 return 0; 435 } 436 #endif /* DETECT_TZ_CHANGES */ 437 438 /* Input buffer for data read from a compiled tz file. */ 439 union input_buffer { 440 /* The first part of the buffer, interpreted as a header. */ 441 struct tzhead tzhead; 442 443 /* The entire buffer. Ideally this would have no size limits; 444 the following should suffice for practical use. */ 445 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 446 + 4 * TZ_MAX_TIMES]; 447 }; 448 449 #ifndef __FreeBSD__ 450 /* TZDIR with a trailing '/' rather than a trailing '\0'. */ 451 static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; 452 #endif /* !__FreeBSD__ */ 453 454 /* Local storage needed for 'tzloadbody'. */ 455 union local_storage { 456 /* The results of analyzing the file's contents after it is opened. */ 457 struct file_analysis { 458 /* The input buffer. */ 459 union input_buffer u; 460 461 /* A temporary state used for parsing a TZ string in the file. */ 462 struct state st; 463 } u; 464 465 #ifndef __FreeBSD__ 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 #endif /* !__FreeBSD__ */ 474 }; 475 476 /* Load tz data from the file named NAME into *SP. Read extended 477 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on 478 success, an errno value on failure. */ 479 static int 480 tzloadbody(char const *name, struct state *sp, bool doextend, 481 union local_storage *lsp) 482 { 483 register int i; 484 register int fid; 485 register int stored; 486 register ssize_t nread; 487 #ifdef __FreeBSD__ 488 int serrno; 489 #else /* !__FreeBSD__ */ 490 register bool doaccess; 491 #endif /* !__FreeBSD__ */ 492 register union input_buffer *up = &lsp->u.u; 493 register int tzheadsize = sizeof(struct tzhead); 494 495 sp->goback = sp->goahead = false; 496 497 if (! name) { 498 name = TZDEFAULT; 499 if (! name) 500 return EINVAL; 501 } 502 503 if (name[0] == ':') 504 ++name; 505 #ifndef __FreeBSD__ 506 #ifdef SUPPRESS_TZDIR 507 /* Do not prepend TZDIR. This is intended for specialized 508 applications only, due to its security implications. */ 509 doaccess = true; 510 #else 511 doaccess = name[0] == '/'; 512 #endif 513 if (!doaccess) { 514 char const *dot; 515 if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name)) 516 return ENAMETOOLONG; 517 518 /* Create a string "TZDIR/NAME". Using sprintf here 519 would pull in stdio (and would fail if the 520 resulting string length exceeded INT_MAX!). */ 521 memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); 522 strcpy(lsp->fullname + sizeof tzdirslash, name); 523 524 /* Set doaccess if NAME contains a ".." file name 525 component, as such a name could read a file outside 526 the TZDIR virtual subtree. */ 527 for (dot = name; (dot = strchr(dot, '.')); dot++) 528 if ((dot == name || dot[-1] == '/') && dot[1] == '.' 529 && (dot[2] == '/' || !dot[2])) { 530 doaccess = true; 531 break; 532 } 533 534 name = lsp->fullname; 535 } 536 if (doaccess && access(name, R_OK) != 0) 537 return errno; 538 fid = _open(name, O_RDONLY | O_BINARY); 539 #else /* __FreeBSD__ */ 540 { 541 const char *relname = name; 542 if (strncmp(relname, TZDIR "/", strlen(TZDIR) + 1) == 0) 543 relname += strlen(TZDIR) + 1; 544 int dd = _open(TZDIR, O_DIRECTORY | O_RDONLY); 545 if (dd < 0) 546 return errno; 547 fid = _openat(dd, relname, O_RDONLY | O_BINARY, 548 issetugid() ? AT_RESOLVE_BENEATH : 0); 549 serrno = errno; 550 _close(dd); 551 errno = serrno; 552 } 553 #endif /* __FreeBSD__ */ 554 if (fid < 0) 555 return errno; 556 557 #ifdef DETECT_TZ_CHANGES 558 if (doextend) { 559 /* 560 * Detect if the timezone file has changed. Check 'doextend' to 561 * ignore TZDEFRULES; the tzfile_changed() function can only 562 * keep state for a single file. 563 */ 564 switch (tzfile_changed(name, fid)) { 565 case -1: 566 serrno = errno; 567 _close(fid); 568 return serrno; 569 case 0: 570 _close(fid); 571 return 0; 572 case 1: 573 break; 574 } 575 } 576 #endif /* DETECT_TZ_CHANGES */ 577 nread = _read(fid, up->buf, sizeof up->buf); 578 if (nread < tzheadsize) { 579 int err = nread < 0 ? errno : EINVAL; 580 _close(fid); 581 return err; 582 } 583 if (_close(fid) < 0) 584 return errno; 585 for (stored = 4; stored <= 8; stored *= 2) { 586 char version = up->tzhead.tzh_version[0]; 587 bool skip_datablock = stored == 4 && version; 588 int_fast32_t datablock_size; 589 int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); 590 int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); 591 int_fast64_t prevtr = -1; 592 int_fast32_t prevcorr; 593 int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); 594 int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); 595 int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); 596 int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); 597 char const *p = up->buf + tzheadsize; 598 /* Although tzfile(5) currently requires typecnt to be nonzero, 599 support future formats that may allow zero typecnt 600 in files that have a TZ string and no transitions. */ 601 if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS 602 && 0 <= typecnt && typecnt < TZ_MAX_TYPES 603 && 0 <= timecnt && timecnt < TZ_MAX_TIMES 604 && 0 <= charcnt && charcnt < TZ_MAX_CHARS 605 && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES 606 && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES)) 607 return EINVAL; 608 datablock_size 609 = (timecnt * stored /* ats */ 610 + timecnt /* types */ 611 + typecnt * 6 /* ttinfos */ 612 + charcnt /* chars */ 613 + leapcnt * (stored + 4) /* lsinfos */ 614 + ttisstdcnt /* ttisstds */ 615 + ttisutcnt); /* ttisuts */ 616 if (nread < tzheadsize + datablock_size) 617 return EINVAL; 618 if (skip_datablock) 619 p += datablock_size; 620 else { 621 if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 622 && (ttisutcnt == typecnt || ttisutcnt == 0))) 623 return EINVAL; 624 625 sp->leapcnt = leapcnt; 626 sp->timecnt = timecnt; 627 sp->typecnt = typecnt; 628 sp->charcnt = charcnt; 629 630 /* Read transitions, discarding those out of time_t range. 631 But pretend the last transition before TIME_T_MIN 632 occurred at TIME_T_MIN. */ 633 timecnt = 0; 634 for (i = 0; i < sp->timecnt; ++i) { 635 int_fast64_t at 636 = stored == 4 ? detzcode(p) : detzcode64(p); 637 sp->types[i] = at <= TIME_T_MAX; 638 if (sp->types[i]) { 639 time_t attime 640 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 641 ? TIME_T_MIN : at); 642 if (timecnt && attime <= sp->ats[timecnt - 1]) { 643 if (attime < sp->ats[timecnt - 1]) 644 return EINVAL; 645 sp->types[i - 1] = 0; 646 timecnt--; 647 } 648 sp->ats[timecnt++] = attime; 649 } 650 p += stored; 651 } 652 653 timecnt = 0; 654 for (i = 0; i < sp->timecnt; ++i) { 655 unsigned char typ = *p++; 656 if (sp->typecnt <= typ) 657 return EINVAL; 658 if (sp->types[i]) 659 sp->types[timecnt++] = typ; 660 } 661 sp->timecnt = timecnt; 662 for (i = 0; i < sp->typecnt; ++i) { 663 register struct ttinfo * ttisp; 664 unsigned char isdst, desigidx; 665 666 ttisp = &sp->ttis[i]; 667 ttisp->tt_utoff = detzcode(p); 668 p += 4; 669 isdst = *p++; 670 if (! (isdst < 2)) 671 return EINVAL; 672 ttisp->tt_isdst = isdst; 673 desigidx = *p++; 674 if (! (desigidx < sp->charcnt)) 675 return EINVAL; 676 ttisp->tt_desigidx = desigidx; 677 } 678 for (i = 0; i < sp->charcnt; ++i) 679 sp->chars[i] = *p++; 680 /* Ensure '\0'-terminated, and make it safe to call 681 ttunspecified later. */ 682 memset(&sp->chars[i], 0, CHARS_EXTRA); 683 684 /* Read leap seconds, discarding those out of time_t range. */ 685 leapcnt = 0; 686 for (i = 0; i < sp->leapcnt; ++i) { 687 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 688 int_fast32_t corr = detzcode(p + stored); 689 p += stored + 4; 690 691 /* Leap seconds cannot occur before the Epoch, 692 or out of order. */ 693 if (tr <= prevtr) 694 return EINVAL; 695 696 /* To avoid other botches in this code, each leap second's 697 correction must differ from the previous one's by 1 698 second or less, except that the first correction can be 699 any value; these requirements are more generous than 700 RFC 8536, to allow future RFC extensions. */ 701 if (! (i == 0 702 || (prevcorr < corr 703 ? corr == prevcorr + 1 704 : (corr == prevcorr 705 || corr == prevcorr - 1)))) 706 return EINVAL; 707 prevtr = tr; 708 prevcorr = corr; 709 710 if (tr <= TIME_T_MAX) { 711 sp->lsis[leapcnt].ls_trans = tr; 712 sp->lsis[leapcnt].ls_corr = corr; 713 leapcnt++; 714 } 715 } 716 sp->leapcnt = leapcnt; 717 718 for (i = 0; i < sp->typecnt; ++i) { 719 register struct ttinfo * ttisp; 720 721 ttisp = &sp->ttis[i]; 722 if (ttisstdcnt == 0) 723 ttisp->tt_ttisstd = false; 724 else { 725 if (*p != true && *p != false) 726 return EINVAL; 727 ttisp->tt_ttisstd = *p++; 728 } 729 } 730 for (i = 0; i < sp->typecnt; ++i) { 731 register struct ttinfo * ttisp; 732 733 ttisp = &sp->ttis[i]; 734 if (ttisutcnt == 0) 735 ttisp->tt_ttisut = false; 736 else { 737 if (*p != true && *p != false) 738 return EINVAL; 739 ttisp->tt_ttisut = *p++; 740 } 741 } 742 } 743 744 nread -= p - up->buf; 745 memmove(up->buf, p, nread); 746 747 /* If this is an old file, we're done. */ 748 if (!version) 749 break; 750 } 751 if (doextend && nread > 2 && 752 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 753 sp->typecnt + 2 <= TZ_MAX_TYPES) { 754 struct state *ts = &lsp->u.st; 755 756 up->buf[nread - 1] = '\0'; 757 if (tzparse(&up->buf[1], ts, sp)) { 758 759 /* Attempt to reuse existing abbreviations. 760 Without this, America/Anchorage would be right on 761 the edge after 2037 when TZ_MAX_CHARS is 50, as 762 sp->charcnt equals 40 (for LMT AST AWT APT AHST 763 AHDT YST AKDT AKST) and ts->charcnt equals 10 764 (for AKST AKDT). Reusing means sp->charcnt can 765 stay 40 in this example. */ 766 int gotabbr = 0; 767 int charcnt = sp->charcnt; 768 for (i = 0; i < ts->typecnt; i++) { 769 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 770 int j; 771 for (j = 0; j < charcnt; j++) 772 if (strcmp(sp->chars + j, tsabbr) == 0) { 773 ts->ttis[i].tt_desigidx = j; 774 gotabbr++; 775 break; 776 } 777 if (! (j < charcnt)) { 778 int tsabbrlen = strlen(tsabbr); 779 if (j + tsabbrlen < TZ_MAX_CHARS) { 780 strcpy(sp->chars + j, tsabbr); 781 charcnt = j + tsabbrlen + 1; 782 ts->ttis[i].tt_desigidx = j; 783 gotabbr++; 784 } 785 } 786 } 787 if (gotabbr == ts->typecnt) { 788 sp->charcnt = charcnt; 789 790 /* Ignore any trailing, no-op transitions generated 791 by zic as they don't help here and can run afoul 792 of bugs in zic 2016j or earlier. */ 793 while (1 < sp->timecnt 794 && (sp->types[sp->timecnt - 1] 795 == sp->types[sp->timecnt - 2])) 796 sp->timecnt--; 797 798 sp->goahead = ts->goahead; 799 800 for (i = 0; i < ts->timecnt; i++) { 801 time_t t = ts->ats[i]; 802 if (increment_overflow_time(&t, leapcorr(sp, t)) 803 || (0 < sp->timecnt 804 && t <= sp->ats[sp->timecnt - 1])) 805 continue; 806 if (TZ_MAX_TIMES <= sp->timecnt) { 807 sp->goahead = false; 808 break; 809 } 810 sp->ats[sp->timecnt] = t; 811 sp->types[sp->timecnt] = (sp->typecnt 812 + ts->types[i]); 813 sp->timecnt++; 814 } 815 for (i = 0; i < ts->typecnt; i++) 816 sp->ttis[sp->typecnt++] = ts->ttis[i]; 817 } 818 } 819 } 820 if (sp->typecnt == 0) 821 return EINVAL; 822 823 return 0; 824 } 825 826 /* Load tz data from the file named NAME into *SP. Read extended 827 format if DOEXTEND. Return 0 on success, an errno value on failure. */ 828 static int 829 tzload(char const *name, struct state *sp, bool doextend) 830 { 831 #ifdef ALL_STATE 832 union local_storage *lsp = malloc(sizeof *lsp); 833 if (!lsp) { 834 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 835 } else { 836 int err = tzloadbody(name, sp, doextend, lsp); 837 free(lsp); 838 return err; 839 } 840 #else 841 union local_storage ls; 842 return tzloadbody(name, sp, doextend, &ls); 843 #endif 844 } 845 846 static const int mon_lengths[2][MONSPERYEAR] = { 847 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 848 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 849 }; 850 851 static const int year_lengths[2] = { 852 DAYSPERNYEAR, DAYSPERLYEAR 853 }; 854 855 /* Is C an ASCII digit? */ 856 static bool 857 is_digit(char c) 858 { 859 return '0' <= c && c <= '9'; 860 } 861 862 /* 863 ** Given a pointer into a timezone string, scan until a character that is not 864 ** a valid character in a time zone abbreviation is found. 865 ** Return a pointer to that character. 866 */ 867 868 ATTRIBUTE_PURE_114833 static const char * 869 getzname(register const char *strp) 870 { 871 register char c; 872 873 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 874 c != '+') 875 ++strp; 876 return strp; 877 } 878 879 /* 880 ** Given a pointer into an extended timezone string, scan until the ending 881 ** delimiter of the time zone abbreviation is located. 882 ** Return a pointer to the delimiter. 883 ** 884 ** As with getzname above, the legal character set is actually quite 885 ** restricted, with other characters producing undefined results. 886 ** We don't do any checking here; checking is done later in common-case code. 887 */ 888 889 ATTRIBUTE_PURE_114833 static const char * 890 getqzname(register const char *strp, const int delim) 891 { 892 register int c; 893 894 while ((c = *strp) != '\0' && c != delim) 895 ++strp; 896 return strp; 897 } 898 899 /* 900 ** Given a pointer into a timezone string, extract a number from that string. 901 ** Check that the number is within a specified range; if it is not, return 902 ** NULL. 903 ** Otherwise, return a pointer to the first character not part of the number. 904 */ 905 906 static const char * 907 getnum(register const char *strp, int *const nump, const int min, const int max) 908 { 909 register char c; 910 register int num; 911 912 if (strp == NULL || !is_digit(c = *strp)) 913 return NULL; 914 num = 0; 915 do { 916 num = num * 10 + (c - '0'); 917 if (num > max) 918 return NULL; /* illegal value */ 919 c = *++strp; 920 } while (is_digit(c)); 921 if (num < min) 922 return NULL; /* illegal value */ 923 *nump = num; 924 return strp; 925 } 926 927 /* 928 ** Given a pointer into a timezone string, extract a number of seconds, 929 ** in hh[:mm[:ss]] form, from the string. 930 ** If any error occurs, return NULL. 931 ** Otherwise, return a pointer to the first character not part of the number 932 ** of seconds. 933 */ 934 935 static const char * 936 getsecs(register const char *strp, int_fast32_t *const secsp) 937 { 938 int num; 939 int_fast32_t secsperhour = SECSPERHOUR; 940 941 /* 942 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 943 ** "M10.4.6/26", which does not conform to POSIX, 944 ** but which specifies the equivalent of 945 ** "02:00 on the first Sunday on or after 23 Oct". 946 */ 947 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 948 if (strp == NULL) 949 return NULL; 950 *secsp = num * secsperhour; 951 if (*strp == ':') { 952 ++strp; 953 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 954 if (strp == NULL) 955 return NULL; 956 *secsp += num * SECSPERMIN; 957 if (*strp == ':') { 958 ++strp; 959 /* 'SECSPERMIN' allows for leap seconds. */ 960 strp = getnum(strp, &num, 0, SECSPERMIN); 961 if (strp == NULL) 962 return NULL; 963 *secsp += num; 964 } 965 } 966 return strp; 967 } 968 969 /* 970 ** Given a pointer into a timezone string, extract an offset, in 971 ** [+-]hh[:mm[:ss]] form, from the string. 972 ** If any error occurs, return NULL. 973 ** Otherwise, return a pointer to the first character not part of the time. 974 */ 975 976 static const char * 977 getoffset(register const char *strp, int_fast32_t *const offsetp) 978 { 979 register bool neg = false; 980 981 if (*strp == '-') { 982 neg = true; 983 ++strp; 984 } else if (*strp == '+') 985 ++strp; 986 strp = getsecs(strp, offsetp); 987 if (strp == NULL) 988 return NULL; /* illegal time */ 989 if (neg) 990 *offsetp = -*offsetp; 991 return strp; 992 } 993 994 /* 995 ** Given a pointer into a timezone string, extract a rule in the form 996 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 997 ** for the format of "date" and "time". 998 ** If a valid rule is not found, return NULL. 999 ** Otherwise, return a pointer to the first character not part of the rule. 1000 */ 1001 1002 static const char * 1003 getrule(const char *strp, register struct rule *const rulep) 1004 { 1005 if (*strp == 'J') { 1006 /* 1007 ** Julian day. 1008 */ 1009 rulep->r_type = JULIAN_DAY; 1010 ++strp; 1011 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1012 } else if (*strp == 'M') { 1013 /* 1014 ** Month, week, day. 1015 */ 1016 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1017 ++strp; 1018 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1019 if (strp == NULL) 1020 return NULL; 1021 if (*strp++ != '.') 1022 return NULL; 1023 strp = getnum(strp, &rulep->r_week, 1, 5); 1024 if (strp == NULL) 1025 return NULL; 1026 if (*strp++ != '.') 1027 return NULL; 1028 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1029 } else if (is_digit(*strp)) { 1030 /* 1031 ** Day of year. 1032 */ 1033 rulep->r_type = DAY_OF_YEAR; 1034 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1035 } else return NULL; /* invalid format */ 1036 if (strp == NULL) 1037 return NULL; 1038 if (*strp == '/') { 1039 /* 1040 ** Time specified. 1041 */ 1042 ++strp; 1043 strp = getoffset(strp, &rulep->r_time); 1044 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1045 return strp; 1046 } 1047 1048 /* 1049 ** Given a year, a rule, and the offset from UT at the time that rule takes 1050 ** effect, calculate the year-relative time that rule takes effect. 1051 */ 1052 1053 static int_fast32_t 1054 transtime(const int year, register const struct rule *const rulep, 1055 const int_fast32_t offset) 1056 { 1057 register bool leapyear; 1058 register int_fast32_t value; 1059 register int i; 1060 int d, m1, yy0, yy1, yy2, dow; 1061 1062 leapyear = isleap(year); 1063 switch (rulep->r_type) { 1064 1065 case JULIAN_DAY: 1066 /* 1067 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1068 ** years. 1069 ** In non-leap years, or if the day number is 59 or less, just 1070 ** add SECSPERDAY times the day number-1 to the time of 1071 ** January 1, midnight, to get the day. 1072 */ 1073 value = (rulep->r_day - 1) * SECSPERDAY; 1074 if (leapyear && rulep->r_day >= 60) 1075 value += SECSPERDAY; 1076 break; 1077 1078 case DAY_OF_YEAR: 1079 /* 1080 ** n - day of year. 1081 ** Just add SECSPERDAY times the day number to the time of 1082 ** January 1, midnight, to get the day. 1083 */ 1084 value = rulep->r_day * SECSPERDAY; 1085 break; 1086 1087 case MONTH_NTH_DAY_OF_WEEK: 1088 /* 1089 ** Mm.n.d - nth "dth day" of month m. 1090 */ 1091 1092 /* 1093 ** Use Zeller's Congruence to get day-of-week of first day of 1094 ** month. 1095 */ 1096 m1 = (rulep->r_mon + 9) % 12 + 1; 1097 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1098 yy1 = yy0 / 100; 1099 yy2 = yy0 % 100; 1100 dow = ((26 * m1 - 2) / 10 + 1101 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1102 if (dow < 0) 1103 dow += DAYSPERWEEK; 1104 1105 /* 1106 ** "dow" is the day-of-week of the first day of the month. Get 1107 ** the day-of-month (zero-origin) of the first "dow" day of the 1108 ** month. 1109 */ 1110 d = rulep->r_day - dow; 1111 if (d < 0) 1112 d += DAYSPERWEEK; 1113 for (i = 1; i < rulep->r_week; ++i) { 1114 if (d + DAYSPERWEEK >= 1115 mon_lengths[leapyear][rulep->r_mon - 1]) 1116 break; 1117 d += DAYSPERWEEK; 1118 } 1119 1120 /* 1121 ** "d" is the day-of-month (zero-origin) of the day we want. 1122 */ 1123 value = d * SECSPERDAY; 1124 for (i = 0; i < rulep->r_mon - 1; ++i) 1125 value += mon_lengths[leapyear][i] * SECSPERDAY; 1126 break; 1127 1128 default: unreachable(); 1129 } 1130 1131 /* 1132 ** "value" is the year-relative time of 00:00:00 UT on the day in 1133 ** question. To get the year-relative time of the specified local 1134 ** time on that day, add the transition time and the current offset 1135 ** from UT. 1136 */ 1137 return value + rulep->r_time + offset; 1138 } 1139 1140 /* 1141 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1142 ** appropriate. 1143 */ 1144 1145 static bool 1146 tzparse(const char *name, struct state *sp, struct state const *basep) 1147 { 1148 const char * stdname; 1149 const char * dstname; 1150 int_fast32_t stdoffset; 1151 int_fast32_t dstoffset; 1152 register char * cp; 1153 register bool load_ok; 1154 ptrdiff_t stdlen, dstlen, charcnt; 1155 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1156 1157 stdname = name; 1158 if (*name == '<') { 1159 name++; 1160 stdname = name; 1161 name = getqzname(name, '>'); 1162 if (*name != '>') 1163 return false; 1164 stdlen = name - stdname; 1165 name++; 1166 } else { 1167 name = getzname(name); 1168 stdlen = name - stdname; 1169 } 1170 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1171 return false; 1172 name = getoffset(name, &stdoffset); 1173 if (name == NULL) 1174 return false; 1175 charcnt = stdlen + 1; 1176 if (basep) { 1177 if (0 < basep->timecnt) 1178 atlo = basep->ats[basep->timecnt - 1]; 1179 load_ok = false; 1180 sp->leapcnt = basep->leapcnt; 1181 memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); 1182 } else { 1183 load_ok = tzload(TZDEFRULES, sp, false) == 0; 1184 if (!load_ok) 1185 sp->leapcnt = 0; /* So, we're off a little. */ 1186 } 1187 if (0 < sp->leapcnt) 1188 leaplo = sp->lsis[sp->leapcnt - 1].ls_trans; 1189 sp->goback = sp->goahead = false; 1190 if (*name != '\0') { 1191 if (*name == '<') { 1192 dstname = ++name; 1193 name = getqzname(name, '>'); 1194 if (*name != '>') 1195 return false; 1196 dstlen = name - dstname; 1197 name++; 1198 } else { 1199 dstname = name; 1200 name = getzname(name); 1201 dstlen = name - dstname; /* length of DST abbr. */ 1202 } 1203 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1204 return false; 1205 charcnt += dstlen + 1; 1206 if (*name != '\0' && *name != ',' && *name != ';') { 1207 name = getoffset(name, &dstoffset); 1208 if (name == NULL) 1209 return false; 1210 } else dstoffset = stdoffset - SECSPERHOUR; 1211 if (*name == '\0' && !load_ok) 1212 name = TZDEFRULESTRING; 1213 if (*name == ',' || *name == ';') { 1214 struct rule start; 1215 struct rule end; 1216 register int year; 1217 register int timecnt; 1218 time_t janfirst; 1219 int_fast32_t janoffset = 0; 1220 int yearbeg, yearlim; 1221 1222 ++name; 1223 if ((name = getrule(name, &start)) == NULL) 1224 return false; 1225 if (*name++ != ',') 1226 return false; 1227 if ((name = getrule(name, &end)) == NULL) 1228 return false; 1229 if (*name != '\0') 1230 return false; 1231 sp->typecnt = 2; /* standard time and DST */ 1232 /* 1233 ** Two transitions per year, from EPOCH_YEAR forward. 1234 */ 1235 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1236 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1237 timecnt = 0; 1238 janfirst = 0; 1239 yearbeg = EPOCH_YEAR; 1240 1241 do { 1242 int_fast32_t yearsecs 1243 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1244 time_t janfirst1 = janfirst; 1245 yearbeg--; 1246 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1247 janoffset = -yearsecs; 1248 break; 1249 } 1250 janfirst = janfirst1; 1251 } while (atlo < janfirst 1252 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1253 1254 while (true) { 1255 int_fast32_t yearsecs 1256 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1257 int yearbeg1 = yearbeg; 1258 time_t janfirst1 = janfirst; 1259 if (increment_overflow_time(&janfirst1, yearsecs) 1260 || increment_overflow(&yearbeg1, 1) 1261 || atlo <= janfirst1) 1262 break; 1263 yearbeg = yearbeg1; 1264 janfirst = janfirst1; 1265 } 1266 1267 yearlim = yearbeg; 1268 if (increment_overflow(&yearlim, years_of_observations)) 1269 yearlim = INT_MAX; 1270 for (year = yearbeg; year < yearlim; year++) { 1271 int_fast32_t 1272 starttime = transtime(year, &start, stdoffset), 1273 endtime = transtime(year, &end, dstoffset); 1274 int_fast32_t 1275 yearsecs = (year_lengths[isleap(year)] 1276 * SECSPERDAY); 1277 bool reversed = endtime < starttime; 1278 if (reversed) { 1279 int_fast32_t swap = starttime; 1280 starttime = endtime; 1281 endtime = swap; 1282 } 1283 if (reversed 1284 || (starttime < endtime 1285 && endtime - starttime < yearsecs)) { 1286 if (TZ_MAX_TIMES - 2 < timecnt) 1287 break; 1288 sp->ats[timecnt] = janfirst; 1289 if (! increment_overflow_time 1290 (&sp->ats[timecnt], 1291 janoffset + starttime) 1292 && atlo <= sp->ats[timecnt]) 1293 sp->types[timecnt++] = !reversed; 1294 sp->ats[timecnt] = janfirst; 1295 if (! increment_overflow_time 1296 (&sp->ats[timecnt], 1297 janoffset + endtime) 1298 && atlo <= sp->ats[timecnt]) { 1299 sp->types[timecnt++] = reversed; 1300 } 1301 } 1302 if (endtime < leaplo) { 1303 yearlim = year; 1304 if (increment_overflow(&yearlim, 1305 years_of_observations)) 1306 yearlim = INT_MAX; 1307 } 1308 if (increment_overflow_time 1309 (&janfirst, janoffset + yearsecs)) 1310 break; 1311 janoffset = 0; 1312 } 1313 sp->timecnt = timecnt; 1314 if (! timecnt) { 1315 sp->ttis[0] = sp->ttis[1]; 1316 sp->typecnt = 1; /* Perpetual DST. */ 1317 } else if (years_of_observations <= year - yearbeg) 1318 sp->goback = sp->goahead = true; 1319 } else { 1320 register int_fast32_t theirstdoffset; 1321 register int_fast32_t theirdstoffset; 1322 register int_fast32_t theiroffset; 1323 register bool isdst; 1324 register int i; 1325 register int j; 1326 1327 if (*name != '\0') 1328 return false; 1329 /* 1330 ** Initial values of theirstdoffset and theirdstoffset. 1331 */ 1332 theirstdoffset = 0; 1333 for (i = 0; i < sp->timecnt; ++i) { 1334 j = sp->types[i]; 1335 if (!sp->ttis[j].tt_isdst) { 1336 theirstdoffset = 1337 - sp->ttis[j].tt_utoff; 1338 break; 1339 } 1340 } 1341 theirdstoffset = 0; 1342 for (i = 0; i < sp->timecnt; ++i) { 1343 j = sp->types[i]; 1344 if (sp->ttis[j].tt_isdst) { 1345 theirdstoffset = 1346 - sp->ttis[j].tt_utoff; 1347 break; 1348 } 1349 } 1350 /* 1351 ** Initially we're assumed to be in standard time. 1352 */ 1353 isdst = false; 1354 /* 1355 ** Now juggle transition times and types 1356 ** tracking offsets as you do. 1357 */ 1358 for (i = 0; i < sp->timecnt; ++i) { 1359 j = sp->types[i]; 1360 sp->types[i] = sp->ttis[j].tt_isdst; 1361 if (sp->ttis[j].tt_ttisut) { 1362 /* No adjustment to transition time */ 1363 } else { 1364 /* 1365 ** If daylight saving time is in 1366 ** effect, and the transition time was 1367 ** not specified as standard time, add 1368 ** the daylight saving time offset to 1369 ** the transition time; otherwise, add 1370 ** the standard time offset to the 1371 ** transition time. 1372 */ 1373 /* 1374 ** Transitions from DST to DDST 1375 ** will effectively disappear since 1376 ** proleptic TZ strings have only one 1377 ** DST offset. 1378 */ 1379 if (isdst && !sp->ttis[j].tt_ttisstd) { 1380 sp->ats[i] += dstoffset - 1381 theirdstoffset; 1382 } else { 1383 sp->ats[i] += stdoffset - 1384 theirstdoffset; 1385 } 1386 } 1387 theiroffset = -sp->ttis[j].tt_utoff; 1388 if (sp->ttis[j].tt_isdst) 1389 theirdstoffset = theiroffset; 1390 else theirstdoffset = theiroffset; 1391 } 1392 /* 1393 ** Finally, fill in ttis. 1394 */ 1395 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1396 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1397 sp->typecnt = 2; 1398 } 1399 } else { 1400 dstlen = 0; 1401 sp->typecnt = 1; /* only standard time */ 1402 sp->timecnt = 0; 1403 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1404 } 1405 sp->charcnt = charcnt; 1406 cp = sp->chars; 1407 memcpy(cp, stdname, stdlen); 1408 cp += stdlen; 1409 *cp++ = '\0'; 1410 if (dstlen != 0) { 1411 memcpy(cp, dstname, dstlen); 1412 *(cp + dstlen) = '\0'; 1413 } 1414 return true; 1415 } 1416 1417 static void 1418 gmtload(struct state *const sp) 1419 { 1420 if (tzload(etc_utc, sp, true) != 0) 1421 tzparse("UTC0", sp, NULL); 1422 } 1423 1424 #ifdef DETECT_TZ_CHANGES 1425 /* 1426 * Check if the time zone data we have is still fresh. 1427 */ 1428 static int 1429 tzdata_is_fresh(void) 1430 { 1431 static time_t last_checked; 1432 struct timespec now; 1433 1434 if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) 1435 return 0; 1436 1437 if ((now.tv_sec - last_checked >= __tz_change_interval) || 1438 (last_checked > now.tv_sec)) { 1439 last_checked = now.tv_sec; 1440 return 1; 1441 } 1442 1443 return 0; 1444 } 1445 #endif /* DETECT_TZ_CHANGES */ 1446 1447 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1448 Return 0 on success, an errno value on failure. */ 1449 static int 1450 zoneinit(struct state *sp, char const *name) 1451 { 1452 if (name && ! name[0]) { 1453 /* 1454 ** User wants it fast rather than right. 1455 */ 1456 sp->leapcnt = 0; /* so, we're off a little */ 1457 sp->timecnt = 0; 1458 sp->typecnt = 0; 1459 sp->charcnt = 0; 1460 sp->goback = sp->goahead = false; 1461 init_ttinfo(&sp->ttis[0], 0, false, 0); 1462 strcpy(sp->chars, utc); 1463 return 0; 1464 } else { 1465 int err = tzload(name, sp, true); 1466 if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) 1467 err = 0; 1468 if (err == 0) 1469 err = scrub_abbrs(sp); 1470 return err; 1471 } 1472 } 1473 1474 static void 1475 tzset_unlocked(void) 1476 { 1477 #ifdef __FreeBSD__ 1478 tzset_unlocked_name(getenv("TZ")); 1479 } 1480 static void 1481 tzset_unlocked_name(char const *name) 1482 { 1483 #else 1484 char const *name = getenv("TZ"); 1485 #endif 1486 struct state *sp = lclptr; 1487 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1488 if (lcl < 0 1489 ? lcl_is_set < 0 1490 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1491 #ifdef DETECT_TZ_CHANGES 1492 if (tzdata_is_fresh() == 0) 1493 #endif /* DETECT_TZ_CHANGES */ 1494 return; 1495 #ifdef ALL_STATE 1496 if (! sp) 1497 lclptr = sp = malloc(sizeof *lclptr); 1498 #endif /* defined ALL_STATE */ 1499 if (sp) { 1500 if (zoneinit(sp, name) != 0) 1501 zoneinit(sp, ""); 1502 if (0 < lcl) 1503 strcpy(lcl_TZname, name); 1504 } 1505 settzname(); 1506 lcl_is_set = lcl; 1507 } 1508 1509 void 1510 tzset(void) 1511 { 1512 if (lock() != 0) 1513 return; 1514 tzset_unlocked(); 1515 unlock(); 1516 } 1517 1518 #ifdef __FreeBSD__ 1519 void 1520 freebsd13_tzsetwall(void) 1521 { 1522 if (lock() != 0) 1523 return; 1524 tzset_unlocked_name(NULL); 1525 unlock(); 1526 } 1527 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 1528 __warn_references(tzsetwall, 1529 "warning: tzsetwall() is deprecated, use tzset() instead."); 1530 #endif /* __FreeBSD__ */ 1531 static void 1532 gmtcheck(void) 1533 { 1534 static bool gmt_is_set; 1535 if (lock() != 0) 1536 return; 1537 if (! gmt_is_set) { 1538 #ifdef ALL_STATE 1539 gmtptr = malloc(sizeof *gmtptr); 1540 #endif 1541 if (gmtptr) 1542 gmtload(gmtptr); 1543 gmt_is_set = true; 1544 } 1545 unlock(); 1546 } 1547 #ifdef __FreeBSD__ 1548 #define gmtcheck() _once(&gmt_once, gmtcheck) 1549 #endif 1550 1551 #if NETBSD_INSPIRED 1552 1553 timezone_t 1554 tzalloc(char const *name) 1555 { 1556 timezone_t sp = malloc(sizeof *sp); 1557 if (sp) { 1558 int err = zoneinit(sp, name); 1559 if (err != 0) { 1560 free(sp); 1561 errno = err; 1562 return NULL; 1563 } 1564 } else if (!HAVE_MALLOC_ERRNO) 1565 errno = ENOMEM; 1566 return sp; 1567 } 1568 1569 void 1570 tzfree(timezone_t sp) 1571 { 1572 free(sp); 1573 } 1574 1575 /* 1576 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 1577 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 1578 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1579 ** 1580 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1581 ** in zones with three or more time zone abbreviations. 1582 ** Callers can instead use localtime_rz + strftime. 1583 */ 1584 1585 #endif 1586 1587 /* 1588 ** The easy way to behave "as if no library function calls" localtime 1589 ** is to not call it, so we drop its guts into "localsub", which can be 1590 ** freely called. (And no, the PANS doesn't require the above behavior, 1591 ** but it *is* desirable.) 1592 ** 1593 ** If successful and SETNAME is nonzero, 1594 ** set the applicable parts of tzname, timezone and altzone; 1595 ** however, it's OK to omit this step for proleptic TZ strings 1596 ** since in that case tzset should have already done this step correctly. 1597 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1598 ** but it is actually a boolean and its value should be 0 or 1. 1599 */ 1600 1601 /*ARGSUSED*/ 1602 static struct tm * 1603 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1604 struct tm *const tmp) 1605 { 1606 register const struct ttinfo * ttisp; 1607 register int i; 1608 register struct tm * result; 1609 const time_t t = *timep; 1610 1611 if (sp == NULL) { 1612 /* Don't bother to set tzname etc.; tzset has already done it. */ 1613 return gmtsub(gmtptr, timep, 0, tmp); 1614 } 1615 if ((sp->goback && t < sp->ats[0]) || 1616 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1617 time_t newt; 1618 register time_t seconds; 1619 register time_t years; 1620 1621 if (t < sp->ats[0]) 1622 seconds = sp->ats[0] - t; 1623 else seconds = t - sp->ats[sp->timecnt - 1]; 1624 --seconds; 1625 1626 /* Beware integer overflow, as SECONDS might 1627 be close to the maximum time_t. */ 1628 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 1629 seconds = years * AVGSECSPERYEAR; 1630 years += YEARSPERREPEAT; 1631 if (t < sp->ats[0]) 1632 newt = t + seconds + SECSPERREPEAT; 1633 else 1634 newt = t - seconds - SECSPERREPEAT; 1635 1636 if (newt < sp->ats[0] || 1637 newt > sp->ats[sp->timecnt - 1]) 1638 return NULL; /* "cannot happen" */ 1639 result = localsub(sp, &newt, setname, tmp); 1640 if (result) { 1641 #if defined ckd_add && defined ckd_sub 1642 if (t < sp->ats[0] 1643 ? ckd_sub(&result->tm_year, 1644 result->tm_year, years) 1645 : ckd_add(&result->tm_year, 1646 result->tm_year, years)) 1647 return NULL; 1648 #else 1649 register int_fast64_t newy; 1650 1651 newy = result->tm_year; 1652 if (t < sp->ats[0]) 1653 newy -= years; 1654 else newy += years; 1655 if (! (INT_MIN <= newy && newy <= INT_MAX)) 1656 return NULL; 1657 result->tm_year = newy; 1658 #endif 1659 } 1660 return result; 1661 } 1662 if (sp->timecnt == 0 || t < sp->ats[0]) { 1663 i = 0; 1664 } else { 1665 register int lo = 1; 1666 register int hi = sp->timecnt; 1667 1668 while (lo < hi) { 1669 register int mid = (lo + hi) >> 1; 1670 1671 if (t < sp->ats[mid]) 1672 hi = mid; 1673 else lo = mid + 1; 1674 } 1675 i = sp->types[lo - 1]; 1676 } 1677 ttisp = &sp->ttis[i]; 1678 /* 1679 ** To get (wrong) behavior that's compatible with System V Release 2.0 1680 ** you'd replace the statement below with 1681 ** t += ttisp->tt_utoff; 1682 ** timesub(&t, 0L, sp, tmp); 1683 */ 1684 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1685 if (result) { 1686 result->tm_isdst = ttisp->tt_isdst; 1687 #ifdef TM_ZONE 1688 result->TM_ZONE = (char *) &sp->chars[ttisp->tt_desigidx]; 1689 #endif /* defined TM_ZONE */ 1690 if (setname) 1691 update_tzname_etc(sp, ttisp); 1692 } 1693 return result; 1694 } 1695 1696 #if NETBSD_INSPIRED 1697 1698 struct tm * 1699 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 1700 struct tm *restrict tmp) 1701 { 1702 return localsub(sp, timep, 0, tmp); 1703 } 1704 1705 #endif 1706 1707 static struct tm * 1708 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1709 { 1710 int err = lock(); 1711 if (err) { 1712 errno = err; 1713 return NULL; 1714 } 1715 #ifndef DETECT_TZ_CHANGES 1716 if (setname || !lcl_is_set) 1717 #endif /* DETECT_TZ_CHANGES */ 1718 tzset_unlocked(); 1719 tmp = localsub(lclptr, timep, setname, tmp); 1720 unlock(); 1721 return tmp; 1722 } 1723 1724 #ifdef __FreeBSD__ 1725 static void 1726 localtime_key_init(void) 1727 { 1728 localtime_key_error = _pthread_key_create(&localtime_key, free); 1729 } 1730 #endif /* __FreeBSD__ */ 1731 struct tm * 1732 localtime(const time_t *timep) 1733 { 1734 #if !SUPPORT_C89 1735 static struct tm tm; 1736 #endif 1737 #ifdef __FreeBSD__ 1738 struct tm *p_tm = &tm; 1739 1740 if (__isthreaded != 0) { 1741 _pthread_once(&localtime_once, localtime_key_init); 1742 if (localtime_key_error != 0) { 1743 errno = localtime_key_error; 1744 return (NULL); 1745 } 1746 if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { 1747 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1748 return (NULL); 1749 } 1750 if (_pthread_setspecific(localtime_key, p_tm) != 0) { 1751 free(p_tm); 1752 return (NULL); 1753 } 1754 } 1755 } 1756 #endif /* __FreeBSD__ */ 1757 return localtime_tzset(timep, p_tm, true); 1758 } 1759 1760 struct tm * 1761 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 1762 { 1763 return localtime_tzset(timep, tmp, false); 1764 } 1765 1766 /* 1767 ** gmtsub is to gmtime as localsub is to localtime. 1768 */ 1769 1770 static struct tm * 1771 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1772 int_fast32_t offset, struct tm *tmp) 1773 { 1774 register struct tm * result; 1775 1776 result = timesub(timep, offset, gmtptr, tmp); 1777 #ifdef TM_ZONE 1778 /* 1779 ** Could get fancy here and deliver something such as 1780 ** "+xx" or "-xx" if offset is non-zero, 1781 ** but this is no time for a treasure hunt. 1782 */ 1783 tmp->TM_ZONE = ((char *) 1784 (offset ? wildabbr : gmtptr ? gmtptr->chars : utc)); 1785 #endif /* defined TM_ZONE */ 1786 return result; 1787 } 1788 1789 /* 1790 * Re-entrant version of gmtime. 1791 */ 1792 1793 struct tm * 1794 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 1795 { 1796 gmtcheck(); 1797 return gmtsub(gmtptr, timep, 0, tmp); 1798 } 1799 1800 #ifdef __FreeBSD__ 1801 static void 1802 gmtime_key_init(void) 1803 { 1804 gmtime_key_error = _pthread_key_create(&gmtime_key, free); 1805 } 1806 #endif /* __FreeBSD__ */ 1807 struct tm * 1808 gmtime(const time_t *timep) 1809 { 1810 #if !SUPPORT_C89 1811 static struct tm tm; 1812 #endif 1813 #ifdef __FreeBSD__ 1814 struct tm *p_tm = &tm; 1815 1816 if (__isthreaded != 0) { 1817 _pthread_once(&gmtime_once, gmtime_key_init); 1818 if (gmtime_key_error != 0) { 1819 errno = gmtime_key_error; 1820 return (NULL); 1821 } 1822 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { 1823 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1824 return (NULL); 1825 } 1826 if (_pthread_setspecific(gmtime_key, p_tm) != 0) { 1827 free(p_tm); 1828 return (NULL); 1829 } 1830 } 1831 } 1832 #endif /* __FreeBSD__ */ 1833 return gmtime_r(timep, p_tm); 1834 } 1835 1836 #if STD_INSPIRED 1837 1838 /* This function is obsolescent and may disappear in future releases. 1839 Callers can instead use localtime_rz with a fixed-offset zone. */ 1840 1841 struct tm * 1842 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 1843 { 1844 gmtcheck(); 1845 return gmtsub(gmtptr, timep, offset, tmp); 1846 } 1847 1848 #ifdef __FreeBSD__ 1849 static void 1850 offtime_key_init(void) 1851 { 1852 offtime_key_error = _pthread_key_create(&offtime_key, free); 1853 } 1854 #endif /* __FreeBSD__ */ 1855 struct tm * 1856 offtime(const time_t *timep, long offset) 1857 { 1858 #if !SUPPORT_C89 1859 static struct tm tm; 1860 #endif 1861 #ifdef __FreeBSD__ 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 #endif 1881 return offtime_r(timep, offset, p_tm); 1882 } 1883 1884 #endif 1885 1886 /* 1887 ** Return the number of leap years through the end of the given year 1888 ** where, to make the math easy, the answer for year zero is defined as zero. 1889 */ 1890 1891 static time_t 1892 leaps_thru_end_of_nonneg(time_t y) 1893 { 1894 return y / 4 - y / 100 + y / 400; 1895 } 1896 1897 static time_t 1898 leaps_thru_end_of(time_t y) 1899 { 1900 return (y < 0 1901 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 1902 : leaps_thru_end_of_nonneg(y)); 1903 } 1904 1905 static struct tm * 1906 timesub(const time_t *timep, int_fast32_t offset, 1907 const struct state *sp, struct tm *tmp) 1908 { 1909 register const struct lsinfo * lp; 1910 register time_t tdays; 1911 register const int * ip; 1912 register int_fast32_t corr; 1913 register int i; 1914 int_fast32_t idays, rem, dayoff, dayrem; 1915 time_t y; 1916 1917 /* If less than SECSPERMIN, the number of seconds since the 1918 most recent positive leap second; otherwise, do not add 1 1919 to localtime tm_sec because of leap seconds. */ 1920 time_t secs_since_posleap = SECSPERMIN; 1921 1922 corr = 0; 1923 i = (sp == NULL) ? 0 : sp->leapcnt; 1924 while (--i >= 0) { 1925 lp = &sp->lsis[i]; 1926 if (*timep >= lp->ls_trans) { 1927 corr = lp->ls_corr; 1928 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 1929 secs_since_posleap = *timep - lp->ls_trans; 1930 break; 1931 } 1932 } 1933 1934 /* Calculate the year, avoiding integer overflow even if 1935 time_t is unsigned. */ 1936 tdays = *timep / SECSPERDAY; 1937 rem = *timep % SECSPERDAY; 1938 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 1939 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 1940 rem %= SECSPERDAY; 1941 /* y = (EPOCH_YEAR 1942 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 1943 sans overflow. But calculate against 1570 (EPOCH_YEAR - 1944 YEARSPERREPEAT) instead of against 1970 so that things work 1945 for localtime values before 1970 when time_t is unsigned. */ 1946 dayrem = tdays % DAYSPERREPEAT; 1947 dayrem += dayoff % DAYSPERREPEAT; 1948 y = (EPOCH_YEAR - YEARSPERREPEAT 1949 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 1950 - ((dayrem % DAYSPERREPEAT) < 0) 1951 + tdays / DAYSPERREPEAT) 1952 * YEARSPERREPEAT)); 1953 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 1954 idays = tdays % DAYSPERREPEAT; 1955 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 1956 idays %= DAYSPERREPEAT; 1957 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 1958 while (year_lengths[isleap(y)] <= idays) { 1959 int tdelta = idays / DAYSPERLYEAR; 1960 int_fast32_t ydelta = tdelta + !tdelta; 1961 time_t newy = y + ydelta; 1962 register int leapdays; 1963 leapdays = leaps_thru_end_of(newy - 1) - 1964 leaps_thru_end_of(y - 1); 1965 idays -= ydelta * DAYSPERNYEAR; 1966 idays -= leapdays; 1967 y = newy; 1968 } 1969 1970 #ifdef ckd_add 1971 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 1972 errno = EOVERFLOW; 1973 return NULL; 1974 } 1975 #else 1976 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 1977 int signed_y = y; 1978 tmp->tm_year = signed_y - TM_YEAR_BASE; 1979 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 1980 && y - TM_YEAR_BASE <= INT_MAX) 1981 tmp->tm_year = y - TM_YEAR_BASE; 1982 else { 1983 errno = EOVERFLOW; 1984 return NULL; 1985 } 1986 #endif 1987 tmp->tm_yday = idays; 1988 /* 1989 ** The "extra" mods below avoid overflow problems. 1990 */ 1991 tmp->tm_wday = (TM_WDAY_BASE 1992 + ((tmp->tm_year % DAYSPERWEEK) 1993 * (DAYSPERNYEAR % DAYSPERWEEK)) 1994 + leaps_thru_end_of(y - 1) 1995 - leaps_thru_end_of(TM_YEAR_BASE - 1) 1996 + idays); 1997 tmp->tm_wday %= DAYSPERWEEK; 1998 if (tmp->tm_wday < 0) 1999 tmp->tm_wday += DAYSPERWEEK; 2000 tmp->tm_hour = rem / SECSPERHOUR; 2001 rem %= SECSPERHOUR; 2002 tmp->tm_min = rem / SECSPERMIN; 2003 tmp->tm_sec = rem % SECSPERMIN; 2004 2005 /* Use "... ??:??:60" at the end of the localtime minute containing 2006 the second just before the positive leap second. */ 2007 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2008 2009 ip = mon_lengths[isleap(y)]; 2010 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2011 idays -= ip[tmp->tm_mon]; 2012 tmp->tm_mday = idays + 1; 2013 tmp->tm_isdst = 0; 2014 #ifdef TM_GMTOFF 2015 tmp->TM_GMTOFF = offset; 2016 #endif /* defined TM_GMTOFF */ 2017 return tmp; 2018 } 2019 2020 /* 2021 ** Adapted from code provided by Robert Elz, who writes: 2022 ** The "best" way to do mktime I think is based on an idea of Bob 2023 ** Kridle's (so its said...) from a long time ago. 2024 ** It does a binary search of the time_t space. Since time_t's are 2025 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2026 ** would still be very reasonable). 2027 */ 2028 2029 #ifndef WRONG 2030 # define WRONG (-1) 2031 #endif /* !defined WRONG */ 2032 2033 /* 2034 ** Normalize logic courtesy Paul Eggert. 2035 */ 2036 2037 static bool 2038 increment_overflow(int *ip, int j) 2039 { 2040 #ifdef ckd_add 2041 return ckd_add(ip, *ip, j); 2042 #else 2043 register int const i = *ip; 2044 2045 /* 2046 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2047 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2048 ** If i < 0 there can only be overflow if i + j < INT_MIN 2049 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2050 */ 2051 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2052 return true; 2053 *ip += j; 2054 return false; 2055 #endif 2056 } 2057 2058 static bool 2059 increment_overflow32(int_fast32_t *const lp, int const m) 2060 { 2061 #ifdef ckd_add 2062 return ckd_add(lp, *lp, m); 2063 #else 2064 register int_fast32_t const l = *lp; 2065 2066 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) 2067 return true; 2068 *lp += m; 2069 return false; 2070 #endif 2071 } 2072 2073 static bool 2074 increment_overflow_time(time_t *tp, int_fast32_t j) 2075 { 2076 #ifdef ckd_add 2077 return ckd_add(tp, *tp, j); 2078 #else 2079 /* 2080 ** This is like 2081 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2082 ** except that it does the right thing even if *tp + j would overflow. 2083 */ 2084 if (! (j < 0 2085 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2086 : *tp <= TIME_T_MAX - j)) 2087 return true; 2088 *tp += j; 2089 return false; 2090 #endif 2091 } 2092 2093 static bool 2094 normalize_overflow(int *const tensptr, int *const unitsptr, const int base) 2095 { 2096 register int tensdelta; 2097 2098 tensdelta = (*unitsptr >= 0) ? 2099 (*unitsptr / base) : 2100 (-1 - (-1 - *unitsptr) / base); 2101 *unitsptr -= tensdelta * base; 2102 return increment_overflow(tensptr, tensdelta); 2103 } 2104 2105 static bool 2106 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base) 2107 { 2108 register int tensdelta; 2109 2110 tensdelta = (*unitsptr >= 0) ? 2111 (*unitsptr / base) : 2112 (-1 - (-1 - *unitsptr) / base); 2113 *unitsptr -= tensdelta * base; 2114 return increment_overflow32(tensptr, tensdelta); 2115 } 2116 2117 static int 2118 tmcomp(register const struct tm *const atmp, 2119 register const struct tm *const btmp) 2120 { 2121 register int result; 2122 2123 if (atmp->tm_year != btmp->tm_year) 2124 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2125 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2126 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2127 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2128 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2129 result = atmp->tm_sec - btmp->tm_sec; 2130 return result; 2131 } 2132 2133 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2134 as other members might not be initialized. */ 2135 static void 2136 mktmcpy(struct tm *dest, struct tm const *src) 2137 { 2138 dest->tm_sec = src->tm_sec; 2139 dest->tm_min = src->tm_min; 2140 dest->tm_hour = src->tm_hour; 2141 dest->tm_mday = src->tm_mday; 2142 dest->tm_mon = src->tm_mon; 2143 dest->tm_year = src->tm_year; 2144 dest->tm_isdst = src->tm_isdst; 2145 #if defined TM_GMTOFF && ! UNINIT_TRAP 2146 dest->TM_GMTOFF = src->TM_GMTOFF; 2147 #endif 2148 } 2149 2150 static time_t 2151 time2sub(struct tm *const tmp, 2152 struct tm *(*funcp)(struct state const *, time_t const *, 2153 int_fast32_t, struct tm *), 2154 struct state const *sp, 2155 const int_fast32_t offset, 2156 bool *okayp, 2157 bool do_norm_secs) 2158 { 2159 register int dir; 2160 register int i, j; 2161 register int saved_seconds; 2162 register int_fast32_t li; 2163 register time_t lo; 2164 register time_t hi; 2165 int_fast32_t y; 2166 time_t newt; 2167 time_t t; 2168 struct tm yourtm, mytm; 2169 2170 *okayp = false; 2171 mktmcpy(&yourtm, tmp); 2172 2173 if (do_norm_secs) { 2174 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 2175 SECSPERMIN)) 2176 return WRONG; 2177 } 2178 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 2179 return WRONG; 2180 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 2181 return WRONG; 2182 y = yourtm.tm_year; 2183 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) 2184 return WRONG; 2185 /* 2186 ** Turn y into an actual year number for now. 2187 ** It is converted back to an offset from TM_YEAR_BASE later. 2188 */ 2189 if (increment_overflow32(&y, TM_YEAR_BASE)) 2190 return WRONG; 2191 while (yourtm.tm_mday <= 0) { 2192 if (increment_overflow32(&y, -1)) 2193 return WRONG; 2194 li = y + (1 < yourtm.tm_mon); 2195 yourtm.tm_mday += year_lengths[isleap(li)]; 2196 } 2197 while (yourtm.tm_mday > DAYSPERLYEAR) { 2198 li = y + (1 < yourtm.tm_mon); 2199 yourtm.tm_mday -= year_lengths[isleap(li)]; 2200 if (increment_overflow32(&y, 1)) 2201 return WRONG; 2202 } 2203 for ( ; ; ) { 2204 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2205 if (yourtm.tm_mday <= i) 2206 break; 2207 yourtm.tm_mday -= i; 2208 if (++yourtm.tm_mon >= MONSPERYEAR) { 2209 yourtm.tm_mon = 0; 2210 if (increment_overflow32(&y, 1)) 2211 return WRONG; 2212 } 2213 } 2214 #ifdef ckd_add 2215 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2216 return WRONG; 2217 #else 2218 if (increment_overflow32(&y, -TM_YEAR_BASE)) 2219 return WRONG; 2220 if (! (INT_MIN <= y && y <= INT_MAX)) 2221 return WRONG; 2222 yourtm.tm_year = y; 2223 #endif 2224 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2225 saved_seconds = 0; 2226 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2227 /* 2228 ** We can't set tm_sec to 0, because that might push the 2229 ** time below the minimum representable time. 2230 ** Set tm_sec to 59 instead. 2231 ** This assumes that the minimum representable time is 2232 ** not in the same minute that a leap second was deleted from, 2233 ** which is a safer assumption than using 58 would be. 2234 */ 2235 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 2236 return WRONG; 2237 saved_seconds = yourtm.tm_sec; 2238 yourtm.tm_sec = SECSPERMIN - 1; 2239 } else { 2240 saved_seconds = yourtm.tm_sec; 2241 yourtm.tm_sec = 0; 2242 } 2243 /* 2244 ** Do a binary search (this works whatever time_t's type is). 2245 */ 2246 lo = TIME_T_MIN; 2247 hi = TIME_T_MAX; 2248 for ( ; ; ) { 2249 t = lo / 2 + hi / 2; 2250 if (t < lo) 2251 t = lo; 2252 else if (t > hi) 2253 t = hi; 2254 if (! funcp(sp, &t, offset, &mytm)) { 2255 /* 2256 ** Assume that t is too extreme to be represented in 2257 ** a struct tm; arrange things so that it is less 2258 ** extreme on the next pass. 2259 */ 2260 dir = (t > 0) ? 1 : -1; 2261 } else dir = tmcomp(&mytm, &yourtm); 2262 if (dir != 0) { 2263 if (t == lo) { 2264 if (t == TIME_T_MAX) 2265 return WRONG; 2266 ++t; 2267 ++lo; 2268 } else if (t == hi) { 2269 if (t == TIME_T_MIN) 2270 return WRONG; 2271 --t; 2272 --hi; 2273 } 2274 if (lo > hi) 2275 return WRONG; 2276 if (dir > 0) 2277 hi = t; 2278 else lo = t; 2279 continue; 2280 } 2281 #if defined TM_GMTOFF && ! UNINIT_TRAP 2282 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2283 && (yourtm.TM_GMTOFF < 0 2284 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2285 && (mytm.TM_GMTOFF <= 2286 (min(INT_FAST32_MAX, LONG_MAX) 2287 + yourtm.TM_GMTOFF))) 2288 : (yourtm.TM_GMTOFF <= SECSPERDAY 2289 && ((max(INT_FAST32_MIN, LONG_MIN) 2290 + yourtm.TM_GMTOFF) 2291 <= mytm.TM_GMTOFF)))) { 2292 /* MYTM matches YOURTM except with the wrong UT offset. 2293 YOURTM.TM_GMTOFF is plausible, so try it instead. 2294 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2295 since the guess gets checked. */ 2296 time_t altt = t; 2297 int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF; 2298 if (!increment_overflow_time(&altt, diff)) { 2299 struct tm alttm; 2300 if (funcp(sp, &altt, offset, &alttm) 2301 && alttm.tm_isdst == mytm.tm_isdst 2302 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2303 && tmcomp(&alttm, &yourtm) == 0) { 2304 t = altt; 2305 mytm = alttm; 2306 } 2307 } 2308 } 2309 #endif 2310 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2311 break; 2312 /* 2313 ** Right time, wrong type. 2314 ** Hunt for right time, right type. 2315 ** It's okay to guess wrong since the guess 2316 ** gets checked. 2317 */ 2318 if (sp == NULL) 2319 return WRONG; 2320 for (i = sp->typecnt - 1; i >= 0; --i) { 2321 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2322 continue; 2323 for (j = sp->typecnt - 1; j >= 0; --j) { 2324 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2325 continue; 2326 if (ttunspecified(sp, j)) 2327 continue; 2328 newt = (t + sp->ttis[j].tt_utoff 2329 - sp->ttis[i].tt_utoff); 2330 if (! funcp(sp, &newt, offset, &mytm)) 2331 continue; 2332 if (tmcomp(&mytm, &yourtm) != 0) 2333 continue; 2334 if (mytm.tm_isdst != yourtm.tm_isdst) 2335 continue; 2336 /* 2337 ** We have a match. 2338 */ 2339 t = newt; 2340 goto label; 2341 } 2342 } 2343 return WRONG; 2344 } 2345 label: 2346 newt = t + saved_seconds; 2347 if ((newt < t) != (saved_seconds < 0)) 2348 return WRONG; 2349 t = newt; 2350 if (funcp(sp, &t, offset, tmp)) 2351 *okayp = true; 2352 return t; 2353 } 2354 2355 static time_t 2356 time2(struct tm * const tmp, 2357 struct tm *(*funcp)(struct state const *, time_t const *, 2358 int_fast32_t, struct tm *), 2359 struct state const *sp, 2360 const int_fast32_t offset, 2361 bool *okayp) 2362 { 2363 time_t t; 2364 2365 /* 2366 ** First try without normalization of seconds 2367 ** (in case tm_sec contains a value associated with a leap second). 2368 ** If that fails, try with normalization of seconds. 2369 */ 2370 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2371 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2372 } 2373 2374 static time_t 2375 time1(struct tm *const tmp, 2376 struct tm *(*funcp)(struct state const *, time_t const *, 2377 int_fast32_t, struct tm *), 2378 struct state const *sp, 2379 const int_fast32_t offset) 2380 { 2381 register time_t t; 2382 register int samei, otheri; 2383 register int sameind, otherind; 2384 register int i; 2385 register int nseen; 2386 char seen[TZ_MAX_TYPES]; 2387 unsigned char types[TZ_MAX_TYPES]; 2388 bool okay; 2389 2390 if (tmp == NULL) { 2391 errno = EINVAL; 2392 return WRONG; 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 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 disappear 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 disappear 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 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 /* DETECT_TZ_CHANGES */ 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 /* DETECT_TZ_CHANGES */ 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