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