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