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