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