localtime.c revision 1.144 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