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