1 /* Copyright (C) 1991-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
21 #include <stdio_ext.h>
29 #include <timezone/tzfile.h>
32 static dev_t tzfile_dev;
33 static ino64_t tzfile_ino;
34 static time_t tzfile_mtime;
38 long int offset; /* Seconds east of GMT. */
39 unsigned char isdst; /* Used to set tm_isdst. */
40 unsigned char idx; /* Index into `zone_names'. */
41 unsigned char isstd; /* Transition times are in standard time. */
42 unsigned char isgmt; /* Transition times are in GMT. */
47 internal_time_t transition; /* Time the transition takes effect. */
48 long int change; /* Seconds of correction to apply. */
51 static size_t num_transitions;
52 libc_freeres_ptr (static internal_time_t *transitions);
53 static unsigned char *type_idxs;
54 static size_t num_types;
55 static struct ttinfo *types;
56 static char *zone_names;
57 static long int rule_stdoff;
58 static long int rule_dstoff;
59 static size_t num_leaps;
60 static struct leap *leaps;
66 /* Decode the four bytes at PTR as a signed integer in network byte order. */
68 __attribute ((always_inline))
69 decode (const void *ptr)
71 if (BYTE_ORDER == BIG_ENDIAN && sizeof (int) == 4)
72 return *(const int *) ptr;
73 if (sizeof (int) == 4)
74 return bswap_32 (*(const int *) ptr);
76 const unsigned char *p = ptr;
77 int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
79 result = (result << 8) | *p++;
80 result = (result << 8) | *p++;
81 result = (result << 8) | *p++;
82 result = (result << 8) | *p++;
89 __attribute ((always_inline))
90 decode64 (const void *ptr)
92 if ((BYTE_ORDER == BIG_ENDIAN))
93 return *(const int64_t *) ptr;
95 return bswap_64 (*(const int64_t *) ptr);
100 __tzfile_read (const char *file, size_t extra, char **extrap)
102 static const char default_tzdir[] = TZDIR;
103 size_t num_isstd, num_isgmt;
105 struct tzhead tzhead;
111 int was_using_tzfile = __use_tzfile;
116 _Static_assert (sizeof (internal_time_t) == 8,
117 "internal_time_t must be eight bytes");
122 /* No user specification; use the site-wide default. */
124 else if (*file == '\0')
125 /* User specified the empty string; use UTC with no leap seconds. */
126 goto ret_free_transitions;
129 /* We must not allow to read an arbitrary file in a setuid
130 program. So we fail for any file which is not in the
131 directory hierachy starting at TZDIR
132 and which is not the system wide default TZDEFAULT. */
133 if (__libc_enable_secure
135 && memcmp (file, TZDEFAULT, sizeof TZDEFAULT)
136 && memcmp (file, default_tzdir, sizeof (default_tzdir) - 1))
137 || strstr (file, "../") != NULL))
138 /* This test is certainly a bit too restrictive but it should
139 catch all critical cases. */
140 goto ret_free_transitions;
147 tzdir = getenv ("TZDIR");
148 if (tzdir == NULL || *tzdir == '\0')
149 tzdir = default_tzdir;
150 if (__asprintf (&new, "%s/%s", tzdir, file) == -1)
151 goto ret_free_transitions;
155 /* If we were already using tzfile, check whether the file changed. */
158 && stat64 (file, &st) == 0
159 && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev
160 && tzfile_mtime == st.st_mtime)
161 goto done; /* Nothing to do. */
163 /* Note the file is opened with cancellation in the I/O functions
164 disabled and if available FD_CLOEXEC set. */
165 f = fopen (file, "rce");
167 goto ret_free_transitions;
169 /* Get information about the file we are actually using. */
170 if (fstat64 (__fileno (f), &st) != 0)
173 free ((void *) transitions);
176 /* Remember the inode and device number and modification time. */
177 tzfile_dev = st.st_dev;
178 tzfile_ino = st.st_ino;
179 tzfile_mtime = st.st_mtime;
181 /* No threads reading this stream. */
182 __fsetlocking (f, FSETLOCKING_BYCALLER);
185 if (__builtin_expect (__fread_unlocked ((void *) &tzhead, sizeof (tzhead),
187 || memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)
190 num_transitions = (size_t) decode (tzhead.tzh_timecnt);
191 num_types = (size_t) decode (tzhead.tzh_typecnt);
192 chars = (size_t) decode (tzhead.tzh_charcnt);
193 num_leaps = (size_t) decode (tzhead.tzh_leapcnt);
194 num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
195 num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
197 if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types))
200 if (trans_width == 4 && tzhead.tzh_version[0] != '\0')
202 /* We use the 8-byte format. */
205 /* Position the stream before the second header. */
206 size_t to_skip = (num_transitions * (4 + 1)
212 if (fseek (f, to_skip, SEEK_CUR) != 0)
218 if (__builtin_expect (num_transitions
219 > ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1))
220 / (sizeof (internal_time_t) + 1)), 0))
222 total_size = num_transitions * (sizeof (internal_time_t) + 1);
223 total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
224 & ~(__alignof__ (struct ttinfo) - 1));
225 types_idx = total_size;
226 if (__builtin_expect (num_types
227 > (SIZE_MAX - total_size) / sizeof (struct ttinfo), 0))
229 total_size += num_types * sizeof (struct ttinfo);
230 if (__glibc_unlikely (chars > SIZE_MAX - total_size))
233 if (__builtin_expect (__alignof__ (struct leap) - 1
234 > SIZE_MAX - total_size, 0))
236 total_size = ((total_size + __alignof__ (struct leap) - 1)
237 & ~(__alignof__ (struct leap) - 1));
238 leaps_idx = total_size;
239 if (__builtin_expect (num_leaps
240 > (SIZE_MAX - total_size) / sizeof (struct leap), 0))
242 total_size += num_leaps * sizeof (struct leap);
244 if (trans_width == 8)
246 off_t rem = st.st_size - __ftello (f);
247 if (__builtin_expect (rem < 0
248 || (size_t) rem < (num_transitions * (8 + 1)
252 tzspec_len = (size_t) rem - (num_transitions * (8 + 1)
255 if (__builtin_expect (num_leaps > SIZE_MAX / 12
256 || tzspec_len < num_leaps * 12, 0))
258 tzspec_len -= num_leaps * 12;
259 if (__glibc_unlikely (tzspec_len < num_isstd))
261 tzspec_len -= num_isstd;
262 if (__glibc_unlikely (tzspec_len == 0 || tzspec_len - 1 < num_isgmt))
264 tzspec_len -= num_isgmt + 1;
265 if (__glibc_unlikely (tzspec_len == 0
266 || SIZE_MAX - total_size < tzspec_len))
269 if (__glibc_unlikely (SIZE_MAX - total_size - tzspec_len < extra))
272 /* Allocate enough memory including the extra block requested by the
274 transitions = malloc (total_size + tzspec_len + extra);
275 if (transitions == NULL)
278 type_idxs = (unsigned char *) transitions + (num_transitions
279 * sizeof (internal_time_t));
280 types = (struct ttinfo *) ((char *) transitions + types_idx);
281 zone_names = (char *) types + num_types * sizeof (struct ttinfo);
282 leaps = (struct leap *) ((char *) transitions + leaps_idx);
283 if (trans_width == 8)
284 tzspec = (char *) leaps + num_leaps * sizeof (struct leap) + extra;
288 *extrap = (char *) &leaps[num_leaps];
290 if (__builtin_expect (trans_width == 8, 1))
292 if (__builtin_expect (__fread_unlocked (transitions, trans_width + 1,
294 != num_transitions, 0))
299 if (__builtin_expect (__fread_unlocked (transitions, 4,
301 != num_transitions, 0)
302 || __builtin_expect (__fread_unlocked (type_idxs, 1, num_transitions,
303 f) != num_transitions, 0))
307 /* Check for bogus indices in the data file, so we can hereafter
308 safely use type_idxs[T] as indices into `types' and never crash. */
309 for (i = 0; i < num_transitions; ++i)
310 if (__glibc_unlikely (type_idxs[i] >= num_types))
313 if (trans_width == 4)
315 /* Decode the transition times, stored as 4-byte integers in
316 network (big-endian) byte order. We work from the end of the
317 array so as not to clobber the next element to be
321 transitions[i] = decode ((char *) transitions + i * 4);
323 else if (BYTE_ORDER != BIG_ENDIAN)
325 /* Decode the transition times, stored as 8-byte integers in
326 network (big-endian) byte order. */
327 for (i = 0; i < num_transitions; ++i)
328 transitions[i] = decode64 ((char *) transitions + i * 8);
331 for (i = 0; i < num_types; ++i)
335 if (__builtin_expect (__fread_unlocked (x, 1,
336 sizeof (x), f) != sizeof (x),
339 c = __getc_unlocked (f);
340 if (__glibc_unlikely ((unsigned int) c > 1u))
343 c = __getc_unlocked (f);
344 if (__glibc_unlikely ((size_t) c > chars))
345 /* Bogus index in data file. */
348 types[i].offset = (long int) decode (x);
351 if (__glibc_unlikely (__fread_unlocked (zone_names, 1, chars, f) != chars))
354 for (i = 0; i < num_leaps; ++i)
357 if (__builtin_expect (__fread_unlocked (x, 1, trans_width, f)
360 if (trans_width == 4)
361 leaps[i].transition = decode (x);
363 leaps[i].transition = decode64 (x);
365 if (__glibc_unlikely (__fread_unlocked (x, 1, 4, f) != 4))
367 leaps[i].change = (long int) decode (x);
370 for (i = 0; i < num_isstd; ++i)
372 int c = __getc_unlocked (f);
373 if (__glibc_unlikely (c == EOF))
375 types[i].isstd = c != 0;
377 while (i < num_types)
378 types[i++].isstd = 0;
380 for (i = 0; i < num_isgmt; ++i)
382 int c = __getc_unlocked (f);
383 if (__glibc_unlikely (c == EOF))
385 types[i].isgmt = c != 0;
387 while (i < num_types)
388 types[i++].isgmt = 0;
390 /* Read the POSIX TZ-style information if possible. */
393 /* Skip over the newline first. */
394 if (__getc_unlocked (f) != '\n'
395 || (__fread_unlocked (tzspec, 1, tzspec_len - 1, f)
399 tzspec[tzspec_len - 1] = '\0';
402 /* Don't use an empty TZ string. */
403 if (tzspec != NULL && tzspec[0] == '\0')
408 /* First "register" all timezone names. */
409 for (i = 0; i < num_types; ++i)
410 if (__tzstring (&zone_names[types[i].idx]) == NULL)
411 goto ret_free_transitions;
413 /* Find the standard and daylight time offsets used by the rule file.
414 We choose the offsets in the types of each flavor that are
415 transitioned to earliest in time. */
418 for (i = num_transitions; i > 0; )
420 int type = type_idxs[--i];
421 int dst = types[type].isdst;
423 if (__tzname[dst] == NULL)
425 int idx = types[type].idx;
427 __tzname[dst] = __tzstring (&zone_names[idx]);
429 if (__tzname[1 - dst] != NULL)
433 if (__tzname[0] == NULL)
435 /* This should only happen if there are no transition rules.
436 In this case there should be only one single type. */
437 assert (num_types == 1);
438 __tzname[0] = __tzstring (zone_names);
440 if (__tzname[1] == NULL)
441 __tzname[1] = __tzname[0];
443 if (num_transitions == 0)
444 /* Use the first rule (which should also be the only one). */
445 rule_stdoff = rule_dstoff = types[0].offset;
448 int stdoff_set = 0, dstoff_set = 0;
449 rule_stdoff = rule_dstoff = 0;
450 i = num_transitions - 1;
453 if (!stdoff_set && !types[type_idxs[i]].isdst)
456 rule_stdoff = types[type_idxs[i]].offset;
458 else if (!dstoff_set && types[type_idxs[i]].isdst)
461 rule_dstoff = types[type_idxs[i]].offset;
463 if (stdoff_set && dstoff_set)
469 rule_dstoff = rule_stdoff;
472 __daylight = rule_stdoff != rule_dstoff;
473 __timezone = -rule_stdoff;
482 ret_free_transitions:
484 free ((void *) transitions);
488 /* The user specified a hand-made timezone, but not its DST rules.
489 We will use the names and offsets from the user, and the rules
490 from the TZDEFRULES file. */
493 __tzfile_default (const char *std, const char *dst,
494 long int stdoff, long int dstoff)
496 size_t stdlen = strlen (std) + 1;
497 size_t dstlen = strlen (dst) + 1;
502 __tzfile_read (TZDEFRULES, stdlen + dstlen, &cp);
512 /* Ignore the zone names read from the file and use the given ones
514 __mempcpy (__mempcpy (cp, std, stdlen), dst, dstlen);
517 /* Now there are only two zones, regardless of what the file contained. */
520 /* Now correct the transition times for the user-specified standard and
521 daylight offsets from GMT. */
523 for (i = 0; i < num_transitions; ++i)
525 struct ttinfo *trans_type = &types[type_idxs[i]];
527 /* We will use only types 0 (standard) and 1 (daylight).
528 Fix up this transition to point to whichever matches
529 the flavor of its original type. */
530 type_idxs[i] = trans_type->isdst;
532 if (trans_type->isgmt)
533 /* The transition time is in GMT. No correction to apply. */ ;
534 else if (isdst && !trans_type->isstd)
535 /* The type says this transition is in "local wall clock time", and
536 wall clock time as of the previous transition was DST. Correct
537 for the difference between the rule's DST offset and the user's
539 transitions[i] += dstoff - rule_dstoff;
541 /* This transition is in "local wall clock time", and wall clock
542 time as of this iteration is non-DST. Correct for the
543 difference between the rule's standard offset and the user's
545 transitions[i] += stdoff - rule_stdoff;
547 /* The DST state of "local wall clock time" for the next iteration is
548 as specified by this transition. */
549 isdst = trans_type->isdst;
552 /* Now that we adjusted the transitions to the requested offsets,
553 reset the rule_stdoff and rule_dstoff values appropriately. They
554 are used elsewhere. */
555 rule_stdoff = stdoff;
556 rule_dstoff = dstoff;
558 /* Reset types 0 and 1 to describe the user's settings. */
560 types[0].offset = stdoff;
562 types[1].idx = stdlen;
563 types[1].offset = dstoff;
566 /* Reset the zone names to point to the user's names. */
567 __tzname[0] = (char *) std;
568 __tzname[1] = (char *) dst;
570 /* Set the timezone. */
571 __timezone = -types[0].offset;
573 /* Invalidate the tzfile attribute cache to force rereading
574 TZDEFRULES the next time it is used. */
581 __tzfile_compute (internal_time_t timer, int use_localtime,
582 long int *leap_correct, int *leap_hit,
592 if (__glibc_unlikely (num_transitions == 0 || timer < transitions[0]))
594 /* TIMER is before any transition (or there are no transitions).
595 Choose the first non-DST type
596 (or the first if they're all DST types). */
598 while (i < num_types && types[i].isdst)
600 if (__tzname[1] == NULL)
601 __tzname[1] = __tzstring (&zone_names[types[i].idx]);
608 __tzname[0] = __tzstring (&zone_names[types[i].idx]);
609 if (__tzname[1] == NULL)
612 while (j < num_types)
615 __tzname[1] = __tzstring (&zone_names[types[j].idx]);
622 else if (__glibc_unlikely (timer >= transitions[num_transitions - 1]))
624 if (__glibc_unlikely (tzspec == NULL))
631 /* Parse the POSIX TZ-style string. */
632 __tzset_parse_tz (tzspec);
634 /* Convert to broken down structure. If this fails do not
637 time_t truncated = timer;
638 if (__glibc_unlikely (truncated != timer
639 || ! __offtime (&truncated, 0, tp)))
643 /* Use the rules from the TZ string to compute the change.
644 timer fits into time_t due to the truncation check
646 __tz_compute (timer, tp, 1);
648 /* If tzspec comes from posixrules loaded by __tzfile_default,
649 override the STD and DST zone names with the ones user
650 requested in TZ envvar. */
651 if (__glibc_unlikely (zone_names == (char *) &leaps[num_leaps]))
653 assert (num_types == 2);
654 __tzname[0] = __tzstring (zone_names);
655 __tzname[1] = __tzstring (&zone_names[strlen (zone_names) + 1]);
662 /* Find the first transition after TIMER, and
663 then pick the type of the transition before it. */
665 size_t hi = num_transitions - 1;
666 /* Assume that DST is changing twice a year and guess
667 initial search spot from it. Half of a gregorian year
668 has on average 365.2425 * 86400 / 2 = 15778476 seconds.
669 The value i can be truncated if size_t is smaller than
670 internal_time_t, but this is harmless because it is just
672 i = (transitions[num_transitions - 1] - timer) / 15778476;
673 if (i < num_transitions)
675 i = num_transitions - 1 - i;
676 if (timer < transitions[i])
678 if (i < 10 || timer >= transitions[i - 10])
681 while (timer < transitions[i - 1])
689 if (i + 10 >= num_transitions || timer < transitions[i + 10])
692 while (timer >= transitions[i])
701 /* assert (timer >= transitions[lo] && timer < transitions[hi]); */
705 if (timer < transitions[i])
713 /* assert (timer >= transitions[i - 1]
714 && (i == num_transitions || timer < transitions[i])); */
715 __tzname[types[type_idxs[i - 1]].isdst]
716 = __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
718 while (j < num_transitions)
720 int type = type_idxs[j];
721 int dst = types[type].isdst;
722 int idx = types[type].idx;
724 if (__tzname[dst] == NULL)
726 __tzname[dst] = __tzstring (&zone_names[idx]);
728 if (__tzname[1 - dst] != NULL)
735 if (__glibc_unlikely (__tzname[0] == NULL))
736 __tzname[0] = __tzname[1];
738 i = type_idxs[i - 1];
741 struct ttinfo *info = &types[i];
742 __daylight = rule_stdoff != rule_dstoff;
743 __timezone = -rule_stdoff;
745 if (__tzname[0] == NULL)
747 /* This should only happen if there are no transition rules.
748 In this case there should be only one single type. */
749 assert (num_types == 1);
750 __tzname[0] = __tzstring (zone_names);
752 if (__tzname[1] == NULL)
753 /* There is no daylight saving time. */
754 __tzname[1] = __tzname[0];
755 tp->tm_isdst = info->isdst;
756 assert (strcmp (&zone_names[info->idx], __tzname[tp->tm_isdst]) == 0);
757 tp->tm_zone = __tzname[tp->tm_isdst];
758 tp->tm_gmtoff = info->offset;
765 /* Find the last leap second correction transition time before TIMER. */
770 while (timer < leaps[i].transition);
772 /* Apply its correction. */
773 *leap_correct = leaps[i].change;
775 if (timer == leaps[i].transition && /* Exactly at the transition time. */
776 ((i == 0 && leaps[i].change > 0) ||
777 leaps[i].change > leaps[i - 1].change))
781 && leaps[i].transition == leaps[i - 1].transition + 1
782 && leaps[i].change == leaps[i - 1].change + 1)