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