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