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