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