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