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