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 HAVE_SYS_STAT_H
23 # include <sys/stat.h>
24 # ifndef S_ISREG
25 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) /* Ancient UNIX. */
26 # endif
27 #else
28 struct stat { char st_ctime, st_dev, st_ino; };
29 # define dev_t char
30 # define ino_t char
31 # define fstat(fd, st) (memset(st, 0, sizeof *(st)), 0)
32 # define stat(name, st) fstat(0, st)
33 # define S_ISREG(mode) 1
34 #endif
35
36 #ifndef HAVE_STRUCT_STAT_ST_CTIM
37 # define HAVE_STRUCT_STAT_ST_CTIM 1
38 #endif
39 #if !defined st_ctim && defined __APPLE__ && defined __MACH__
40 # define st_ctim st_ctimespec
41 #endif
42
43 #ifndef THREAD_SAFE
44 # define THREAD_SAFE 0
45 #endif
46
47 #ifndef THREAD_RWLOCK
48 # define THREAD_RWLOCK 0
49 #endif
50
51 #ifndef THREAD_TM_MULTI
52 # define THREAD_TM_MULTI 0
53 #endif
54
55 #ifndef USE_TIMEX_T
56 # define USE_TIMEX_T false
57 #endif
58
59 #if THREAD_SAFE
60 # include <pthread.h>
61
62 # ifndef THREAD_PREFER_SINGLE
63 # define THREAD_PREFER_SINGLE 0
64 # endif
65 # if THREAD_PREFER_SINGLE
66 # ifndef HAVE___ISTHREADED
67 # if defined __FreeBSD__ || defined __OpenBSD__
68 # define HAVE___ISTHREADED 1
69 # else
70 # define HAVE___ISTHREADED 0
71 # endif
72 # endif
73 # if HAVE___ISTHREADED
74 extern int __isthreaded;
75 # else
76 # if !defined HAVE_SYS_SINGLE_THREADED_H && defined __has_include
77 # if __has_include(<sys/single_threaded.h>)
78 # define HAVE_SYS_SINGLE_THREADED_H 1
79 # else
80 # define HAVE_SYS_SINGLE_THREADED_H 0
81 # endif
82 # endif
83 # ifndef HAVE_SYS_SINGLE_THREADED_H
84 # if defined __GLIBC__ && 2 < __GLIBC__ + (32 <= __GLIBC_MINOR__)
85 # define HAVE_SYS_SINGLE_THREADED_H 1
86 # else
87 # define HAVE_SYS_SINGLE_THREADED_H 0
88 # endif
89 # endif
90 # if HAVE_SYS_SINGLE_THREADED_H
91 # include <sys/single_threaded.h>
92 # endif
93 # endif
94 # endif
95 #endif
96
97 #if !defined TM_GMTOFF || !USE_TIMEX_T
98 # if THREAD_SAFE
99
100 /* True if the current process might be multi-threaded,
101 false if it is definitely single-threaded.
102 If false, it will be false the next time it is called
103 unless the caller creates a thread in the meantime.
104 If true, it might become false the next time it is called
105 if all other threads exit in the meantime. */
106 static bool
is_threaded(void)107 is_threaded(void)
108 {
109 # if THREAD_PREFER_SINGLE && HAVE___ISTHREADED
110 return !!__isthreaded;
111 # elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H
112 return !__libc_single_threaded;
113 # else
114 return true;
115 # endif
116 }
117
118 # if THREAD_RWLOCK
119 static pthread_rwlock_t locallock = PTHREAD_RWLOCK_INITIALIZER;
dolock(void)120 static int dolock(void) { return pthread_rwlock_rdlock(&locallock); }
dounlock(void)121 static void dounlock(void) { pthread_rwlock_unlock(&locallock); }
122 # else
123 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
dolock(void)124 static int dolock(void) { return pthread_mutex_lock(&locallock); }
dounlock(void)125 static void dounlock(void) { pthread_mutex_unlock(&locallock); }
126 # endif
127
128 /* Get a lock. Return 0 on success, a positive errno value on failure,
129 negative if known to be single-threaded so no lock is needed. */
130 static int
lock(void)131 lock(void)
132 {
133 if (!is_threaded())
134 return -1;
135 return dolock();
136 }
137 static void
unlock(bool threaded)138 unlock(bool threaded)
139 {
140 if (threaded)
141 dounlock();
142 }
143 # else
lock(void)144 static int lock(void) { return -1; }
unlock(ATTRIBUTE_MAYBE_UNUSED bool threaded)145 static void unlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) { }
146 # endif
147 #endif
148
149 #if THREAD_SAFE
150 typedef pthread_once_t once_t;
151 # define ONCE_INIT PTHREAD_ONCE_INIT
152 #else
153 typedef bool once_t;
154 # define ONCE_INIT false
155 #endif
156
157 static void
once(once_t * once_control,void init_routine (void))158 once(once_t *once_control, void init_routine(void))
159 {
160 #if THREAD_SAFE
161 pthread_once(once_control, init_routine);
162 #else
163 if (!*once_control) {
164 *once_control = true;
165 init_routine();
166 }
167 #endif
168 }
169
170 enum tm_multi { LOCALTIME_TM_MULTI, GMTIME_TM_MULTI, OFFTIME_TM_MULTI };
171
172 #if THREAD_SAFE && THREAD_TM_MULTI
173
174 enum { N_TM_MULTI = OFFTIME_TM_MULTI + 1 };
175 static pthread_key_t tm_multi_key;
176 static int tm_multi_key_err;
177
178 static void
tm_multi_key_init(void)179 tm_multi_key_init(void)
180 {
181 tm_multi_key_err = pthread_key_create(&tm_multi_key, free);
182 }
183
184 #endif
185
186 /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs.
187 Use this carefully, as the casts disable type checking.
188 This is a macro so that it can be used in static initializers. */
189 #ifdef INTPTR_MAX
190 # define UNCONST(a) ((char *) (intptr_t) (a))
191 #else
192 # define UNCONST(a) ((char *) (a))
193 #endif
194
195 /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year
196 without overflow. The static_assert checks that it is indeed wider
197 than int; if this fails on your platform please let us know. */
198 #if INT_MAX < LONG_MAX
199 typedef long iinntt;
200 # define IINNTT_MIN LONG_MIN
201 # define IINNTT_MAX LONG_MAX
202 #elif INT_MAX < LLONG_MAX
203 typedef long long iinntt;
204 # define IINNTT_MIN LLONG_MIN
205 # define IINNTT_MAX LLONG_MAX
206 #else
207 typedef intmax_t iinntt;
208 # define IINNTT_MIN INTMAX_MIN
209 # define IINNTT_MAX INTMAX_MAX
210 #endif
211 static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX);
212
213 #ifndef HAVE_STRUCT_TIMESPEC
214 # define HAVE_STRUCT_TIMESPEC 1
215 #endif
216 #if !HAVE_STRUCT_TIMESPEC
217 struct timespec { time_t tv_sec; long tv_nsec; };
218 #endif
219
220 #if !defined CLOCK_MONOTONIC_COARSE && defined CLOCK_MONOTONIC
221 # define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
222 #endif
223 #ifndef CLOCK_MONOTONIC_COARSE
224 # undef clock_gettime
225 # define clock_gettime(id, t) ((t)->tv_sec = time(NULL), (t)->tv_nsec = 0, 0)
226 #endif
227
228 /* How many seconds to wait before checking the default TZif file again.
229 Negative means no checking. Default to 61 if DETECT_TZ_CHANGES
230 (as FreeBSD optionally builds its localtime.c with -DDETECT_TZ_CHANGES),
231 and to -1 otherwise. */
232 #ifndef TZ_CHANGE_INTERVAL
233 # ifdef DETECT_TZ_CHANGES
234 # define TZ_CHANGE_INTERVAL 61
235 # else
236 # define TZ_CHANGE_INTERVAL (-1)
237 # endif
238 #endif
239 static_assert(TZ_CHANGE_INTERVAL < 0 || HAVE_SYS_STAT_H);
240
241 /* The change detection interval. */
242 #if TZ_CHANGE_INTERVAL < 0 || !defined __FreeBSD__
243 enum { tz_change_interval = TZ_CHANGE_INTERVAL };
244 #else
245 /* FreeBSD uses this private-but-extern var in its internal test suite. */
246 int __tz_change_interval = TZ_CHANGE_INTERVAL;
247 # define tz_change_interval __tz_change_interval
248 #endif
249
250 /* The type of monotonic times.
251 This is the system time_t, even if USE_TIMEX_T #defines time_t below. */
252 typedef time_t monotime_t;
253
254 /* On platforms where offtime or mktime might overflow,
255 strftime.c defines USE_TIMEX_T to be true and includes us.
256 This tells us to #define time_t to an internal type timex_t that is
257 wide enough so that strftime %s never suffers from integer overflow,
258 and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise)
259 to a static function that returns the redefined time_t.
260 It also tells us to define only data and code needed
261 to support the offtime or mktime variant. */
262 #if USE_TIMEX_T
263 # undef TIME_T_MIN
264 # undef TIME_T_MAX
265 # undef time_t
266 # define time_t timex_t
267 # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX)
268 typedef long timex_t;
269 # define TIME_T_MIN LONG_MIN
270 # define TIME_T_MAX LONG_MAX
271 # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX)
272 typedef long long timex_t;
273 # define TIME_T_MIN LLONG_MIN
274 # define TIME_T_MAX LLONG_MAX
275 # else
276 typedef intmax_t timex_t;
277 # define TIME_T_MIN INTMAX_MIN
278 # define TIME_T_MAX INTMAX_MAX
279 # endif
280
281 # ifdef TM_GMTOFF
282 # undef timeoff
283 # define timeoff timex_timeoff
284 # undef EXTERN_TIMEOFF
285 # else
286 # undef mktime
287 # define mktime timex_mktime
288 # endif
289 #endif
290
291 /* Placeholders for platforms lacking AT_FCWD, openat, and fstatat. */
292 #ifndef AT_FDCWD
293 # define AT_FDCWD (-1) /* any negative value will do */
openat(int dd,char const * path,int oflag)294 static int openat(int dd, char const *path, int oflag) { unreachable (); }
fstatat(int dd,char const * path,struct stat * st,int flags)295 static int fstatat(int dd, char const *path, struct stat *st, int flags)
296 { unreachable(); }
297 #endif
298
299 /* Port to platforms that lack some O_* flags. Unless otherwise
300 specified, the flags are standardized by POSIX. */
301
302 #ifndef O_BINARY
303 # define O_BINARY 0 /* MS-Windows */
304 #endif
305 #ifndef O_CLOEXEC
306 # define O_CLOEXEC 0
307 #endif
308 #ifndef O_CLOFORK
309 # define O_CLOFORK 0
310 #endif
311 #ifndef O_DIRECTORY
312 # define O_DIRECTORY 0
313 #endif
314 #ifndef O_IGNORE_CTTY
315 # define O_IGNORE_CTTY 0 /* GNU/Hurd */
316 #endif
317 #ifndef O_NOCTTY
318 # define O_NOCTTY 0
319 #endif
320 #ifndef O_PATH
321 # define O_PATH 0
322 #endif
323 #ifndef O_REGULAR
324 # define O_REGULAR 0
325 #endif
326 #ifndef O_RESOLVE_BENEATH
327 # define O_RESOLVE_BENEATH 0
328 #endif
329 #ifndef O_SEARCH
330 # define O_SEARCH 0
331 #endif
332
333 #if !HAVE_ISSETUGID
334
335 # if !defined HAVE_SYS_AUXV_H && defined __has_include
336 # if __has_include(<sys/auxv.h>)
337 # define HAVE_SYS_AUXV_H 1
338 # endif
339 # endif
340 # ifndef HAVE_SYS_AUXV_H
341 # if defined __GLIBC__ && 2 < __GLIBC__ + (19 <= __GLIBC_MINOR__)
342 # define HAVE_SYS_AUXV_H 1
343 # else
344 # define HAVE_SYS_AUXV_H 0
345 # endif
346 # endif
347 # if HAVE_SYS_AUXV_H
348 # include <sys/auxv.h>
349 # endif
350
351 /* Return 1 if the process is privileged, 0 otherwise. */
352 static int
issetugid(void)353 issetugid(void)
354 {
355 # if HAVE_SYS_AUXV_H && defined AT_SECURE
356 unsigned long val;
357 errno = 0;
358 val = getauxval(AT_SECURE);
359 if (val || errno != ENOENT)
360 return !!val;
361 # endif
362 # if HAVE_GETRESUID
363 {
364 uid_t ruid, euid, suid;
365 gid_t rgid, egid, sgid;
366 if (0 <= getresuid (&ruid, &euid, &suid)) {
367 if ((ruid ^ euid) | (ruid ^ suid))
368 return 1;
369 if (0 <= getresgid (&rgid, &egid, &sgid))
370 return !!((rgid ^ egid) | (rgid ^ sgid));
371 }
372 }
373 # endif
374 # if HAVE_GETEUID
375 return geteuid() != getuid() || getegid() != getgid();
376 # else
377 return 0;
378 # endif
379 }
380 #endif
381
382 #ifndef WILDABBR
383 /*
384 ** Someone might make incorrect use of a time zone abbreviation:
385 ** 1. They might reference tzname[0] before calling tzset (explicitly
386 ** or implicitly).
387 ** 2. They might reference tzname[1] before calling tzset (explicitly
388 ** or implicitly).
389 ** 3. They might reference tzname[1] after setting to a time zone
390 ** in which Daylight Saving Time is never observed.
391 ** 4. They might reference tzname[0] after setting to a time zone
392 ** in which Standard Time is never observed.
393 ** 5. They might reference tm.TM_ZONE after calling offtime.
394 ** What's best to do in the above cases is open to debate;
395 ** for now, we just set things up so that in any of the five cases
396 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
397 ** string "tzname[0] used before set", and similarly for the other cases.
398 ** And another: initialize tzname[0] to "ERA", with an explanation in the
399 ** manual page of what this "time zone abbreviation" means (doing this so
400 ** that tzname[0] has the "normal" length of three characters).
401 */
402 # define WILDABBR " "
403 #endif /* !defined WILDABBR */
404
405 static const char wildabbr[] = WILDABBR;
406
407 static char const etc_utc[] = "Etc/UTC";
408
409 #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF
410 static char const *utc = etc_utc + sizeof "Etc/" - 1;
411 #endif
412
413 /*
414 ** The DST rules to use if TZ has no rules.
415 ** Default to US rules as of 2017-05-07.
416 ** POSIX does not specify the default DST rules;
417 ** for historical reasons, US rules are a common default.
418 */
419 #ifndef TZDEFRULESTRING
420 # define TZDEFRULESTRING ",M3.2.0,M11.1.0"
421 #endif
422
423 /* If compiled with -DOPENAT_TZDIR, then when accessing a relative
424 name like "America/Los_Angeles", first open TZDIR (default
425 "/usr/share/zoneinfo") as a directory and then use the result in
426 openat with "America/Los_Angeles", rather than the traditional
427 approach of opening "/usr/share/zoneinfo/America/Los_Angeles".
428 Although the OPENAT_TZDIR approach is less efficient, suffers from
429 spurious EMFILE and ENFILE failures, and is no more secure in practice,
430 bleeding edge FreeBSD started doing it this way in August 2025. */
431 #ifndef OPENAT_TZDIR
432 # define OPENAT_TZDIR 0
433 #endif
434
435 /* If compiled with -DSUPPRESS_TZDIR, do not prepend TZDIR to relative TZ.
436 This is intended for specialized applications only, due to its
437 security implications. */
438 #ifndef SUPPRESS_TZDIR
439 # define SUPPRESS_TZDIR 0
440 #endif
441
442 /* Limit to time zone abbreviation length in proleptic TZ strings.
443 This is distinct from TZ_MAX_CHARS, which limits TZif file contents.
444 It defaults to 254, not 255, so that desigidx_type can be an unsigned char.
445 unsigned char suffices for TZif files, so the only reason to increase
446 TZNAME_MAXIMUM is to support TZ strings specifying abbreviations
447 longer than 254 bytes. There is little reason to do that, though,
448 as strings that long are hardly "abbreviations". */
449 #ifndef TZNAME_MAXIMUM
450 # define TZNAME_MAXIMUM 254
451 #endif
452
453 #if TZNAME_MAXIMUM < UCHAR_MAX
454 typedef unsigned char desigidx_type;
455 #elif TZNAME_MAXIMUM < INT_MAX
456 typedef int desigidx_type;
457 #elif TZNAME_MAXIMUM < PTRDIFF_MAX
458 typedef ptrdiff_t desigidx_type;
459 #else
460 # error "TZNAME_MAXIMUM too large"
461 #endif
462
463 /* A type that can represent any 32-bit two's complement integer,
464 i.e., any integer in the range -2**31 .. 2**31 - 1.
465 Ordinarily this is int_fast32_t, but on non-C23 hosts
466 that are not two's complement it is int_fast64_t. */
467 #if INT_FAST32_MIN < -TWO_31_MINUS_1
468 typedef int_fast32_t int_fast32_2s;
469 #else
470 typedef int_fast64_t int_fast32_2s;
471 #endif
472
473 struct ttinfo { /* time type information */
474 int_least32_t tt_utoff; /* UT offset in seconds; in the range
475 -2**31 + 1 .. 2**31 - 1 */
476 desigidx_type tt_desigidx; /* abbreviation list index */
477 bool tt_isdst; /* used to set tm_isdst */
478 bool tt_ttisstd; /* transition is std time */
479 bool tt_ttisut; /* transition is UT */
480 };
481
482 struct lsinfo { /* leap second information */
483 time_t ls_trans; /* transition time (positive) */
484 int_fast32_2s ls_corr; /* correction to apply */
485 };
486
487 /* This abbreviation means local time is unspecified. */
488 static char const UNSPEC[] = "-00";
489
490 /* How many extra bytes are needed at the end of struct state's chars array.
491 This needs to be at least 1 for null termination in case the input
492 data isn't properly terminated, and it also needs to be big enough
493 for ttunspecified to work without crashing. */
494 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
495
496 /* A representation of the contents of a TZif file. Ideally this
497 would have no size limits; the following sizes should suffice for
498 practical use. This struct should not be too large, as instances
499 are put on the stack and stacks are relatively small on some platforms.
500 See tzfile.h for more about the sizes. */
501 struct state {
502 #if TZ_RUNTIME_LEAPS
503 int leapcnt;
504 #endif
505 int timecnt;
506 int typecnt;
507 int charcnt;
508 bool goback;
509 bool goahead;
510 time_t ats[TZ_MAX_TIMES];
511 unsigned char types[TZ_MAX_TIMES];
512 struct ttinfo ttis[TZ_MAX_TYPES];
513 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
514 2 * (TZNAME_MAXIMUM + 1))];
515 #if TZ_RUNTIME_LEAPS
516 struct lsinfo lsis[TZ_MAX_LEAPS];
517 #endif
518 };
519
520 static int
leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const * sp)521 leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp)
522 {
523 #if TZ_RUNTIME_LEAPS
524 return sp->leapcnt;
525 #else
526 return 0;
527 #endif
528 }
529 static void
set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state * sp,ATTRIBUTE_MAYBE_UNUSED int leapcnt)530 set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp,
531 ATTRIBUTE_MAYBE_UNUSED int leapcnt)
532 {
533 #if TZ_RUNTIME_LEAPS
534 sp->leapcnt = leapcnt;
535 #endif
536 }
537 static struct lsinfo
lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const * sp,ATTRIBUTE_MAYBE_UNUSED int i)538 lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const *sp,
539 ATTRIBUTE_MAYBE_UNUSED int i)
540 {
541 #if TZ_RUNTIME_LEAPS
542 return sp->lsis[i];
543 #else
544 unreachable();
545 #endif
546 }
547 static void
set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state * sp,ATTRIBUTE_MAYBE_UNUSED int i,ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo)548 set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp,
549 ATTRIBUTE_MAYBE_UNUSED int i,
550 ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo)
551 {
552 #if TZ_RUNTIME_LEAPS
553 sp->lsis[i] = lsinfo;
554 #endif
555 }
556
557 enum r_type {
558 JULIAN_DAY, /* Jn = Julian day */
559 DAY_OF_YEAR, /* n = day of year */
560 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
561 };
562
563 struct rule {
564 enum r_type r_type; /* type of rule */
565 int r_day; /* day number of rule */
566 int r_week; /* week number of rule */
567 int r_mon; /* month number of rule */
568 int_fast32_t r_time; /* transition time of rule */
569 };
570
571 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
572 struct tm *);
573 static bool increment_overflow(int *, int);
574 static bool increment_overflow_time(time_t *, int_fast32_2s);
575 static int_fast32_2s leapcorr(struct state const *, time_t);
576 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
577 struct tm *);
578 static bool tzparse(char const *, struct state *, struct state const *);
579
580 #ifndef ALL_STATE
581 # define ALL_STATE 0
582 #endif
583
584 #if ALL_STATE
585 static struct state * lclptr;
586 static struct state * gmtptr;
587 #else
588 static struct state lclmem;
589 static struct state gmtmem;
590 static struct state *const lclptr = &lclmem;
591 static struct state *const gmtptr = &gmtmem;
592 #endif /* State Farm */
593
594 /* Maximum number of bytes in an efficiently-handled TZ string.
595 Longer strings work, albeit less efficiently. */
596 #ifndef TZ_STRLEN_MAX
597 # define TZ_STRLEN_MAX 255
598 #endif /* !defined TZ_STRLEN_MAX */
599
600 #if !USE_TIMEX_T || !defined TM_GMTOFF
601 static char lcl_TZname[TZ_STRLEN_MAX + 1];
602 static int lcl_is_set;
603 #endif
604
605 /*
606 ** Section 4.12.3 of X3.159-1989 requires that
607 ** Except for the strftime function, these functions [asctime,
608 ** ctime, gmtime, localtime] return values in one of two static
609 ** objects: a broken-down time structure and an array of char.
610 ** Thanks to Paul Eggert for noting this.
611 **
612 ** Although this requirement was removed in C99 it is still present in POSIX.
613 ** Follow the requirement if SUPPORT_C89, even though this is more likely to
614 ** trigger latent bugs in programs.
615 */
616
617 #if !USE_TIMEX_T
618
619 # if SUPPORT_C89
620 static struct tm tm;
621 # endif
622
623 # if 2 <= HAVE_TZNAME + TZ_TIME_T
624 char *tzname[2] = { UNCONST(wildabbr), UNCONST(wildabbr) };
625 # endif
626 # if 2 <= USG_COMPAT + TZ_TIME_T
627 long timezone;
628 int daylight;
629 # endif
630 # if 2 <= ALTZONE + TZ_TIME_T
631 long altzone;
632 # endif
633
634 #endif
635
636 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
637 static void
init_ttinfo(struct ttinfo * s,int_fast32_t utoff,bool isdst,desigidx_type desigidx)638 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst,
639 desigidx_type desigidx)
640 {
641 s->tt_utoff = utoff;
642 s->tt_isdst = isdst;
643 s->tt_desigidx = desigidx;
644 s->tt_ttisstd = false;
645 s->tt_ttisut = false;
646 }
647
648 /* Return true if SP's time type I does not specify local time. */
649 static bool
ttunspecified(struct state const * sp,int i)650 ttunspecified(struct state const *sp, int i)
651 {
652 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
653 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */
654 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
655 }
656
657 static int_fast32_2s
detzcode(const char * const codep)658 detzcode(const char *const codep)
659 {
660 register int i;
661 int_fast32_2s
662 maxval = TWO_31_MINUS_1,
663 minval = -1 - maxval,
664 result;
665
666 result = codep[0] & 0x7f;
667 for (i = 1; i < 4; ++i)
668 result = (result << 8) | (codep[i] & 0xff);
669
670 if (codep[0] & 0x80) {
671 /* Do two's-complement negation even on non-two's-complement machines.
672 This cannot overflow, as int_fast32_2s is wide enough. */
673 result += minval;
674 }
675 return result;
676 }
677
678 static int_fast64_t
detzcode64(const char * const codep)679 detzcode64(const char *const codep)
680 {
681 register int_fast64_t result;
682 register int i;
683 int_fast64_t one = 1;
684 int_fast64_t halfmaxval = one << (64 - 2);
685 int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
686 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
687
688 result = codep[0] & 0x7f;
689 for (i = 1; i < 8; ++i)
690 result = (result << 8) | (codep[i] & 0xff);
691
692 if (codep[0] & 0x80) {
693 /* Do two's-complement negation even on non-two's-complement machines.
694 If the result would be minval - 1, return minval. */
695 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
696 result += minval;
697 }
698 return result;
699 }
700
701 #if !USE_TIMEX_T || !defined TM_GMTOFF
702
703 static void
update_tzname_etc(struct state const * sp,struct ttinfo const * ttisp)704 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
705 {
706 # if HAVE_TZNAME
707 tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]);
708 # endif
709 # if USG_COMPAT
710 if (!ttisp->tt_isdst)
711 timezone = - ttisp->tt_utoff;
712 # endif
713 # if ALTZONE
714 if (ttisp->tt_isdst)
715 altzone = - ttisp->tt_utoff;
716 # endif
717 }
718
719 /* If STDDST_MASK indicates that SP's TYPE provides useful info,
720 update tzname, timezone, and/or altzone and return STDDST_MASK,
721 diminished by the provided info if it is a specified local time.
722 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */
723 static int
may_update_tzname_etc(int stddst_mask,struct state * sp,int type)724 may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
725 {
726 struct ttinfo *ttisp = &sp->ttis[type];
727 int this_bit = 1 << ttisp->tt_isdst;
728 if (stddst_mask & this_bit) {
729 update_tzname_etc(sp, ttisp);
730 if (!ttunspecified(sp, type))
731 return stddst_mask & ~this_bit;
732 }
733 return stddst_mask;
734 }
735
736 static void
settzname(void)737 settzname(void)
738 {
739 register struct state * const sp = lclptr;
740 register int i;
741
742 /* If STDDST_MASK & 1 we need info about a standard time.
743 If STDDST_MASK & 2 we need info about a daylight saving time.
744 When STDDST_MASK becomes zero we can stop looking. */
745 int stddst_mask = 0;
746
747 # if HAVE_TZNAME
748 tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc);
749 stddst_mask = 3;
750 # endif
751 # if USG_COMPAT
752 timezone = 0;
753 stddst_mask = 3;
754 # endif
755 # if ALTZONE
756 altzone = 0;
757 stddst_mask |= 2;
758 # endif
759 /*
760 ** And to get the latest time zone abbreviations into tzname. . .
761 */
762 if (sp) {
763 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
764 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
765 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
766 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
767 }
768 # if USG_COMPAT
769 daylight = stddst_mask >> 1 ^ 1;
770 # endif
771 }
772
773 /* Replace bogus characters in time zone abbreviations.
774 Return 0 on success, an errno value if a time zone abbreviation is
775 too long. */
776 static int
scrub_abbrs(struct state * sp)777 scrub_abbrs(struct state *sp)
778 {
779 int i;
780
781 /* Reject overlong abbreviations. */
782 for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
783 int len = strnlen(&sp->chars[i], TZNAME_MAXIMUM + 1);
784 if (TZNAME_MAXIMUM < len)
785 return EOVERFLOW;
786 i += len + 1;
787 }
788
789 /* Replace bogus characters. */
790 for (i = 0; i < sp->charcnt; ++i)
791 switch (sp->chars[i]) {
792 case '\0':
793 case '+': case '-': case '.':
794 case '0': case '1': case '2': case '3': case '4':
795 case '5': case '6': case '7': case '8': case '9':
796 case ':':
797 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
798 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
799 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
800 case 'V': case 'W': case 'X': case 'Y': case 'Z':
801 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
802 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
803 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
804 case 'v': case 'w': case 'x': case 'y': case 'z':
805 break;
806
807 default:
808 sp->chars[i] = '_';
809 break;
810 }
811
812 return 0;
813 }
814
815 #endif
816
817 /* Return true if the TZif file with descriptor FD changed,
818 or may have changed, since the last time we were called.
819 Return false if it did not change.
820 If *ST is valid it is the file's current status;
821 otherwise, update *ST to the status if possible. */
822 static bool
tzfile_changed(int fd,struct stat * st)823 tzfile_changed(int fd, struct stat *st)
824 {
825 /* If old_ctim.tv_sec, these variables hold the corresponding part
826 of the file's metadata the last time this function was called. */
827 static struct timespec old_ctim;
828 static dev_t old_dev;
829 static ino_t old_ino;
830
831 if (!st->st_ctime && fstat(fd, st) < 0) {
832 /* We do not know the file's state, so reset. */
833 old_ctim.tv_sec = 0;
834 return true;
835 } else {
836 /* Use the change time, as it changes more reliably; mod time can
837 be set back with futimens etc. Use subsecond timestamp
838 resolution if available, as this can help distinguish files on
839 non-POSIX platforms where st_dev and st_ino are unreliable. */
840 struct timespec ctim;
841 #if HAVE_STRUCT_STAT_ST_CTIM
842 ctim = st->st_ctim;
843 #else
844 ctim.tv_sec = st->st_ctime;
845 ctim.tv_nsec = 0;
846 #endif
847
848 if ((ctim.tv_sec ^ old_ctim.tv_sec) | (ctim.tv_nsec ^ old_ctim.tv_nsec)
849 | (st->st_dev ^ old_dev) | (st->st_ino ^ old_ino)) {
850 old_ctim = ctim;
851 old_dev = st->st_dev;
852 old_ino = st->st_ino;
853 return true;
854 }
855
856 return false;
857 }
858 }
859
860 /* Input buffer for data read from a compiled tz file. */
861 union input_buffer {
862 /* The first part of the buffer, interpreted as a header. */
863 struct tzhead tzhead;
864
865 /* The entire buffer. Ideally this would have no size limits;
866 the following should suffice for practical use. */
867 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
868 + 4 * TZ_MAX_TIMES];
869 };
870
871 /* TZDIR with a trailing '/'. It is null-terminated if OPENAT_TZDIR. */
872 #if !OPENAT_TZDIR
873 ATTRIBUTE_NONSTRING
874 #endif
875 static char const tzdirslash[sizeof TZDIR + OPENAT_TZDIR] = TZDIR "/";
876 enum { tzdirslashlen = sizeof TZDIR };
877 #ifdef PATH_MAX
878 static_assert(tzdirslashlen <= PATH_MAX); /* Sanity check; assumed below. */
879 #endif
880
881 /* Local storage needed for 'tzloadbody'. */
882 union local_storage {
883 /* The results of analyzing the file's contents after it is opened. */
884 struct file_analysis {
885 /* The input buffer. */
886 union input_buffer u;
887
888 /* A temporary state used for parsing a TZ string in the file. */
889 struct state st;
890 } u;
891
892 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR
893 /* The name of the file to be opened. */
894 char fullname[PATH_MAX];
895 #endif
896 };
897
898 /* These tzload flags can be ORed together, and fit into 'char'. */
899 enum { TZLOAD_FROMENV = 1 }; /* The TZ string came from the environment. */
900 enum { TZLOAD_TZSTRING = 2 }; /* Read any newline-surrounded TZ string. */
901 enum { TZLOAD_TZDIR_SUB = 4 }; /* TZ should be a file under TZDIR. */
902
903 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS.
904 Use **LSPP for temporary storage. Return 0 on
905 success, an errno value on failure. */
906 static int
tzloadbody(char const * name,struct state * sp,char tzloadflags,union local_storage ** lspp)907 tzloadbody(char const *name, struct state *sp, char tzloadflags,
908 union local_storage **lspp)
909 {
910 register int i;
911 register int fid;
912 register int stored;
913 register ssize_t nread;
914 char const *relname;
915 union local_storage *lsp = *lspp;
916 union input_buffer *up;
917 register int tzheadsize = sizeof(struct tzhead);
918 int dd = AT_FDCWD;
919 int oflags = (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK
920 | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR);
921 bool might_escape = false;
922 int err;
923 struct stat st;
924 st.st_ctime = 0;
925
926 sp->goback = sp->goahead = false;
927
928 if (! name) {
929 name = TZDEFAULT;
930 if (! name)
931 return EINVAL;
932 #ifdef __FreeBSD__
933 tzloadflags &= ~TZLOAD_FROMENV;
934 #endif /* __FreeBSD__ */
935 }
936
937 if (name[0] == ':')
938 ++name;
939
940 relname = name;
941
942 /* If the program is privileged, NAME is TZDEFAULT or
943 subsidiary to TZDIR. Also, NAME is not a device. */
944 if (name[0] == '/' && strcmp(name, TZDEFAULT) != 0) {
945 if (!SUPPRESS_TZDIR
946 && strncmp(relname, tzdirslash, tzdirslashlen) == 0)
947 for (relname += tzdirslashlen; *relname == '/'; relname++)
948 continue;
949 else if (issetugid())
950 return ENOTCAPABLE;
951 else
952 might_escape = true;
953 }
954
955 if (relname[0] != '/') {
956 if (!OPENAT_TZDIR || !O_RESOLVE_BENEATH) {
957 /* Fail if a relative name contains a non-terminal ".." component,
958 as such a name could read a non-directory outside TZDIR
959 when AT_FDCWD and O_RESOLVE_BENEATH are not available. */
960 char const *component;
961 for (component = relname; component[0]; component++)
962 if (component[0] == '.' && component[1] == '.'
963 && component[2] == '/'
964 && (component == relname || component[-1] == '/')) {
965 if (issetugid())
966 return ENOTCAPABLE;
967 might_escape = true;
968 break;
969 }
970 }
971
972 if (OPENAT_TZDIR && !SUPPRESS_TZDIR) {
973 /* Prefer O_SEARCH or O_PATH if available;
974 O_RDONLY should be OK too, as TZDIR is invariably readable.
975 O_DIRECTORY should be redundant but might help
976 on old platforms that mishandle trailing '/'. */
977 dd = open(tzdirslash,
978 ((O_SEARCH ? O_SEARCH : O_PATH ? O_PATH : O_RDONLY)
979 | O_BINARY | O_CLOEXEC | O_CLOFORK | O_DIRECTORY));
980 if (dd < 0)
981 return errno;
982 if (O_RESOLVE_BENEATH && issetugid()) {
983 oflags |= O_RESOLVE_BENEATH;
984 might_escape = false;
985 }
986 }
987 }
988
989 if (!OPENAT_TZDIR && !SUPPRESS_TZDIR && name[0] != '/') {
990 char *cp;
991 size_t fullnamesize;
992 #ifdef PATH_MAX
993 size_t namesizemax = PATH_MAX - tzdirslashlen;
994 size_t namelen = strnlen (name, namesizemax);
995 if (namesizemax <= namelen)
996 return ENAMETOOLONG;
997 #else
998 size_t namelen = strlen (name);
999 #endif
1000 fullnamesize = tzdirslashlen + namelen + 1;
1001
1002 /* Create a string "TZDIR/NAME". Using sprintf here
1003 would pull in stdio (and would fail if the
1004 resulting string length exceeded INT_MAX!). */
1005 if (ALL_STATE || sizeof *lsp < fullnamesize) {
1006 lsp = malloc(max(sizeof *lsp, fullnamesize));
1007 if (!lsp)
1008 return HAVE_MALLOC_ERRNO ? errno : ENOMEM;
1009 *lspp = lsp;
1010 }
1011 cp = mempcpy(lsp, tzdirslash, tzdirslashlen);
1012 cp = mempcpy(cp, name, namelen);
1013 *cp = '\0';
1014 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR
1015 name = lsp->fullname;
1016 #else
1017 name = (char *) lsp;
1018 #endif
1019 }
1020
1021 /* For a platform that lacks O_REGULAR and a file that might
1022 be outside TZDIR, check that it is a regular file,
1023 as merely opening a device could have unwanted side effects.
1024 Though racy, there is no portable way to fix the race. */
1025 if (!O_REGULAR && might_escape) {
1026 /* (oflags & O_RESOLVE_BENEATH) must be zero here. */
1027 if ((OPENAT_TZDIR ? fstatat(dd, relname, &st, 0) : stat(name, &st))
1028 < 0)
1029 return errno;
1030 if (!S_ISREG(st.st_mode))
1031 return EFTYPE;
1032 }
1033 fid = OPENAT_TZDIR ? openat(dd, relname, oflags) : open(name, oflags);
1034 err = errno;
1035 if (0 <= dd)
1036 close(dd);
1037 if (fid < 0)
1038 return err;
1039
1040 /* If detecting changes to the the primary TZif file's state and
1041 the file's status is unchanged, save time by returning now.
1042 Otherwise read the file's contents. Close the file either way. */
1043 if (0 <= tz_change_interval && (tzloadflags & TZLOAD_FROMENV)
1044 && !tzfile_changed(fid, &st))
1045 err = -1;
1046 else {
1047 if (ALL_STATE && !lsp) {
1048 lsp = malloc(sizeof *lsp);
1049 if (!lsp)
1050 return HAVE_MALLOC_ERRNO ? errno : ENOMEM;
1051 *lspp = lsp;
1052 }
1053 up = &lsp->u.u;
1054 nread = read(fid, up->buf, sizeof up->buf);
1055 err = tzheadsize <= nread ? 0 : nread < 0 ? errno : EFTYPE;
1056 }
1057 close(fid);
1058 if (err)
1059 return err < 0 ? 0 : err;
1060
1061 for (stored = 4; stored <= 8; stored *= 2) {
1062 char version = up->tzhead.tzh_version[0];
1063 bool skip_datablock = stored == 4 && version;
1064 int_fast32_t datablock_size;
1065 int_fast32_2s
1066 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt),
1067 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt),
1068 leapcnt = detzcode(up->tzhead.tzh_leapcnt),
1069 timecnt = detzcode(up->tzhead.tzh_timecnt),
1070 typecnt = detzcode(up->tzhead.tzh_typecnt),
1071 charcnt = detzcode(up->tzhead.tzh_charcnt);
1072 char const *p = up->buf + tzheadsize;
1073 /* Although tzfile(5) currently requires typecnt to be nonzero,
1074 support future formats that may allow zero typecnt
1075 in files that have a TZ string and no transitions. */
1076 if (! (0 <= leapcnt
1077 && leapcnt <= (TZ_RUNTIME_LEAPS ? TZ_MAX_LEAPS : 0)
1078 && 0 <= typecnt && typecnt <= TZ_MAX_TYPES
1079 && 0 <= timecnt && timecnt <= TZ_MAX_TIMES
1080 && 0 <= charcnt && charcnt <= TZ_MAX_CHARS
1081 && 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES
1082 && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES))
1083 return EFTYPE;
1084 datablock_size
1085 = (timecnt * stored /* ats */
1086 + timecnt /* types */
1087 + typecnt * 6 /* ttinfos */
1088 + charcnt /* chars */
1089 + leapcnt * (stored + 4) /* lsinfos */
1090 + ttisstdcnt /* ttisstds */
1091 + ttisutcnt); /* ttisuts */
1092 if (nread < tzheadsize + datablock_size)
1093 return EFTYPE;
1094 if (skip_datablock)
1095 p += datablock_size;
1096 else if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
1097 && (ttisutcnt == typecnt || ttisutcnt == 0)))
1098 return EFTYPE;
1099 else {
1100 int_fast64_t prevtr = -1;
1101 int_fast32_2s prevcorr;
1102 set_leapcount(sp, leapcnt);
1103 sp->timecnt = timecnt;
1104 sp->typecnt = typecnt;
1105 sp->charcnt = charcnt;
1106
1107 /* Read transitions, discarding those out of time_t range.
1108 But pretend the last transition before TIME_T_MIN
1109 occurred at TIME_T_MIN. */
1110 timecnt = 0;
1111 for (i = 0; i < sp->timecnt; ++i) {
1112 int_fast64_t at
1113 = stored == 4 ? detzcode(p) : detzcode64(p);
1114 sp->types[i] = at <= TIME_T_MAX;
1115 if (sp->types[i]) {
1116 time_t attime
1117 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
1118 ? TIME_T_MIN : at);
1119 if (timecnt && attime <= sp->ats[timecnt - 1]) {
1120 if (attime < sp->ats[timecnt - 1])
1121 return EFTYPE;
1122 sp->types[i - 1] = 0;
1123 timecnt--;
1124 }
1125 sp->ats[timecnt++] = attime;
1126 }
1127 p += stored;
1128 }
1129
1130 timecnt = 0;
1131 for (i = 0; i < sp->timecnt; ++i) {
1132 unsigned char typ = *p++;
1133 if (sp->typecnt <= typ)
1134 return EFTYPE;
1135 if (sp->types[i])
1136 sp->types[timecnt++] = typ;
1137 }
1138 sp->timecnt = timecnt;
1139 for (i = 0; i < sp->typecnt; ++i) {
1140 register struct ttinfo * ttisp;
1141 unsigned char isdst, desigidx;
1142 int_fast32_2s utoff = detzcode(p);
1143
1144 /* Reject a UT offset equal to -2**31, as it might
1145 cause trouble both in this file and in callers.
1146 Also, it violates RFC 9636 section 3.2. */
1147 if (utoff < -TWO_31_MINUS_1)
1148 return EFTYPE;
1149
1150 ttisp = &sp->ttis[i];
1151 ttisp->tt_utoff = utoff;
1152 p += 4;
1153 isdst = *p++;
1154 if (! (isdst < 2))
1155 return EFTYPE;
1156 ttisp->tt_isdst = isdst;
1157 desigidx = *p++;
1158 if (! (desigidx < sp->charcnt))
1159 return EFTYPE;
1160 ttisp->tt_desigidx = desigidx;
1161 }
1162 for (i = 0; i < sp->charcnt; ++i)
1163 sp->chars[i] = *p++;
1164 /* Ensure '\0'-terminated, and make it safe to call
1165 ttunspecified later. */
1166 memset(&sp->chars[i], 0, CHARS_EXTRA);
1167
1168 /* Read leap seconds, discarding those out of time_t range. */
1169 leapcnt = 0;
1170 for (i = 0; i < leapcount(sp); i++) {
1171 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
1172 int_fast32_2s corr = detzcode(p + stored);
1173 p += stored + 4;
1174
1175 /* Leap seconds cannot occur before the Epoch,
1176 or out of order. */
1177 if (tr <= prevtr)
1178 return EFTYPE;
1179
1180 /* To avoid other botches in this code, each leap second's
1181 correction must differ from the previous one's by 1
1182 second or less, except that the first correction can be
1183 any value; these requirements are more generous than
1184 RFC 9636, to allow future RFC extensions. */
1185 if (! (i == 0
1186 || (prevcorr < corr
1187 ? corr == prevcorr + 1
1188 : (corr == prevcorr
1189 || corr == prevcorr - 1))))
1190 return EFTYPE;
1191 prevtr = tr;
1192 prevcorr = corr;
1193
1194 if (tr <= TIME_T_MAX) {
1195 struct lsinfo ls;
1196 ls.ls_trans = tr;
1197 ls.ls_corr = corr;
1198 set_lsinfo(sp, leapcnt, ls);
1199 leapcnt++;
1200 }
1201 }
1202 set_leapcount(sp, leapcnt);
1203
1204 for (i = 0; i < sp->typecnt; ++i) {
1205 register struct ttinfo * ttisp;
1206
1207 ttisp = &sp->ttis[i];
1208 if (ttisstdcnt == 0)
1209 ttisp->tt_ttisstd = false;
1210 else {
1211 if (*p != true && *p != false)
1212 return EFTYPE;
1213 ttisp->tt_ttisstd = *p++;
1214 }
1215 }
1216 for (i = 0; i < sp->typecnt; ++i) {
1217 register struct ttinfo * ttisp;
1218
1219 ttisp = &sp->ttis[i];
1220 if (ttisutcnt == 0)
1221 ttisp->tt_ttisut = false;
1222 else {
1223 if (*p != true && *p != false)
1224 return EFTYPE;
1225 ttisp->tt_ttisut = *p++;
1226 }
1227 }
1228 }
1229
1230 nread -= p - up->buf;
1231 memmove(up->buf, p, nread);
1232
1233 /* If this is an old file, we're done. */
1234 if (!version)
1235 break;
1236 }
1237 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 &&
1238 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
1239 sp->typecnt + 2 <= TZ_MAX_TYPES) {
1240 struct state *ts = &lsp->u.st;
1241
1242 up->buf[nread - 1] = '\0';
1243 if (tzparse(&up->buf[1], ts, sp)) {
1244
1245 /* Attempt to reuse existing abbreviations.
1246 Without this, America/Anchorage would
1247 consume 50 bytes for abbreviations, as
1248 sp->charcnt equals 40 (for LMT AST AWT APT AHST
1249 AHDT YST AKDT AKST) and ts->charcnt equals 10
1250 (for AKST AKDT). Reusing means sp->charcnt can
1251 stay 40 in this example. */
1252 int gotabbr = 0;
1253 int charcnt = sp->charcnt;
1254 for (i = 0; i < ts->typecnt; i++) {
1255 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
1256 int j;
1257 for (j = 0; j < charcnt; j++)
1258 if (strcmp(sp->chars + j, tsabbr) == 0) {
1259 ts->ttis[i].tt_desigidx = j;
1260 gotabbr++;
1261 break;
1262 }
1263 if (! (j < charcnt)) {
1264 int tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j);
1265 if (j + tsabbrlen < TZ_MAX_CHARS) {
1266 char *cp = sp->chars + j;
1267 cp = mempcpy(cp, tsabbr, tsabbrlen);
1268 *cp = '\0';
1269 charcnt = j + tsabbrlen + 1;
1270 ts->ttis[i].tt_desigidx = j;
1271 gotabbr++;
1272 }
1273 }
1274 }
1275 if (gotabbr == ts->typecnt) {
1276 sp->charcnt = charcnt;
1277
1278 /* Ignore any trailing, no-op transitions generated
1279 by zic as they don't help here and can run afoul
1280 of bugs in zic 2016j or earlier. */
1281 while (1 < sp->timecnt
1282 && (sp->types[sp->timecnt - 1]
1283 == sp->types[sp->timecnt - 2]))
1284 sp->timecnt--;
1285
1286 sp->goahead = ts->goahead;
1287
1288 for (i = 0; i < ts->timecnt; i++) {
1289 time_t t = ts->ats[i];
1290 if (increment_overflow_time(&t, leapcorr(sp, t))
1291 || (0 < sp->timecnt
1292 && t <= sp->ats[sp->timecnt - 1]))
1293 continue;
1294 if (TZ_MAX_TIMES <= sp->timecnt) {
1295 sp->goahead = false;
1296 break;
1297 }
1298 sp->ats[sp->timecnt] = t;
1299 sp->types[sp->timecnt] = (sp->typecnt
1300 + ts->types[i]);
1301 sp->timecnt++;
1302 }
1303 for (i = 0; i < ts->typecnt; i++)
1304 sp->ttis[sp->typecnt++] = ts->ttis[i];
1305 }
1306 }
1307 }
1308 if (sp->typecnt == 0)
1309 return EFTYPE;
1310
1311 return 0;
1312 }
1313
1314 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS.
1315 Return 0 on success, an errno value on failure. */
1316 static int
tzload(char const * name,struct state * sp,char tzloadflags)1317 tzload(char const *name, struct state *sp, char tzloadflags)
1318 {
1319 int r;
1320 union local_storage *lsp0;
1321 union local_storage *lsp;
1322 #if ALL_STATE
1323 lsp = NULL;
1324 #else
1325 union local_storage ls;
1326 lsp = &ls;
1327 #endif
1328 lsp0 = lsp;
1329 r = tzloadbody(name, sp, tzloadflags, &lsp);
1330 if (lsp != lsp0)
1331 free(lsp);
1332 return r;
1333 }
1334
1335 static const int mon_lengths[2][MONSPERYEAR] = {
1336 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
1337 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
1338 };
1339
1340 static const int year_lengths[2] = {
1341 DAYSPERNYEAR, DAYSPERLYEAR
1342 };
1343
1344 /* Is C an ASCII digit? */
1345 static bool
is_digit(char c)1346 is_digit(char c)
1347 {
1348 return '0' <= c && c <= '9';
1349 }
1350
1351 /*
1352 ** Given a pointer into a timezone string, scan until a character that is not
1353 ** a valid character in a time zone abbreviation is found.
1354 ** Return a pointer to that character.
1355 */
1356
1357 ATTRIBUTE_PURE_114833 static const char *
getzname(register const char * strp)1358 getzname(register const char *strp)
1359 {
1360 register char c;
1361
1362 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
1363 c != '+')
1364 ++strp;
1365 return strp;
1366 }
1367
1368 /*
1369 ** Given a pointer into an extended timezone string, scan until the ending
1370 ** delimiter of the time zone abbreviation is located.
1371 ** Return a pointer to the delimiter.
1372 **
1373 ** As with getzname above, the legal character set is actually quite
1374 ** restricted, with other characters producing undefined results.
1375 ** We don't do any checking here; checking is done later in common-case code.
1376 */
1377
1378 ATTRIBUTE_PURE_114833 static const char *
getqzname(register const char * strp,const int delim)1379 getqzname(register const char *strp, const int delim)
1380 {
1381 register int c;
1382
1383 while ((c = *strp) != '\0' && c != delim)
1384 ++strp;
1385 return strp;
1386 }
1387
1388 /*
1389 ** Given a pointer into a timezone string, extract a number from that string.
1390 ** Check that the number is within a specified range; if it is not, return
1391 ** NULL.
1392 ** Otherwise, return a pointer to the first character not part of the number.
1393 */
1394
1395 static const char *
getnum(register const char * strp,int * const nump,const int min,const int max)1396 getnum(register const char *strp, int *const nump, const int min, const int max)
1397 {
1398 register char c;
1399 register int num;
1400
1401 if (strp == NULL || !is_digit(c = *strp))
1402 return NULL;
1403 num = 0;
1404 do {
1405 num = num * 10 + (c - '0');
1406 if (num > max)
1407 return NULL; /* illegal value */
1408 c = *++strp;
1409 } while (is_digit(c));
1410 if (num < min)
1411 return NULL; /* illegal value */
1412 *nump = num;
1413 return strp;
1414 }
1415
1416 /*
1417 ** Given a pointer into a timezone string, extract a number of seconds,
1418 ** in hh[:mm[:ss]] form, from the string.
1419 ** If any error occurs, return NULL.
1420 ** Otherwise, return a pointer to the first character not part of the number
1421 ** of seconds.
1422 */
1423
1424 static const char *
getsecs(register const char * strp,int_fast32_t * const secsp)1425 getsecs(register const char *strp, int_fast32_t *const secsp)
1426 {
1427 int num;
1428 int_fast32_t secsperhour = SECSPERHOUR;
1429
1430 /*
1431 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
1432 ** "M10.4.6/26", which does not conform to POSIX,
1433 ** but which specifies the equivalent of
1434 ** "02:00 on the first Sunday on or after 23 Oct".
1435 */
1436 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
1437 if (strp == NULL)
1438 return NULL;
1439 *secsp = num * secsperhour;
1440 if (*strp == ':') {
1441 ++strp;
1442 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
1443 if (strp == NULL)
1444 return NULL;
1445 *secsp += num * SECSPERMIN;
1446 if (*strp == ':') {
1447 ++strp;
1448 /* 'SECSPERMIN' allows for leap seconds. */
1449 strp = getnum(strp, &num, 0, SECSPERMIN);
1450 if (strp == NULL)
1451 return NULL;
1452 *secsp += num;
1453 }
1454 }
1455 return strp;
1456 }
1457
1458 /*
1459 ** Given a pointer into a timezone string, extract an offset, in
1460 ** [+-]hh[:mm[:ss]] form, from the string.
1461 ** If any error occurs, return NULL.
1462 ** Otherwise, return a pointer to the first character not part of the time.
1463 */
1464
1465 static const char *
getoffset(register const char * strp,int_fast32_t * const offsetp)1466 getoffset(register const char *strp, int_fast32_t *const offsetp)
1467 {
1468 register bool neg = false;
1469
1470 if (*strp == '-') {
1471 neg = true;
1472 ++strp;
1473 } else if (*strp == '+')
1474 ++strp;
1475 strp = getsecs(strp, offsetp);
1476 if (strp == NULL)
1477 return NULL; /* illegal time */
1478 if (neg)
1479 *offsetp = -*offsetp;
1480 return strp;
1481 }
1482
1483 /*
1484 ** Given a pointer into a timezone string, extract a rule in the form
1485 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ
1486 ** for the format of "date" and "time".
1487 ** If a valid rule is not found, return NULL.
1488 ** Otherwise, return a pointer to the first character not part of the rule.
1489 */
1490
1491 static const char *
getrule(const char * strp,register struct rule * const rulep)1492 getrule(const char *strp, register struct rule *const rulep)
1493 {
1494 if (*strp == 'J') {
1495 /*
1496 ** Julian day.
1497 */
1498 rulep->r_type = JULIAN_DAY;
1499 ++strp;
1500 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1501 } else if (*strp == 'M') {
1502 /*
1503 ** Month, week, day.
1504 */
1505 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1506 ++strp;
1507 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1508 if (strp == NULL)
1509 return NULL;
1510 if (*strp++ != '.')
1511 return NULL;
1512 strp = getnum(strp, &rulep->r_week, 1, 5);
1513 if (strp == NULL)
1514 return NULL;
1515 if (*strp++ != '.')
1516 return NULL;
1517 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
1518 } else if (is_digit(*strp)) {
1519 /*
1520 ** Day of year.
1521 */
1522 rulep->r_type = DAY_OF_YEAR;
1523 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
1524 } else return NULL; /* invalid format */
1525 if (strp == NULL)
1526 return NULL;
1527 if (*strp == '/') {
1528 /*
1529 ** Time specified.
1530 */
1531 ++strp;
1532 strp = getoffset(strp, &rulep->r_time);
1533 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
1534 return strp;
1535 }
1536
1537 /*
1538 ** Given a year, a rule, and the offset from UT at the time that rule takes
1539 ** effect, calculate the year-relative time that rule takes effect.
1540 */
1541
1542 static int_fast32_t
transtime(const int year,register const struct rule * const rulep,const int_fast32_t offset)1543 transtime(const int year, register const struct rule *const rulep,
1544 const int_fast32_t offset)
1545 {
1546 register bool leapyear;
1547 register int_fast32_t value;
1548 register int i;
1549 int d, m1, yy0, yy1, yy2, dow;
1550
1551 leapyear = isleap(year);
1552 switch (rulep->r_type) {
1553
1554 case JULIAN_DAY:
1555 /*
1556 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
1557 ** years.
1558 ** In non-leap years, or if the day number is 59 or less, just
1559 ** add SECSPERDAY times the day number-1 to the time of
1560 ** January 1, midnight, to get the day.
1561 */
1562 value = (rulep->r_day - 1) * SECSPERDAY;
1563 if (leapyear && rulep->r_day >= 60)
1564 value += SECSPERDAY;
1565 break;
1566
1567 case DAY_OF_YEAR:
1568 /*
1569 ** n - day of year.
1570 ** Just add SECSPERDAY times the day number to the time of
1571 ** January 1, midnight, to get the day.
1572 */
1573 value = rulep->r_day * SECSPERDAY;
1574 break;
1575
1576 case MONTH_NTH_DAY_OF_WEEK:
1577 /*
1578 ** Mm.n.d - nth "dth day" of month m.
1579 */
1580
1581 /*
1582 ** Use Zeller's Congruence to get day-of-week of first day of
1583 ** month.
1584 */
1585 m1 = (rulep->r_mon + 9) % 12 + 1;
1586 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
1587 yy1 = yy0 / 100;
1588 yy2 = yy0 % 100;
1589 dow = ((26 * m1 - 2) / 10 +
1590 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
1591 if (dow < 0)
1592 dow += DAYSPERWEEK;
1593
1594 /*
1595 ** "dow" is the day-of-week of the first day of the month. Get
1596 ** the day-of-month (zero-origin) of the first "dow" day of the
1597 ** month.
1598 */
1599 d = rulep->r_day - dow;
1600 if (d < 0)
1601 d += DAYSPERWEEK;
1602 for (i = 1; i < rulep->r_week; ++i) {
1603 if (d + DAYSPERWEEK >=
1604 mon_lengths[leapyear][rulep->r_mon - 1])
1605 break;
1606 d += DAYSPERWEEK;
1607 }
1608
1609 /*
1610 ** "d" is the day-of-month (zero-origin) of the day we want.
1611 */
1612 value = d * SECSPERDAY;
1613 for (i = 0; i < rulep->r_mon - 1; ++i)
1614 value += mon_lengths[leapyear][i] * SECSPERDAY;
1615 break;
1616
1617 default: unreachable();
1618 }
1619
1620 /*
1621 ** "value" is the year-relative time of 00:00:00 UT on the day in
1622 ** question. To get the year-relative time of the specified local
1623 ** time on that day, add the transition time and the current offset
1624 ** from UT.
1625 */
1626 return value + rulep->r_time + offset;
1627 }
1628
1629 /*
1630 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as
1631 ** appropriate.
1632 */
1633
1634 static bool
tzparse(const char * name,struct state * sp,struct state const * basep)1635 tzparse(const char *name, struct state *sp, struct state const *basep)
1636 {
1637 const char * stdname;
1638 const char * dstname;
1639 int_fast32_t stdoffset;
1640 int_fast32_t dstoffset;
1641 register char * cp;
1642 ptrdiff_t stdlen, dstlen, charcnt;
1643 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
1644
1645 stdname = name;
1646 if (*name == '<') {
1647 name++;
1648 stdname = name;
1649 name = getqzname(name, '>');
1650 if (*name != '>')
1651 return false;
1652 stdlen = name - stdname;
1653 name++;
1654 } else {
1655 name = getzname(name);
1656 stdlen = name - stdname;
1657 }
1658 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
1659 return false;
1660 name = getoffset(name, &stdoffset);
1661 if (name == NULL)
1662 return false;
1663 charcnt = stdlen + 1;
1664 if (basep) {
1665 if (0 < basep->timecnt)
1666 atlo = basep->ats[basep->timecnt - 1];
1667 set_leapcount(sp, leapcount(basep));
1668 if (0 < leapcount(sp)) {
1669 int i;
1670 for (i = 0; i < leapcount(sp); i++)
1671 set_lsinfo(sp, i, lsinfo(basep, i));
1672 leaplo = lsinfo(sp, leapcount(sp) - 1).ls_trans;
1673 }
1674 } else
1675 set_leapcount(sp, 0); /* So, we're off a little. */
1676 sp->goback = sp->goahead = false;
1677 if (*name != '\0') {
1678 struct rule start, end;
1679 int year, yearbeg, yearlim, timecnt;
1680 time_t janfirst;
1681 int_fast32_t janoffset = 0;
1682
1683 if (*name == '<') {
1684 dstname = ++name;
1685 name = getqzname(name, '>');
1686 if (*name != '>')
1687 return false;
1688 dstlen = name - dstname;
1689 name++;
1690 } else {
1691 dstname = name;
1692 name = getzname(name);
1693 dstlen = name - dstname; /* length of DST abbr. */
1694 }
1695 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
1696 return false;
1697 charcnt += dstlen + 1;
1698 if (*name != '\0' && *name != ',' && *name != ';') {
1699 name = getoffset(name, &dstoffset);
1700 if (name == NULL)
1701 return false;
1702 } else dstoffset = stdoffset - SECSPERHOUR;
1703
1704 if (*name == '\0')
1705 name = TZDEFRULESTRING;
1706 if (! (*name == ',' || *name == ';'))
1707 return false;
1708
1709 name = getrule(name + 1, &start);
1710 if (!name)
1711 return false;
1712 if (*name++ != ',')
1713 return false;
1714 name = getrule(name, &end);
1715 if (!name || *name)
1716 return false;
1717 sp->typecnt = 2; /* standard time and DST */
1718 /*
1719 ** Two transitions per year, from EPOCH_YEAR forward.
1720 */
1721 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1722 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1723 timecnt = 0;
1724 janfirst = 0;
1725 yearbeg = EPOCH_YEAR;
1726
1727 do {
1728 int_fast32_t yearsecs
1729 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1730 time_t janfirst1 = janfirst;
1731 yearbeg--;
1732 if (increment_overflow_time(&janfirst1, -yearsecs)) {
1733 janoffset = -yearsecs;
1734 break;
1735 }
1736 janfirst = janfirst1;
1737 } while (atlo < janfirst
1738 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1739
1740 while (true) {
1741 int_fast32_t yearsecs
1742 = year_lengths[isleap(yearbeg)] * SECSPERDAY;
1743 int yearbeg1 = yearbeg;
1744 time_t janfirst1 = janfirst;
1745 if (increment_overflow_time(&janfirst1, yearsecs)
1746 || increment_overflow(&yearbeg1, 1)
1747 || atlo <= janfirst1)
1748 break;
1749 yearbeg = yearbeg1;
1750 janfirst = janfirst1;
1751 }
1752
1753 yearlim = yearbeg;
1754 if (increment_overflow(&yearlim, years_of_observations))
1755 yearlim = INT_MAX;
1756 for (year = yearbeg; year < yearlim; year++) {
1757 int_fast32_t
1758 starttime = transtime(year, &start, stdoffset),
1759 endtime = transtime(year, &end, dstoffset),
1760 yearsecs = year_lengths[isleap(year)] * SECSPERDAY;
1761 bool reversed = endtime < starttime;
1762 if (reversed) {
1763 int_fast32_t swap = starttime;
1764 starttime = endtime;
1765 endtime = swap;
1766 }
1767 if (reversed
1768 || (starttime < endtime
1769 && endtime - starttime < yearsecs)) {
1770 if (TZ_MAX_TIMES - 2 < timecnt)
1771 break;
1772 sp->ats[timecnt] = janfirst;
1773 if (! increment_overflow_time(&sp->ats[timecnt],
1774 janoffset + starttime)
1775 && atlo <= sp->ats[timecnt])
1776 sp->types[timecnt++] = !reversed;
1777 sp->ats[timecnt] = janfirst;
1778 if (! increment_overflow_time(&sp->ats[timecnt],
1779 janoffset + endtime)
1780 && atlo <= sp->ats[timecnt]) {
1781 sp->types[timecnt++] = reversed;
1782 }
1783 }
1784 if (endtime < leaplo) {
1785 yearlim = year;
1786 if (increment_overflow(&yearlim, years_of_observations))
1787 yearlim = INT_MAX;
1788 }
1789 if (increment_overflow_time(&janfirst, janoffset + yearsecs))
1790 break;
1791 janoffset = 0;
1792 }
1793 sp->timecnt = timecnt;
1794 if (! timecnt) {
1795 sp->ttis[0] = sp->ttis[1];
1796 sp->typecnt = 1; /* Perpetual DST. */
1797 } else if (years_of_observations <= year - yearbeg)
1798 sp->goback = sp->goahead = true;
1799 } else {
1800 dstlen = 0;
1801 sp->typecnt = 1; /* only standard time */
1802 sp->timecnt = 0;
1803 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1804 }
1805 sp->charcnt = charcnt;
1806 cp = sp->chars;
1807 cp = mempcpy(cp, stdname, stdlen);
1808 *cp++ = '\0';
1809 if (dstlen != 0) {
1810 cp = mempcpy(cp, dstname, dstlen);
1811 *cp = '\0';
1812 }
1813 return true;
1814 }
1815
1816 static void
gmtload(struct state * const sp)1817 gmtload(struct state *const sp)
1818 {
1819 if (!TZ_RUNTIME_LEAPS || tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0)
1820 tzparse("UTC0", sp, NULL);
1821 }
1822
1823 #if !USE_TIMEX_T || !defined TM_GMTOFF
1824
1825 /* Return true if primary cached time zone data are fresh,
1826 i.e., if this function is known to have recently returned false.
1827 A call is recent if it occurred less than tz_change_interval seconds ago.
1828 NOW should be the current time. */
1829 static bool
fresh_tzdata(monotime_t now)1830 fresh_tzdata(monotime_t now)
1831 {
1832 /* If nonzero, the time of the last false return. */
1833 static monotime_t last_checked;
1834
1835 if (last_checked && now - last_checked < tz_change_interval)
1836 return true;
1837 last_checked = now;
1838 return false;
1839 }
1840
1841 /* Initialize *SP to a value appropriate for the TZ setting NAME.
1842 Respect TZLOADFLAGS.
1843 Return 0 on success, an errno value on failure. */
1844 static int
zoneinit(struct state * sp,char const * name,char tzloadflags)1845 zoneinit(struct state *sp, char const *name, char tzloadflags)
1846 {
1847 if (name && ! name[0]) {
1848 /*
1849 ** User wants it fast rather than right.
1850 */
1851 set_leapcount(sp, 0); /* so, we're off a little */
1852 sp->timecnt = 0;
1853 sp->typecnt = 0;
1854 sp->charcnt = 0;
1855 sp->goback = sp->goahead = false;
1856 init_ttinfo(&sp->ttis[0], 0, false, 0);
1857 strcpy(sp->chars, utc);
1858 return 0;
1859 } else {
1860 int err = tzload(name, sp, tzloadflags);
1861 if (err != 0 && name && name[0] != ':' && !(tzloadflags & TZLOAD_TZDIR_SUB)
1862 && tzparse(name, sp, NULL))
1863 err = 0;
1864 if (err == 0)
1865 err = scrub_abbrs(sp);
1866 return err;
1867 }
1868 }
1869
1870 /* If THREADED, upgrade a read lock to a write lock.
1871 Return 0 on success, a positive errno value otherwise. */
1872 static int
rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded)1873 rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded)
1874 {
1875 # if THREAD_RWLOCK
1876 if (threaded) {
1877 dounlock();
1878 return pthread_rwlock_wrlock(&locallock);
1879 }
1880 # endif
1881 return 0;
1882 }
1883
1884 /* Like tzset(), but in a critical section.
1885 If THREADED && THREAD_RWLOCK the caller has a read lock,
1886 and this function might upgrade it to a write lock.
1887 If WALL, act as if TZ is unset; although always false in this file,
1888 a wrapper .c file's obsolete and ineffective tzsetwall function can use it.
1889 If tz_change_interval is positive the time is NOW; otherwise ignore NOW. */
1890 static void
tzset_unlocked(bool threaded,bool wall,monotime_t now)1891 tzset_unlocked(bool threaded, bool wall, monotime_t now)
1892 {
1893 char const *name;
1894 struct state *sp;
1895 char tzloadflags;
1896 size_t namelen;
1897 bool writing = false;
1898
1899 for (;;) {
1900 name = wall ? NULL : getenv("TZ");
1901 sp = lclptr;
1902 tzloadflags = TZLOAD_FROMENV | TZLOAD_TZSTRING;
1903 namelen = sizeof lcl_TZname + 1; /* placeholder for no name */
1904
1905 if (name) {
1906 namelen = strnlen(name, sizeof lcl_TZname);
1907
1908 /* Abbreviate a string like "/usr/share/zoneinfo/America/Los_Angeles"
1909 to its shorter equivalent "America/Los_Angeles". */
1910 if (!SUPPRESS_TZDIR && tzdirslashlen < namelen
1911 && memcmp(name, tzdirslash, tzdirslashlen) == 0) {
1912 char const *p = name + tzdirslashlen;
1913 while (*p == '/')
1914 p++;
1915 if (*p && *p != ':') {
1916 name = p;
1917 namelen = strnlen(name, sizeof lcl_TZname);
1918 tzloadflags |= TZLOAD_TZDIR_SUB;
1919 }
1920 }
1921 }
1922
1923 if ((tz_change_interval <= 0 ? tz_change_interval < 0 : fresh_tzdata(now))
1924 && (name
1925 ? 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0
1926 : lcl_is_set < 0))
1927 return;
1928
1929 if (!THREAD_RWLOCK || writing)
1930 break;
1931 if (rd2wrlock(threaded) != 0)
1932 return;
1933 writing = true;
1934 }
1935
1936 # if ALL_STATE
1937 if (! sp)
1938 lclptr = sp = malloc(sizeof *lclptr);
1939 # endif
1940 if (sp) {
1941 int err = zoneinit(sp, name, tzloadflags);
1942 if (err != 0) {
1943 zoneinit(sp, "", 0);
1944 /* Abbreviate with "-00" if there was an error.
1945 Do not treat a missing TZDEFAULT file as an error. */
1946 if (name || err != ENOENT)
1947 strcpy(sp->chars, UNSPEC);
1948 }
1949 if (namelen < sizeof lcl_TZname) {
1950 char *cp = lcl_TZname;
1951 cp = mempcpy(cp, name, namelen);
1952 *cp = '\0';
1953 }
1954 }
1955 settzname();
1956 lcl_is_set = (sizeof lcl_TZname > namelen) - (sizeof lcl_TZname < namelen);
1957 }
1958
1959 #endif
1960
1961 #if !defined TM_GMTOFF || !USE_TIMEX_T
1962
1963 /* If tz_change_interval is positive,
1964 return the current time as a monotonically nondecreasing value.
1965 Otherwise the return value does not matter. */
1966 static monotime_t
get_monotonic_time(void)1967 get_monotonic_time(void)
1968 {
1969 struct timespec now;
1970 now.tv_sec = 0;
1971 if (0 < tz_change_interval)
1972 clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
1973 return now.tv_sec;
1974 }
1975 #endif
1976
1977 #if !USE_TIMEX_T
1978
1979 void
tzset(void)1980 tzset(void)
1981 {
1982 monotime_t now = get_monotonic_time();
1983 int err = lock();
1984 if (0 < err) {
1985 errno = err;
1986 return;
1987 }
1988 tzset_unlocked(!err, false, now);
1989 unlock(!err);
1990 }
1991 #endif
1992
1993 #ifdef __FreeBSD__
1994 void
freebsd13_tzsetwall(void)1995 freebsd13_tzsetwall(void)
1996 {
1997 monotime_t now = get_monotonic_time();
1998 int err = lock();
1999 if (0 < err) {
2000 errno = err;
2001 return;
2002 }
2003 tzset_unlocked(!err, true, now);
2004 unlock(!err);
2005 }
2006 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0);
2007 __warn_references(tzsetwall,
2008 "warning: tzsetwall() is deprecated, use tzset() instead.");
2009 #endif /* __FreeBSD__ */
2010 static void
gmtcheck1(void)2011 gmtcheck1(void)
2012 {
2013 #if ALL_STATE
2014 gmtptr = malloc(sizeof *gmtptr);
2015 #endif
2016 if (gmtptr)
2017 gmtload(gmtptr);
2018 }
2019
2020 static void
gmtcheck(void)2021 gmtcheck(void)
2022 {
2023 static once_t gmt_once = ONCE_INIT;
2024 once(&gmt_once, gmtcheck1);
2025 }
2026
2027 #if NETBSD_INSPIRED && !USE_TIMEX_T
2028
2029 timezone_t
tzalloc(char const * name)2030 tzalloc(char const *name)
2031 {
2032 timezone_t sp = malloc(sizeof *sp);
2033 if (sp) {
2034 int err = zoneinit(sp, name, TZLOAD_TZSTRING);
2035 if (err != 0) {
2036 free(sp);
2037 errno = err;
2038 return NULL;
2039 }
2040 } else if (!HAVE_MALLOC_ERRNO)
2041 errno = ENOMEM;
2042 return sp;
2043 }
2044
2045 #ifndef FREE_PRESERVES_ERRNO
2046 # if ((defined _POSIX_VERSION && 202405 <= _POSIX_VERSION) \
2047 || (defined __GLIBC__ && 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__)) \
2048 || defined __OpenBSD__ || defined __sun)
2049 # define FREE_PRESERVES_ERRNO 1
2050 # else
2051 # define FREE_PRESERVES_ERRNO 0
2052 # endif
2053 #endif
2054
2055 void
tzfree(timezone_t sp)2056 tzfree(timezone_t sp)
2057 {
2058 int err;
2059 if (!FREE_PRESERVES_ERRNO)
2060 err = errno;
2061 free(sp);
2062 if (!FREE_PRESERVES_ERRNO)
2063 errno = err;
2064 }
2065
2066 /*
2067 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and
2068 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that
2069 ** ctime_rz would share. Callers can instead use localtime_rz + strftime.
2070 **
2071 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
2072 ** in zones with three or more time zone abbreviations.
2073 ** Callers can instead use localtime_rz + strftime.
2074 */
2075
2076 #endif
2077
2078 #if !USE_TIMEX_T || !defined TM_GMTOFF
2079
2080 /*
2081 ** The easy way to behave "as if no library function calls" localtime
2082 ** is to not call it, so we drop its guts into "localsub", which can be
2083 ** freely called. (And no, the PANS doesn't require the above behavior,
2084 ** but it *is* desirable.)
2085 **
2086 ** If successful and SETNAME is nonzero,
2087 ** set the applicable parts of tzname, timezone and altzone;
2088 ** however, it's OK to omit this step for proleptic TZ strings
2089 ** since in that case tzset should have already done this step correctly.
2090 ** SETNAME's type is int_fast32_t for compatibility with gmtsub,
2091 ** but it is actually a boolean and its value should be 0 or 1.
2092 */
2093
2094 /*ARGSUSED*/
2095 static struct tm *
localsub(struct state const * sp,time_t const * timep,int_fast32_t setname,struct tm * const tmp)2096 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
2097 struct tm *const tmp)
2098 {
2099 register const struct ttinfo * ttisp;
2100 register int i;
2101 register struct tm * result;
2102 const time_t t = *timep;
2103
2104 if (sp == NULL) {
2105 /* Don't bother to set tzname etc.; tzset has already done it. */
2106 return gmtsub(gmtptr, timep, 0, tmp);
2107 }
2108 if ((sp->goback && t < sp->ats[0]) ||
2109 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
2110 time_t newt;
2111 register time_t seconds;
2112 register time_t years;
2113
2114 if (t < sp->ats[0])
2115 seconds = sp->ats[0] - t;
2116 else seconds = t - sp->ats[sp->timecnt - 1];
2117 --seconds;
2118
2119 /* Beware integer overflow, as SECONDS might
2120 be close to the maximum time_t. */
2121 years = seconds / SECSPERREPEAT * YEARSPERREPEAT;
2122 seconds = years * AVGSECSPERYEAR;
2123 years += YEARSPERREPEAT;
2124 if (t < sp->ats[0])
2125 newt = t + seconds + SECSPERREPEAT;
2126 else
2127 newt = t - seconds - SECSPERREPEAT;
2128
2129 if (newt < sp->ats[0] ||
2130 newt > sp->ats[sp->timecnt - 1])
2131 return NULL; /* "cannot happen" */
2132 result = localsub(sp, &newt, setname, tmp);
2133 if (result) {
2134 # if defined ckd_add && defined ckd_sub
2135 if (t < sp->ats[0]
2136 ? ckd_sub(&result->tm_year,
2137 result->tm_year, years)
2138 : ckd_add(&result->tm_year,
2139 result->tm_year, years))
2140 return NULL;
2141 # else
2142 register int_fast64_t newy;
2143
2144 newy = result->tm_year;
2145 if (t < sp->ats[0])
2146 newy -= years;
2147 else newy += years;
2148 if (! (INT_MIN <= newy && newy <= INT_MAX))
2149 return NULL;
2150 result->tm_year = newy;
2151 # endif
2152 }
2153 return result;
2154 }
2155 if (sp->timecnt == 0 || t < sp->ats[0]) {
2156 i = 0;
2157 } else {
2158 register int lo = 1;
2159 register int hi = sp->timecnt;
2160
2161 while (lo < hi) {
2162 register int mid = (lo + hi) >> 1;
2163
2164 if (t < sp->ats[mid])
2165 hi = mid;
2166 else lo = mid + 1;
2167 }
2168 i = sp->types[lo - 1];
2169 }
2170 ttisp = &sp->ttis[i];
2171 /*
2172 ** To get (wrong) behavior that's compatible with System V Release 2.0
2173 ** you'd replace the statement below with
2174 ** t += ttisp->tt_utoff;
2175 ** timesub(&t, 0, sp, tmp);
2176 */
2177 result = timesub(&t, ttisp->tt_utoff, sp, tmp);
2178 if (result) {
2179 result->tm_isdst = ttisp->tt_isdst;
2180 # ifdef TM_ZONE
2181 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]);
2182 # endif
2183 if (setname)
2184 update_tzname_etc(sp, ttisp);
2185 }
2186 return result;
2187 }
2188 #endif
2189
2190 #if !USE_TIMEX_T
2191
2192 /* Return TMP, or a thread-specific struct tm * selected by WHICH. */
2193 static struct tm *
tm_multi(struct tm * tmp,ATTRIBUTE_MAYBE_UNUSED enum tm_multi which)2194 tm_multi(struct tm *tmp, ATTRIBUTE_MAYBE_UNUSED enum tm_multi which)
2195 {
2196 # if THREAD_SAFE && THREAD_TM_MULTI
2197 /* It is OK to check is_threaded() separately here; even if it
2198 returns a different value in other places in the caller,
2199 this function's behavior is still valid. */
2200 if (is_threaded()) {
2201 /* Try to get a thread-specific struct tm *.
2202 Fall back on TMP if this fails. */
2203 static pthread_once_t tm_multi_once = PTHREAD_ONCE_INIT;
2204 pthread_once(&tm_multi_once, tm_multi_key_init);
2205 if (!tm_multi_key_err) {
2206 struct tm *p = pthread_getspecific(tm_multi_key);
2207 if (!p) {
2208 p = malloc(N_TM_MULTI * sizeof *p);
2209 if (p && pthread_setspecific(tm_multi_key, p) != 0) {
2210 free(p);
2211 p = NULL;
2212 }
2213 }
2214 if (p)
2215 return &p[which];
2216 }
2217 }
2218 # endif
2219 return tmp;
2220 }
2221
2222 # if NETBSD_INSPIRED
2223 struct tm *
localtime_rz(struct state * restrict sp,time_t const * restrict timep,struct tm * restrict tmp)2224 localtime_rz(struct state *restrict sp, time_t const *restrict timep,
2225 struct tm *restrict tmp)
2226 {
2227 return localsub(sp, timep, 0, tmp);
2228 }
2229 # endif
2230
2231 static struct tm *
localtime_tzset(time_t const * timep,struct tm * tmp,bool setname)2232 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
2233 {
2234 monotime_t now = get_monotonic_time();
2235 int err = lock();
2236 if (0 < err) {
2237 errno = err;
2238 return NULL;
2239 }
2240 if (0 <= tz_change_interval || setname || !lcl_is_set)
2241 tzset_unlocked(!err, false, now);
2242 tmp = localsub(lclptr, timep, setname, tmp);
2243 unlock(!err);
2244 return tmp;
2245 }
2246
2247 struct tm *
localtime(const time_t * timep)2248 localtime(const time_t *timep)
2249 {
2250 # if !SUPPORT_C89
2251 static struct tm tm;
2252 # endif
2253 return localtime_tzset(timep, tm_multi(&tm, LOCALTIME_TM_MULTI), true);
2254 }
2255
2256 struct tm *
localtime_r(const time_t * restrict timep,struct tm * restrict tmp)2257 localtime_r(const time_t *restrict timep, struct tm *restrict tmp)
2258 {
2259 return localtime_tzset(timep, tmp, false);
2260 }
2261 #endif
2262
2263 /*
2264 ** gmtsub is to gmtime as localsub is to localtime.
2265 */
2266
2267 static struct tm *
gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const * sp,time_t const * timep,int_fast32_t offset,struct tm * tmp)2268 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
2269 int_fast32_t offset, struct tm *tmp)
2270 {
2271 register struct tm * result;
2272
2273 result = timesub(timep, offset, gmtptr, tmp);
2274 #ifdef TM_ZONE
2275 /*
2276 ** Could get fancy here and deliver something such as
2277 ** "+xx" or "-xx" if offset is non-zero,
2278 ** but this is no time for a treasure hunt.
2279 */
2280 tmp->TM_ZONE = UNCONST(offset ? wildabbr
2281 : gmtptr ? gmtptr->chars : utc);
2282 #endif /* defined TM_ZONE */
2283 return result;
2284 }
2285
2286 #if !USE_TIMEX_T
2287
2288 /*
2289 * Re-entrant version of gmtime.
2290 */
2291
2292 struct tm *
gmtime_r(time_t const * restrict timep,struct tm * restrict tmp)2293 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp)
2294 {
2295 gmtcheck();
2296 return gmtsub(gmtptr, timep, 0, tmp);
2297 }
2298
2299 struct tm *
gmtime(const time_t * timep)2300 gmtime(const time_t *timep)
2301 {
2302 # if !SUPPORT_C89
2303 static struct tm tm;
2304 # endif
2305 return gmtime_r(timep, tm_multi(&tm, GMTIME_TM_MULTI));
2306 }
2307
2308 # if STD_INSPIRED
2309
2310 /* This function is obsolescent and may disappear in future releases.
2311 Callers can instead use localtime_rz with a fixed-offset zone. */
2312
2313 struct tm *
offtime_r(time_t const * restrict timep,long offset,struct tm * restrict tmp)2314 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp)
2315 {
2316 gmtcheck();
2317 return gmtsub(gmtptr, timep, offset, tmp);
2318 }
2319
2320 struct tm *
offtime(time_t const * timep,long offset)2321 offtime(time_t const *timep, long offset)
2322 {
2323 # if !SUPPORT_C89
2324 static struct tm tm;
2325 # endif
2326 return offtime_r(timep, offset, tm_multi(&tm, OFFTIME_TM_MULTI));
2327 }
2328
2329 # endif
2330 #endif
2331
2332 /*
2333 ** Return the number of leap years through the end of the given year
2334 ** where, to make the math easy, the answer for year zero is defined as zero.
2335 */
2336
2337 static time_t
leaps_thru_end_of_nonneg(time_t y)2338 leaps_thru_end_of_nonneg(time_t y)
2339 {
2340 return y / 4 - y / 100 + y / 400;
2341 }
2342
2343 static time_t
leaps_thru_end_of(time_t y)2344 leaps_thru_end_of(time_t y)
2345 {
2346 return (y < 0
2347 ? -1 - leaps_thru_end_of_nonneg(-1 - y)
2348 : leaps_thru_end_of_nonneg(y));
2349 }
2350
2351 static struct tm *
timesub(const time_t * timep,int_fast32_t offset,const struct state * sp,struct tm * tmp)2352 timesub(const time_t *timep, int_fast32_t offset,
2353 const struct state *sp, struct tm *tmp)
2354 {
2355 register time_t tdays;
2356 register const int * ip;
2357 int_fast32_2s corr;
2358 register int i;
2359 int_fast32_t idays, rem, dayoff, dayrem;
2360 time_t y;
2361
2362 /* If less than SECSPERMIN, the number of seconds since the
2363 most recent positive leap second; otherwise, do not add 1
2364 to localtime tm_sec because of leap seconds. */
2365 time_t secs_since_posleap = SECSPERMIN;
2366
2367 corr = 0;
2368 i = sp ? leapcount(sp) : 0;
2369 while (--i >= 0) {
2370 struct lsinfo ls = lsinfo(sp, i);
2371 if (ls.ls_trans <= *timep) {
2372 corr = ls.ls_corr;
2373 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr)
2374 secs_since_posleap = *timep - ls.ls_trans;
2375 break;
2376 }
2377 }
2378
2379 /* Calculate the year, avoiding integer overflow even if
2380 time_t is unsigned. */
2381 tdays = *timep / SECSPERDAY;
2382 rem = *timep % SECSPERDAY;
2383 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
2384 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
2385 rem %= SECSPERDAY;
2386 /* y = (EPOCH_YEAR
2387 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
2388 sans overflow. But calculate against 1570 (EPOCH_YEAR -
2389 YEARSPERREPEAT) instead of against 1970 so that things work
2390 for localtime values before 1970 when time_t is unsigned. */
2391 dayrem = tdays % DAYSPERREPEAT;
2392 dayrem += dayoff % DAYSPERREPEAT;
2393 y = (EPOCH_YEAR - YEARSPERREPEAT
2394 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
2395 - ((dayrem % DAYSPERREPEAT) < 0)
2396 + tdays / DAYSPERREPEAT)
2397 * YEARSPERREPEAT));
2398 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
2399 idays = tdays % DAYSPERREPEAT;
2400 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
2401 idays %= DAYSPERREPEAT;
2402 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
2403 while (year_lengths[isleap(y)] <= idays) {
2404 int tdelta = idays / DAYSPERLYEAR;
2405 int_fast32_t ydelta = tdelta + !tdelta;
2406 time_t newy = y + ydelta;
2407 register int leapdays;
2408 leapdays = leaps_thru_end_of(newy - 1) -
2409 leaps_thru_end_of(y - 1);
2410 idays -= ydelta * DAYSPERNYEAR;
2411 idays -= leapdays;
2412 y = newy;
2413 }
2414
2415 #ifdef ckd_add
2416 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
2417 errno = EOVERFLOW;
2418 return NULL;
2419 }
2420 #else
2421 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
2422 int signed_y = y;
2423 tmp->tm_year = signed_y - TM_YEAR_BASE;
2424 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
2425 && y - TM_YEAR_BASE <= INT_MAX)
2426 tmp->tm_year = y - TM_YEAR_BASE;
2427 else {
2428 errno = EOVERFLOW;
2429 return NULL;
2430 }
2431 #endif
2432 tmp->tm_yday = idays;
2433 /*
2434 ** The "extra" mods below avoid overflow problems.
2435 */
2436 tmp->tm_wday = (TM_WDAY_BASE
2437 + ((tmp->tm_year % DAYSPERWEEK)
2438 * (DAYSPERNYEAR % DAYSPERWEEK))
2439 + leaps_thru_end_of(y - 1)
2440 - leaps_thru_end_of(TM_YEAR_BASE - 1)
2441 + idays);
2442 tmp->tm_wday %= DAYSPERWEEK;
2443 if (tmp->tm_wday < 0)
2444 tmp->tm_wday += DAYSPERWEEK;
2445 tmp->tm_hour = rem / SECSPERHOUR;
2446 rem %= SECSPERHOUR;
2447 tmp->tm_min = rem / SECSPERMIN;
2448 tmp->tm_sec = rem % SECSPERMIN;
2449
2450 /* Use "... ??:??:60" at the end of the localtime minute containing
2451 the second just before the positive leap second. */
2452 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
2453
2454 ip = mon_lengths[isleap(y)];
2455 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
2456 idays -= ip[tmp->tm_mon];
2457 tmp->tm_mday = idays + 1;
2458 tmp->tm_isdst = 0;
2459 #ifdef TM_GMTOFF
2460 tmp->TM_GMTOFF = offset;
2461 #endif /* defined TM_GMTOFF */
2462 return tmp;
2463 }
2464
2465 /*
2466 ** Adapted from code provided by Robert Elz, who writes:
2467 ** The "best" way to do mktime I think is based on an idea of Bob
2468 ** Kridle's (so its said...) from a long time ago.
2469 ** It does a binary search of the time_t space. Since time_t's are
2470 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
2471 ** would still be very reasonable).
2472 */
2473
2474 #ifndef WRONG
2475 # define WRONG (-1)
2476 #endif /* !defined WRONG */
2477
2478 /*
2479 ** Normalize logic courtesy Paul Eggert.
2480 */
2481
2482 static bool
increment_overflow(int * ip,int j)2483 increment_overflow(int *ip, int j)
2484 {
2485 #ifdef ckd_add
2486 return ckd_add(ip, *ip, j);
2487 #else
2488 register int const i = *ip;
2489
2490 /*
2491 ** If i >= 0 there can only be overflow if i + j > INT_MAX
2492 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
2493 ** If i < 0 there can only be overflow if i + j < INT_MIN
2494 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
2495 */
2496 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
2497 return true;
2498 *ip += j;
2499 return false;
2500 #endif
2501 }
2502
2503 static bool
increment_overflow_64(int * ip,int_fast64_t j)2504 increment_overflow_64(int *ip, int_fast64_t j)
2505 {
2506 #ifdef ckd_add
2507 return ckd_add(ip, *ip, j);
2508 #else
2509 if (j < 0 ? *ip < INT_MIN - j : INT_MAX - j < *ip)
2510 return true;
2511 *ip += j;
2512 return false;
2513 #endif
2514 }
2515
2516 static bool
increment_overflow_time_iinntt(time_t * tp,iinntt j)2517 increment_overflow_time_iinntt(time_t *tp, iinntt j)
2518 {
2519 #ifdef ckd_add
2520 return ckd_add(tp, *tp, j);
2521 #else
2522 if (j < 0
2523 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j)
2524 : TIME_T_MAX - j < *tp)
2525 return true;
2526 *tp += j;
2527 return false;
2528 #endif
2529 }
2530
2531 static bool
increment_overflow_time_64(time_t * tp,int_fast64_t j)2532 increment_overflow_time_64(time_t *tp, int_fast64_t j)
2533 {
2534 #ifdef ckd_add
2535 return ckd_add(tp, *tp, j);
2536 #else
2537 if (j < 0
2538 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j)
2539 : TIME_T_MAX - j < *tp)
2540 return true;
2541 *tp += j;
2542 return false;
2543 #endif
2544 }
2545
2546 static bool
increment_overflow_time(time_t * tp,int_fast32_2s j)2547 increment_overflow_time(time_t *tp, int_fast32_2s j)
2548 {
2549 #ifdef ckd_add
2550 return ckd_add(tp, *tp, j);
2551 #else
2552 /*
2553 ** This is like
2554 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
2555 ** except that it does the right thing even if *tp + j would overflow.
2556 */
2557 if (! (j < 0
2558 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
2559 : *tp <= TIME_T_MAX - j))
2560 return true;
2561 *tp += j;
2562 return false;
2563 #endif
2564 }
2565
2566 /* Return A - B, where both are in the range -2**31 + 1 .. 2**31 - 1.
2567 The result cannot overflow. */
2568 static int_fast64_t
utoff_diff(int_fast32_t a,int_fast32_t b)2569 utoff_diff (int_fast32_t a, int_fast32_t b)
2570 {
2571 int_fast64_t aa = a;
2572 return aa - b;
2573 }
2574
2575 static int
tmcomp(register const struct tm * const atmp,register const struct tm * const btmp)2576 tmcomp(register const struct tm *const atmp,
2577 register const struct tm *const btmp)
2578 {
2579 register int result;
2580
2581 if (atmp->tm_year != btmp->tm_year)
2582 return atmp->tm_year < btmp->tm_year ? -1 : 1;
2583 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
2584 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
2585 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
2586 (result = (atmp->tm_min - btmp->tm_min)) == 0)
2587 result = atmp->tm_sec - btmp->tm_sec;
2588 return result;
2589 }
2590
2591 /* Copy to *DEST from *SRC. Copy only the members needed for mktime,
2592 as other members might not be initialized. */
2593 static void
mktmcpy(struct tm * dest,struct tm const * src)2594 mktmcpy(struct tm *dest, struct tm const *src)
2595 {
2596 dest->tm_sec = src->tm_sec;
2597 dest->tm_min = src->tm_min;
2598 dest->tm_hour = src->tm_hour;
2599 dest->tm_mday = src->tm_mday;
2600 dest->tm_mon = src->tm_mon;
2601 dest->tm_year = src->tm_year;
2602 dest->tm_isdst = src->tm_isdst;
2603 #if defined TM_GMTOFF && ! UNINIT_TRAP
2604 dest->TM_GMTOFF = src->TM_GMTOFF;
2605 #endif
2606 }
2607
2608 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)2609 time2sub(struct tm *const tmp,
2610 struct tm *funcp(struct state const *, time_t const *,
2611 int_fast32_t, struct tm *),
2612 struct state const *sp,
2613 const int_fast32_t offset,
2614 bool *okayp,
2615 bool do_norm_secs)
2616 {
2617 register int dir;
2618 register int i, j;
2619 register time_t lo;
2620 register time_t hi;
2621 iinntt y, mday, hour, min, saved_seconds;
2622 time_t newt;
2623 time_t t;
2624 struct tm yourtm, mytm;
2625
2626 *okayp = false;
2627 mktmcpy(&yourtm, tmp);
2628
2629 min = yourtm.tm_min;
2630 if (do_norm_secs) {
2631 min += yourtm.tm_sec / SECSPERMIN;
2632 yourtm.tm_sec %= SECSPERMIN;
2633 if (yourtm.tm_sec < 0) {
2634 yourtm.tm_sec += SECSPERMIN;
2635 min--;
2636 }
2637 }
2638
2639 hour = yourtm.tm_hour;
2640 hour += min / MINSPERHOUR;
2641 yourtm.tm_min = min % MINSPERHOUR;
2642 if (yourtm.tm_min < 0) {
2643 yourtm.tm_min += MINSPERHOUR;
2644 hour--;
2645 }
2646
2647 mday = yourtm.tm_mday;
2648 mday += hour / HOURSPERDAY;
2649 yourtm.tm_hour = hour % HOURSPERDAY;
2650 if (yourtm.tm_hour < 0) {
2651 yourtm.tm_hour += HOURSPERDAY;
2652 mday--;
2653 }
2654
2655 y = yourtm.tm_year;
2656 y += yourtm.tm_mon / MONSPERYEAR;
2657 yourtm.tm_mon %= MONSPERYEAR;
2658 if (yourtm.tm_mon < 0) {
2659 yourtm.tm_mon += MONSPERYEAR;
2660 y--;
2661 }
2662
2663 /*
2664 ** Turn y into an actual year number for now.
2665 ** It is converted back to an offset from TM_YEAR_BASE later.
2666 */
2667 y += TM_YEAR_BASE;
2668
2669 while (mday <= 0) {
2670 iinntt li = y - (yourtm.tm_mon <= 1);
2671 mday += year_lengths[isleap(li)];
2672 y--;
2673 }
2674 while (DAYSPERLYEAR < mday) {
2675 iinntt li = y + (1 < yourtm.tm_mon);
2676 mday -= year_lengths[isleap(li)];
2677 y++;
2678 }
2679 yourtm.tm_mday = mday;
2680 for ( ; ; ) {
2681 i = mon_lengths[isleap(y)][yourtm.tm_mon];
2682 if (yourtm.tm_mday <= i)
2683 break;
2684 yourtm.tm_mday -= i;
2685 if (++yourtm.tm_mon >= MONSPERYEAR) {
2686 yourtm.tm_mon = 0;
2687 y++;
2688 }
2689 }
2690 #ifdef ckd_add
2691 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
2692 return WRONG;
2693 #else
2694 y -= TM_YEAR_BASE;
2695 if (! (INT_MIN <= y && y <= INT_MAX))
2696 return WRONG;
2697 yourtm.tm_year = y;
2698 #endif
2699 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
2700 saved_seconds = 0;
2701 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) {
2702 /*
2703 ** We can't set tm_sec to 0, because that might push the
2704 ** time below the minimum representable time.
2705 ** Set tm_sec to 59 instead.
2706 ** This assumes that the minimum representable time is
2707 ** not in the same minute that a leap second was deleted from,
2708 ** which is a safer assumption than using 58 would be.
2709 */
2710 saved_seconds = yourtm.tm_sec;
2711 saved_seconds -= SECSPERMIN - 1;
2712 yourtm.tm_sec = SECSPERMIN - 1;
2713 } else {
2714 saved_seconds = yourtm.tm_sec;
2715 yourtm.tm_sec = 0;
2716 }
2717 /*
2718 ** Do a binary search (this works whatever time_t's type is).
2719 */
2720 lo = TIME_T_MIN;
2721 hi = TIME_T_MAX;
2722 for ( ; ; ) {
2723 t = lo / 2 + hi / 2;
2724 if (t < lo)
2725 t = lo;
2726 else if (t > hi)
2727 t = hi;
2728 if (! funcp(sp, &t, offset, &mytm)) {
2729 /*
2730 ** Assume that t is too extreme to be represented in
2731 ** a struct tm; arrange things so that it is less
2732 ** extreme on the next pass.
2733 */
2734 dir = (t > 0) ? 1 : -1;
2735 } else dir = tmcomp(&mytm, &yourtm);
2736 if (dir != 0) {
2737 if (t == lo) {
2738 if (t == TIME_T_MAX)
2739 return WRONG;
2740 ++t;
2741 ++lo;
2742 } else if (t == hi) {
2743 if (t == TIME_T_MIN)
2744 return WRONG;
2745 --t;
2746 --hi;
2747 }
2748 if (lo > hi)
2749 return WRONG;
2750 if (dir > 0)
2751 hi = t;
2752 else lo = t;
2753 continue;
2754 }
2755 #if defined TM_GMTOFF && ! UNINIT_TRAP
2756 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
2757 && (yourtm.TM_GMTOFF < 0
2758 ? (-SECSPERDAY <= yourtm.TM_GMTOFF
2759 && (mytm.TM_GMTOFF <=
2760 (min(INT_FAST32_MAX, LONG_MAX)
2761 + yourtm.TM_GMTOFF)))
2762 : (yourtm.TM_GMTOFF <= SECSPERDAY
2763 && ((max(INT_FAST32_MIN, LONG_MIN)
2764 + yourtm.TM_GMTOFF)
2765 <= mytm.TM_GMTOFF)))) {
2766 /* MYTM matches YOURTM except with the wrong UT offset.
2767 YOURTM.TM_GMTOFF is plausible, so try it instead.
2768 It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2769 since the guess gets checked. */
2770 time_t altt = t;
2771 int_fast64_t offdiff;
2772 bool v;
2773 # ifdef ckd_sub
2774 v = ckd_sub(&offdiff, mytm.TM_GMTOFF, yourtm.TM_GMTOFF);
2775 # else
2776 /* A ckd_sub approximation that is good enough here. */
2777 v = !(-TWO_31_MINUS_1 <= yourtm.TM_GMTOFF
2778 && yourtm.TM_GMTOFF <= TWO_31_MINUS_1);
2779 if (!v)
2780 offdiff = utoff_diff(mytm.TM_GMTOFF, yourtm.TM_GMTOFF);
2781 # endif
2782 if (!v && !increment_overflow_time_64(&altt, offdiff)) {
2783 struct tm alttm;
2784 if (funcp(sp, &altt, offset, &alttm)
2785 && alttm.tm_isdst == mytm.tm_isdst
2786 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2787 && tmcomp(&alttm, &yourtm) == 0) {
2788 t = altt;
2789 mytm = alttm;
2790 }
2791 }
2792 }
2793 #endif
2794 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2795 break;
2796 /*
2797 ** Right time, wrong type.
2798 ** Hunt for right time, right type.
2799 ** It's okay to guess wrong since the guess
2800 ** gets checked.
2801 */
2802 if (sp == NULL)
2803 return WRONG;
2804 for (i = sp->typecnt - 1; i >= 0; --i) {
2805 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2806 continue;
2807 for (j = sp->typecnt - 1; j >= 0; --j) {
2808 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2809 continue;
2810 if (ttunspecified(sp, j))
2811 continue;
2812 newt = t;
2813 if (increment_overflow_time_64
2814 (&newt,
2815 utoff_diff(sp->ttis[j].tt_utoff,
2816 sp->ttis[i].tt_utoff)))
2817 continue;
2818 if (! funcp(sp, &newt, offset, &mytm))
2819 continue;
2820 if (tmcomp(&mytm, &yourtm) != 0)
2821 continue;
2822 if (mytm.tm_isdst != yourtm.tm_isdst)
2823 continue;
2824 /*
2825 ** We have a match.
2826 */
2827 t = newt;
2828 goto label;
2829 }
2830 }
2831 return WRONG;
2832 }
2833 label:
2834 if (increment_overflow_time_iinntt(&t, saved_seconds))
2835 return WRONG;
2836 if (funcp(sp, &t, offset, tmp))
2837 *okayp = true;
2838 return t;
2839 }
2840
2841 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)2842 time2(struct tm * const tmp,
2843 struct tm *funcp(struct state const *, time_t const *,
2844 int_fast32_t, struct tm *),
2845 struct state const *sp,
2846 const int_fast32_t offset,
2847 bool *okayp)
2848 {
2849 time_t t;
2850
2851 /*
2852 ** First try without normalization of seconds
2853 ** (in case tm_sec contains a value associated with a leap second).
2854 ** If that fails, try with normalization of seconds.
2855 */
2856 t = time2sub(tmp, funcp, sp, offset, okayp, false);
2857 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2858 }
2859
2860 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)2861 time1(struct tm *const tmp,
2862 struct tm *funcp(struct state const *, time_t const *,
2863 int_fast32_t, struct tm *),
2864 struct state const *sp,
2865 const int_fast32_t offset)
2866 {
2867 register time_t t;
2868 register int samei, otheri;
2869 register int sameind, otherind;
2870 register int i;
2871 register int nseen;
2872 char seen[TZ_MAX_TYPES];
2873 unsigned char types[TZ_MAX_TYPES];
2874 bool okay;
2875
2876 if (tmp == NULL) {
2877 errno = EINVAL;
2878 return WRONG;
2879 }
2880 if (tmp->tm_isdst > 1)
2881 tmp->tm_isdst = 1;
2882 t = time2(tmp, funcp, sp, offset, &okay);
2883 if (okay)
2884 return t;
2885 if (tmp->tm_isdst < 0)
2886 #ifdef PCTS
2887 /*
2888 ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2889 */
2890 tmp->tm_isdst = 0; /* reset to std and try again */
2891 #else
2892 return t;
2893 #endif /* !defined PCTS */
2894 /*
2895 ** We're supposed to assume that somebody took a time of one type
2896 ** and did some math on it that yielded a "struct tm" that's bad.
2897 ** We try to divine the type they started from and adjust to the
2898 ** type they need.
2899 */
2900 if (sp == NULL)
2901 return WRONG;
2902 for (i = 0; i < sp->typecnt; ++i)
2903 seen[i] = false;
2904 nseen = 0;
2905 for (i = sp->timecnt - 1; i >= 0; --i)
2906 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
2907 seen[sp->types[i]] = true;
2908 types[nseen++] = sp->types[i];
2909 }
2910 for (sameind = 0; sameind < nseen; ++sameind) {
2911 samei = types[sameind];
2912 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2913 continue;
2914 for (otherind = 0; otherind < nseen; ++otherind) {
2915 otheri = types[otherind];
2916 if (sp->ttis[otheri].tt_isdst != tmp->tm_isdst) {
2917 int sec = tmp->tm_sec;
2918 if (!increment_overflow_64
2919 (&tmp->tm_sec,
2920 utoff_diff(sp->ttis[otheri].tt_utoff,
2921 sp->ttis[samei].tt_utoff))) {
2922 tmp->tm_isdst = !tmp->tm_isdst;
2923 t = time2(tmp, funcp, sp, offset, &okay);
2924 if (okay)
2925 return t;
2926 tmp->tm_isdst = !tmp->tm_isdst;
2927 }
2928 tmp->tm_sec = sec;
2929 }
2930 }
2931 }
2932 return WRONG;
2933 }
2934
2935 #if !defined TM_GMTOFF || !USE_TIMEX_T
2936
2937 static time_t
mktime_tzname(struct state * sp,struct tm * tmp,bool setname)2938 mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
2939 {
2940 if (sp)
2941 return time1(tmp, localsub, sp, setname);
2942 else {
2943 gmtcheck();
2944 return time1(tmp, gmtsub, gmtptr, 0);
2945 }
2946 }
2947
2948 # if USE_TIMEX_T
2949 static
2950 # endif
2951 time_t
mktime(struct tm * tmp)2952 mktime(struct tm *tmp)
2953 {
2954 monotime_t now = get_monotonic_time();
2955 time_t t;
2956 int err = lock();
2957 if (0 < err) {
2958 errno = err;
2959 return -1;
2960 }
2961 tzset_unlocked(!err, false, now);
2962 t = mktime_tzname(lclptr, tmp, true);
2963 unlock(!err);
2964 return t;
2965 }
2966
2967 #endif
2968
2969 #if NETBSD_INSPIRED && !USE_TIMEX_T
2970 time_t
mktime_z(struct state * restrict sp,struct tm * restrict tmp)2971 mktime_z(struct state *restrict sp, struct tm *restrict tmp)
2972 {
2973 return mktime_tzname(sp, tmp, false);
2974 }
2975 #endif
2976
2977 #if STD_INSPIRED && !USE_TIMEX_T
2978 /* This function is obsolescent and may disappear in future releases.
2979 Callers can instead use mktime. */
2980 time_t
timelocal(struct tm * tmp)2981 timelocal(struct tm *tmp)
2982 {
2983 if (tmp != NULL)
2984 tmp->tm_isdst = -1; /* in case it wasn't initialized */
2985 return mktime(tmp);
2986 }
2987 #endif
2988
2989 #if defined TM_GMTOFF || !USE_TIMEX_T
2990
2991 # ifndef EXTERN_TIMEOFF
2992 # ifndef timeoff
2993 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */
2994 # endif
2995 # define EXTERN_TIMEOFF static
2996 # endif
2997
2998 /* This function is obsolescent and may disappear in future releases.
2999 Callers can instead use mktime_z with a fixed-offset zone. */
3000 EXTERN_TIMEOFF time_t
timeoff(struct tm * tmp,long offset)3001 timeoff(struct tm *tmp, long offset)
3002 {
3003 if (tmp)
3004 tmp->tm_isdst = 0;
3005 gmtcheck();
3006 return time1(tmp, gmtsub, gmtptr, offset);
3007 }
3008 #endif
3009
3010 #if !USE_TIMEX_T
3011 time_t
timegm(struct tm * tmp)3012 timegm(struct tm *tmp)
3013 {
3014 time_t t;
3015 struct tm tmcpy;
3016 mktmcpy(&tmcpy, tmp);
3017 tmcpy.tm_wday = -1;
3018 t = timeoff(&tmcpy, 0);
3019 if (0 <= tmcpy.tm_wday)
3020 *tmp = tmcpy;
3021 return t;
3022 }
3023 #endif
3024
3025 static int_fast32_2s
leapcorr(struct state const * sp,time_t t)3026 leapcorr(struct state const *sp, time_t t)
3027 {
3028 register int i;
3029
3030 i = leapcount(sp);
3031 while (--i >= 0) {
3032 struct lsinfo ls = lsinfo(sp, i);
3033 if (ls.ls_trans <= t)
3034 return ls.ls_corr;
3035 }
3036 return 0;
3037 }
3038
3039 /*
3040 ** XXX--is the below the right way to conditionalize??
3041 */
3042
3043 #if !USE_TIMEX_T
3044 # if STD_INSPIRED
3045
3046 static bool
decrement_overflow_time(time_t * tp,int_fast32_2s j)3047 decrement_overflow_time(time_t *tp, int_fast32_2s j)
3048 {
3049 #ifdef ckd_sub
3050 return ckd_sub(tp, *tp, j);
3051 #else
3052 if (! (j < 0
3053 ? *tp <= TIME_T_MAX + j
3054 : (TYPE_SIGNED(time_t) ? TIME_T_MIN + j <= *tp : j <= *tp)))
3055 return true;
3056 *tp -= j;
3057 return false;
3058 #endif
3059 }
3060
3061 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
3062 NETBSD_INSPIRED is defined, and are private otherwise. */
3063 # if NETBSD_INSPIRED
3064 # define NETBSD_INSPIRED_EXTERN
3065 # else
3066 # define NETBSD_INSPIRED_EXTERN static
3067 # endif
3068
3069 /*
3070 ** IEEE Std 1003.1 (POSIX) says that 536457599
3071 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
3072 ** is not the case if we are accounting for leap seconds.
3073 ** So, we provide the following conversion routines for use
3074 ** when exchanging timestamps with POSIX conforming systems.
3075 */
3076
3077 NETBSD_INSPIRED_EXTERN time_t
time2posix_z(struct state * sp,time_t t)3078 time2posix_z(struct state *sp, time_t t)
3079 {
3080 if (decrement_overflow_time(&t, leapcorr(sp, t))) {
3081 /* Overflow near maximum time_t value with negative correction.
3082 This can happen with unrealistic-but-valid TZif files. */
3083 errno = EOVERFLOW;
3084 return -1;
3085 }
3086 return t;
3087 }
3088
3089 time_t
time2posix(time_t t)3090 time2posix(time_t t)
3091 {
3092 monotime_t now = get_monotonic_time();
3093 int err = lock();
3094 if (0 < err) {
3095 errno = err;
3096 return -1;
3097 }
3098 if (0 <= tz_change_interval || !lcl_is_set)
3099 tzset_unlocked(!err, false, now);
3100 if (lclptr)
3101 t = time2posix_z(lclptr, t);
3102 unlock(!err);
3103 return t;
3104 }
3105
3106 NETBSD_INSPIRED_EXTERN time_t
posix2time_z(struct state * sp,time_t t)3107 posix2time_z(struct state *sp, time_t t)
3108 {
3109 int i;
3110 for (i = leapcount(sp); 0 <= --i; ) {
3111 struct lsinfo ls = lsinfo(sp, i);
3112 time_t t_corr = t;
3113
3114 if (increment_overflow_time(&t_corr, ls.ls_corr)) {
3115 if (0 <= ls.ls_corr) {
3116 /* Overflow near maximum time_t value with positive correction.
3117 This can happen with ordinary TZif files with leap seconds. */
3118 errno = EOVERFLOW;
3119 return -1;
3120 } else {
3121 /* A negative correction overflowed, so keep going.
3122 This can happen with unrealistic-but-valid TZif files. */
3123 }
3124 } else if (ls.ls_trans <= t_corr)
3125 return (t_corr
3126 - (ls.ls_trans == t_corr
3127 && (i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < ls.ls_corr));
3128 }
3129 return t;
3130 }
3131
3132 time_t
posix2time(time_t t)3133 posix2time(time_t t)
3134 {
3135 monotime_t now = get_monotonic_time();
3136 int err = lock();
3137 if (0 < err) {
3138 errno = err;
3139 return -1;
3140 }
3141 if (0 <= tz_change_interval || !lcl_is_set)
3142 tzset_unlocked(!err, false, now);
3143 if (lclptr)
3144 t = posix2time_z(lclptr, t);
3145 unlock(!err);
3146 return t;
3147 }
3148
3149 # endif /* STD_INSPIRED */
3150
3151 # if TZ_TIME_T
3152
3153 # if !USG_COMPAT
3154 # define timezone 0
3155 # endif
3156
3157 /* Convert from the underlying system's time_t to the ersatz time_tz,
3158 which is called 'time_t' in this file. Typically, this merely
3159 converts the time's integer width. On some platforms, the system
3160 time is local time not UT, or uses some epoch other than the POSIX
3161 epoch.
3162
3163 Although this code appears to define a function named 'time' that
3164 returns time_t, the macros in private.h cause this code to actually
3165 define a function named 'tz_time' that returns tz_time_t. The call
3166 to sys_time invokes the underlying system's 'time' function. */
3167
3168 time_t
time(time_t * p)3169 time(time_t *p)
3170 {
3171 time_t r = sys_time(NULL);
3172 if (r != (time_t) -1) {
3173 iinntt offset = EPOCH_LOCAL ? timezone : 0;
3174 if (offset < IINNTT_MIN + EPOCH_OFFSET
3175 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) {
3176 errno = EOVERFLOW;
3177 r = -1;
3178 }
3179 }
3180 if (p)
3181 *p = r;
3182 return r;
3183 }
3184
3185 # endif
3186 #endif
3187