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