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