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