Age Owner TLA Line data Source code
1 : /* Convert timestamp from pg_time_t to struct pg_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 : * IDENTIFICATION
8 : * src/timezone/localtime.c
9 : */
10 :
11 : /*
12 : * Leap second handling from Bradley White.
13 : * POSIX-style TZ environment variable handling from Guy Harris.
14 : */
15 :
16 : /* this file needs to build in both frontend and backend contexts */
17 : #include "c.h"
18 :
19 : #include <fcntl.h>
20 :
21 : #include "datatype/timestamp.h"
22 : #include "pgtz.h"
23 :
24 : #include "private.h"
25 : #include "tzfile.h"
26 :
27 :
28 : #ifndef WILDABBR
29 : /*
30 : * Someone might make incorrect use of a time zone abbreviation:
31 : * 1. They might reference tzname[0] before calling tzset (explicitly
32 : * or implicitly).
33 : * 2. They might reference tzname[1] before calling tzset (explicitly
34 : * or implicitly).
35 : * 3. They might reference tzname[1] after setting to a time zone
36 : * in which Daylight Saving Time is never observed.
37 : * 4. They might reference tzname[0] after setting to a time zone
38 : * in which Standard Time is never observed.
39 : * 5. They might reference tm.tm_zone after calling offtime.
40 : * What's best to do in the above cases is open to debate;
41 : * for now, we just set things up so that in any of the five cases
42 : * WILDABBR is used. Another possibility: initialize tzname[0] to the
43 : * string "tzname[0] used before set", and similarly for the other cases.
44 : * And another: initialize tzname[0] to "ERA", with an explanation in the
45 : * manual page of what this "time zone abbreviation" means (doing this so
46 : * that tzname[0] has the "normal" length of three characters).
47 : */
48 : #define WILDABBR " "
49 : #endif /* !defined WILDABBR */
50 :
51 : static const char wildabbr[] = WILDABBR;
52 :
53 : static const char gmt[] = "GMT";
54 :
55 : /*
56 : * The DST rules to use if a POSIX TZ string has no rules.
57 : * Default to US rules as of 2017-05-07.
58 : * POSIX does not specify the default DST rules;
59 : * for historical reasons, US rules are a common default.
60 : */
61 : #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
62 :
63 : /* structs ttinfo, lsinfo, state have been moved to pgtz.h */
64 :
65 : enum r_type
66 : {
67 : JULIAN_DAY, /* Jn = Julian day */
68 : DAY_OF_YEAR, /* n = day of year */
69 : MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
70 : };
71 :
72 : struct rule
73 : {
74 : enum r_type r_type; /* type of rule */
75 : int r_day; /* day number of rule */
76 : int r_week; /* week number of rule */
77 : int r_mon; /* month number of rule */
78 : int32 r_time; /* transition time of rule */
79 : };
80 :
81 : /*
82 : * Prototypes for static functions.
83 : */
84 :
85 : static struct pg_tm *gmtsub(pg_time_t const *timep, int32 offset,
86 : struct pg_tm *tmp);
87 : static bool increment_overflow(int *ip, int j);
88 : static bool increment_overflow_time(pg_time_t *tp, int32 j);
89 : static int64 leapcorr(struct state const *sp, pg_time_t t);
90 : static struct pg_tm *timesub(pg_time_t const *timep,
91 : int32 offset, struct state const *sp,
92 : struct pg_tm *tmp);
93 : static bool typesequiv(struct state const *sp, int a, int b);
94 :
95 :
96 : /*
97 : * Section 4.12.3 of X3.159-1989 requires that
98 : * Except for the strftime function, these functions [asctime,
99 : * ctime, gmtime, localtime] return values in one of two static
100 : * objects: a broken-down time structure and an array of char.
101 : * Thanks to Paul Eggert for noting this.
102 : */
103 :
104 : static struct pg_tm tm;
105 :
106 : /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
107 : static void
1362 tgl 108 GIC 17559 : init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
109 : {
1362 tgl 110 CBC 17559 : s->tt_utoff = utoff;
2568 tgl 111 GIC 17559 : s->tt_isdst = isdst;
1362 tgl 112 CBC 17559 : s->tt_desigidx = desigidx;
2568 113 17559 : s->tt_ttisstd = false;
1362 114 17559 : s->tt_ttisut = false;
2568 115 17559 : }
6918 bruce 116 ECB :
2568 tgl 117 : static int32
1633 tgl 118 GIC 164788 : detzcode(const char *const codep)
119 : {
2568 tgl 120 ECB : int32 result;
121 : int i;
2568 tgl 122 GIC 164788 : int32 one = 1;
123 164788 : int32 halfmaxval = one << (32 - 2);
2568 tgl 124 CBC 164788 : int32 maxval = halfmaxval - 1 + halfmaxval;
125 164788 : int32 minval = -1 - maxval;
6918 bruce 126 ECB :
2568 tgl 127 CBC 164788 : result = codep[0] & 0x7f;
2568 tgl 128 GIC 659152 : for (i = 1; i < 4; ++i)
6918 bruce 129 CBC 494364 : result = (result << 8) | (codep[i] & 0xff);
2568 tgl 130 ECB :
2568 tgl 131 CBC 164788 : if (codep[0] & 0x80)
132 : {
2568 tgl 133 ECB : /*
134 : * Do two's-complement negation even on non-two's-complement machines.
135 : * If the result would be minval - 1, return minval.
136 : */
1058 tgl 137 GIC 28643 : result -= !TWOS_COMPLEMENT(int32) && result != 0;
2568 138 28643 : result += minval;
2568 tgl 139 ECB : }
6918 bruce 140 CBC 164788 : return result;
141 : }
6918 bruce 142 ECB :
143 : static int64
1633 tgl 144 GIC 658298 : detzcode64(const char *const codep)
145 : {
2568 tgl 146 ECB : uint64 result;
147 : int i;
2568 tgl 148 GIC 658298 : int64 one = 1;
149 658298 : int64 halfmaxval = one << (64 - 2);
2568 tgl 150 CBC 658298 : int64 maxval = halfmaxval - 1 + halfmaxval;
1058 151 658298 : int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
2568 tgl 152 ECB :
2568 tgl 153 CBC 658298 : result = codep[0] & 0x7f;
2568 tgl 154 GIC 5266384 : for (i = 1; i < 8; ++i)
2568 tgl 155 CBC 4608086 : result = (result << 8) | (codep[i] & 0xff);
5531 tgl 156 ECB :
2568 tgl 157 CBC 658298 : if (codep[0] & 0x80)
158 : {
2568 tgl 159 ECB : /*
160 : * Do two's-complement negation even on non-two's-complement machines.
161 : * If the result would be minval - 1, return minval.
162 : */
1058 tgl 163 GIC 181155 : result -= !TWOS_COMPLEMENT(int64) && result != 0;
2568 164 181155 : result += minval;
2568 tgl 165 ECB : }
5531 tgl 166 CBC 658298 : return result;
167 : }
5531 tgl 168 ECB :
169 : static bool
2568 tgl 170 GIC 6590753 : differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
171 : {
1058 tgl 172 ECB : if (TYPE_BIT(pg_time_t) - TYPE_SIGNED(pg_time_t) < SECSPERREPEAT_BITS)
173 : return 0;
5531 tgl 174 GIC 6590753 : return t1 - t0 == SECSPERREPEAT;
175 : }
5531 tgl 176 ECB :
177 : /* Input buffer for data read from a compiled tz file. */
178 : union input_buffer
179 : {
180 : /* The first part of the buffer, interpreted as a header. */
181 : struct tzhead tzhead;
182 :
183 : /* The entire buffer. */
184 : char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
185 : + 4 * TZ_MAX_TIMES];
186 : };
187 :
188 : /* Local storage needed for 'tzloadbody'. */
189 : union local_storage
190 : {
191 : /* The results of analyzing the file's contents after it is opened. */
192 : struct file_analysis
193 : {
194 : /* The input buffer. */
195 : union input_buffer u;
196 :
197 : /* A temporary state used for parsing a TZ string in the file. */
198 : struct state st;
199 : } u;
200 :
201 : /* We don't need the "fullname" member */
202 : };
203 :
204 : /* Load tz data from the file named NAME into *SP. Read extended
205 : * format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
206 : * success, an errno value on failure.
207 : * PG: If "canonname" is not NULL, then on success the canonical spelling of
208 : * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
209 : */
210 : static int
2118 tgl 211 GIC 9742 : tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
212 : union local_storage *lsp)
6918 bruce 213 ECB : {
214 : int i;
215 : int fid;
216 : int stored;
217 : ssize_t nread;
2568 tgl 218 GIC 9742 : union input_buffer *up = &lsp->u.u;
219 9742 : int tzheadsize = sizeof(struct tzhead);
2568 tgl 220 ECB :
2568 tgl 221 CBC 9742 : sp->goback = sp->goahead = false;
222 :
223 9742 : if (!name)
224 : {
2568 tgl 225 LBC 0 : name = TZDEFAULT;
2568 tgl 226 UIC 0 : if (!name)
2568 tgl 227 UBC 0 : return EINVAL;
2568 tgl 228 EUB : }
6918 bruce 229 :
6019 tgl 230 GIC 9742 : if (name[0] == ':')
6019 tgl 231 UIC 0 : ++name;
2568 tgl 232 ECB :
6019 tgl 233 GBC 9742 : fid = pg_open_tzfile(name, canonname);
6019 tgl 234 GIC 9742 : if (fid < 0)
2568 tgl 235 CBC 205 : return ENOENT; /* pg_open_tzfile may not set errno */
2568 tgl 236 ECB :
2568 tgl 237 CBC 9537 : nread = read(fid, up->buf, sizeof up->buf);
2568 tgl 238 GIC 9537 : if (nread < tzheadsize)
2568 tgl 239 ECB : {
2568 tgl 240 LBC 0 : int err = nread < 0 ? errno : EINVAL;
241 :
2568 tgl 242 UBC 0 : close(fid);
2568 tgl 243 UIC 0 : return err;
2568 tgl 244 EUB : }
2568 tgl 245 GBC 9537 : if (close(fid) < 0)
2568 tgl 246 UIC 0 : return errno;
5531 tgl 247 CBC 28611 : for (stored = 4; stored <= 8; stored *= 2)
6918 bruce 248 EUB : {
2568 tgl 249 CBC 19074 : int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
1362 tgl 250 GIC 19074 : int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
2025 tgl 251 CBC 19074 : int64 prevtr = 0;
252 19074 : int32 prevcorr = 0;
2568 253 19074 : int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
254 19074 : int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
255 19074 : int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
256 19074 : int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
257 19074 : char const *p = up->buf + tzheadsize;
2568 tgl 258 ECB :
1633 259 : /*
260 : * Although tzfile(5) currently requires typecnt to be nonzero,
261 : * support future formats that may allow zero typecnt in files that
262 : * have a TZ string and no transitions.
263 : */
2568 tgl 264 GIC 38148 : if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
1633 265 19074 : && 0 <= typecnt && typecnt < TZ_MAX_TYPES
2568 tgl 266 CBC 19074 : && 0 <= timecnt && timecnt < TZ_MAX_TIMES
267 19074 : && 0 <= charcnt && charcnt < TZ_MAX_CHARS
268 19074 : && (ttisstdcnt == typecnt || ttisstdcnt == 0)
1362 269 19074 : && (ttisutcnt == typecnt || ttisutcnt == 0)))
2568 tgl 270 LBC 0 : return EINVAL;
2568 tgl 271 CBC 19074 : if (nread
2568 tgl 272 EUB : < (tzheadsize /* struct tzhead */
2118 tgl 273 CBC 19074 : + timecnt * stored /* ats */
2568 tgl 274 GIC 19074 : + timecnt /* types */
2568 tgl 275 CBC 19074 : + typecnt * 6 /* ttinfos */
276 19074 : + charcnt /* chars */
277 19074 : + leapcnt * (stored + 4) /* lsinfos */
278 19074 : + ttisstdcnt /* ttisstds */
1362 279 19074 : + ttisutcnt)) /* ttisuts */
2568 tgl 280 LBC 0 : return EINVAL;
2568 tgl 281 CBC 19074 : sp->leapcnt = leapcnt;
2568 tgl 282 GBC 19074 : sp->timecnt = timecnt;
2568 tgl 283 CBC 19074 : sp->typecnt = typecnt;
284 19074 : sp->charcnt = charcnt;
2568 tgl 285 ECB :
286 : /*
287 : * Read transitions, discarding those out of pg_time_t range. But
288 : * pretend the last transition before TIME_T_MIN occurred at
289 : * TIME_T_MIN.
290 : */
2568 tgl 291 GIC 19074 : timecnt = 0;
6897 bruce 292 677372 : for (i = 0; i < sp->timecnt; ++i)
6897 bruce 293 ECB : {
2568 tgl 294 CBC 658298 : int64 at
2568 tgl 295 GIC 658298 : = stored == 4 ? detzcode(p) : detzcode64(p);
2568 tgl 296 ECB :
2025 tgl 297 CBC 658298 : sp->types[i] = at <= TIME_T_MAX;
2568 tgl 298 GIC 658298 : if (sp->types[i])
2568 tgl 299 ECB : {
2568 tgl 300 CBC 658298 : pg_time_t attime
301 : = ((TYPE_SIGNED(pg_time_t) ? at < TIME_T_MIN : at < 0)
2025 tgl 302 ECB : ? TIME_T_MIN : at);
303 :
2568 tgl 304 GIC 658298 : if (timecnt && attime <= sp->ats[timecnt - 1])
305 : {
2568 tgl 306 LBC 0 : if (attime < sp->ats[timecnt - 1])
2568 tgl 307 UIC 0 : return EINVAL;
2568 tgl 308 UBC 0 : sp->types[i - 1] = 0;
309 0 : timecnt--;
2568 tgl 310 EUB : }
2568 tgl 311 GBC 658298 : sp->ats[timecnt++] = attime;
312 : }
5531 tgl 313 CBC 658298 : p += stored;
314 : }
2568 tgl 315 ECB :
2568 tgl 316 GIC 19074 : timecnt = 0;
6897 bruce 317 677372 : for (i = 0; i < sp->timecnt; ++i)
6897 bruce 318 ECB : {
2568 tgl 319 CBC 658298 : unsigned char typ = *p++;
320 :
321 658298 : if (sp->typecnt <= typ)
2568 tgl 322 UIC 0 : return EINVAL;
2568 tgl 323 CBC 658298 : if (sp->types[i])
2568 tgl 324 GBC 658298 : sp->types[timecnt++] = typ;
6918 bruce 325 ECB : }
2568 tgl 326 CBC 19074 : sp->timecnt = timecnt;
6897 bruce 327 GIC 69418 : for (i = 0; i < sp->typecnt; ++i)
6897 bruce 328 ECB : {
6502 neilc 329 : struct ttinfo *ttisp;
330 : unsigned char isdst,
331 : desigidx;
332 :
6918 bruce 333 GIC 50344 : ttisp = &sp->ttis[i];
1362 tgl 334 50344 : ttisp->tt_utoff = detzcode(p);
6918 bruce 335 CBC 50344 : p += 4;
2568 tgl 336 50344 : isdst = *p++;
337 50344 : if (!(isdst < 2))
2568 tgl 338 LBC 0 : return EINVAL;
2568 tgl 339 CBC 50344 : ttisp->tt_isdst = isdst;
1362 tgl 340 GBC 50344 : desigidx = *p++;
1362 tgl 341 CBC 50344 : if (!(desigidx < sp->charcnt))
2568 tgl 342 LBC 0 : return EINVAL;
1362 tgl 343 CBC 50344 : ttisp->tt_desigidx = desigidx;
6918 bruce 344 EUB : }
6918 bruce 345 CBC 188956 : for (i = 0; i < sp->charcnt; ++i)
6918 bruce 346 GIC 169882 : sp->chars[i] = *p++;
6918 bruce 347 CBC 19074 : sp->chars[i] = '\0'; /* ensure '\0' at end */
2568 tgl 348 ECB :
349 : /* Read leap seconds, discarding those out of pg_time_t range. */
2568 tgl 350 GIC 19074 : leapcnt = 0;
6897 bruce 351 19074 : for (i = 0; i < sp->leapcnt; ++i)
6897 bruce 352 ECB : {
2568 tgl 353 LBC 0 : int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
2568 tgl 354 UIC 0 : int32 corr = detzcode(p + stored);
6918 bruce 355 EUB :
2568 tgl 356 UBC 0 : p += stored + 4;
357 : /* Leap seconds cannot occur before the Epoch. */
2025 358 0 : if (tr < 0)
2025 tgl 359 UIC 0 : return EINVAL;
2025 tgl 360 EUB : if (tr <= TIME_T_MAX)
2568 361 : {
362 : /*
363 : * Leap seconds cannot occur more than once per UTC month, and
364 : * UTC months are at least 28 days long (minus 1 second for a
365 : * negative leap second). Each leap second's correction must
366 : * differ from the previous one's by 1 second.
367 : */
2025 tgl 368 UIC 0 : if (tr - prevtr < 28 * SECSPERDAY - 1
369 0 : || (corr != prevcorr - 1 && corr != prevcorr + 1))
2025 tgl 370 UBC 0 : return EINVAL;
371 0 : sp->lsis[leapcnt].ls_trans = prevtr = tr;
372 0 : sp->lsis[leapcnt].ls_corr = prevcorr = corr;
2568 373 0 : leapcnt++;
2568 tgl 374 EUB : }
6918 bruce 375 : }
2568 tgl 376 GIC 19074 : sp->leapcnt = leapcnt;
377 :
6897 bruce 378 CBC 69418 : for (i = 0; i < sp->typecnt; ++i)
379 : {
6502 neilc 380 ECB : struct ttinfo *ttisp;
381 :
6918 bruce 382 GIC 50344 : ttisp = &sp->ttis[i];
383 50344 : if (ttisstdcnt == 0)
2568 tgl 384 CBC 50344 : ttisp->tt_ttisstd = false;
6897 bruce 385 ECB : else
386 : {
2568 tgl 387 UIC 0 : if (*p != true && *p != false)
388 0 : return EINVAL;
6918 bruce 389 UBC 0 : ttisp->tt_ttisstd = *p++;
6918 bruce 390 EUB : }
391 : }
6897 bruce 392 GIC 69418 : for (i = 0; i < sp->typecnt; ++i)
393 : {
6502 neilc 394 ECB : struct ttinfo *ttisp;
395 :
6918 bruce 396 GIC 50344 : ttisp = &sp->ttis[i];
1362 tgl 397 50344 : if (ttisutcnt == 0)
1362 tgl 398 CBC 50344 : ttisp->tt_ttisut = false;
6897 bruce 399 ECB : else
400 : {
2568 tgl 401 UIC 0 : if (*p != true && *p != false)
402 0 : return EINVAL;
1362 tgl 403 UBC 0 : ttisp->tt_ttisut = *p++;
6918 bruce 404 EUB : }
405 : }
406 :
407 : /*
408 : * If this is an old file, we're done.
409 : */
2568 tgl 410 GIC 19074 : if (up->tzhead.tzh_version[0] == '\0')
5531 tgl 411 UIC 0 : break;
2568 tgl 412 CBC 19074 : nread -= p - up->buf;
2568 tgl 413 GBC 19074 : memmove(up->buf, p, nread);
6918 bruce 414 ECB : }
5531 tgl 415 CBC 9537 : if (doextend && nread > 2 &&
2568 tgl 416 GIC 9537 : up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
5531 tgl 417 CBC 9537 : sp->typecnt + 2 <= TZ_MAX_TYPES)
5531 tgl 418 ECB : {
2568 tgl 419 CBC 9537 : struct state *ts = &lsp->u.st;
420 :
421 9537 : up->buf[nread - 1] = '\0';
1633 tgl 422 GIC 9537 : if (tzparse(&up->buf[1], ts, false))
5531 tgl 423 ECB : {
2568 424 : /*
425 : * Attempt to reuse existing abbreviations. Without this,
426 : * America/Anchorage would be right on the edge after 2037 when
427 : * TZ_MAX_CHARS is 50, as sp->charcnt equals 40 (for LMT AST AWT
428 : * APT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
429 : * AKST AKDT). Reusing means sp->charcnt can stay 40 in this
430 : * example.
431 : */
2568 tgl 432 GIC 9537 : int gotabbr = 0;
433 9537 : int charcnt = sp->charcnt;
2568 tgl 434 ECB :
1633 tgl 435 CBC 25079 : for (i = 0; i < ts->typecnt; i++)
436 : {
1362 437 15542 : char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
438 : int j;
2568 tgl 439 ECB :
2568 tgl 440 GIC 107259 : for (j = 0; j < charcnt; j++)
441 107243 : if (strcmp(sp->chars + j, tsabbr) == 0)
2568 tgl 442 ECB : {
1362 tgl 443 CBC 15526 : ts->ttis[i].tt_desigidx = j;
2568 tgl 444 GIC 15526 : gotabbr++;
2568 tgl 445 CBC 15526 : break;
2568 tgl 446 ECB : }
2568 tgl 447 CBC 15542 : if (!(j < charcnt))
448 : {
449 16 : int tsabbrlen = strlen(tsabbr);
450 :
451 16 : if (j + tsabbrlen < TZ_MAX_CHARS)
452 : {
453 16 : strcpy(sp->chars + j, tsabbr);
2568 tgl 454 GIC 16 : charcnt = j + tsabbrlen + 1;
1362 tgl 455 CBC 16 : ts->ttis[i].tt_desigidx = j;
2568 456 16 : gotabbr++;
2568 tgl 457 ECB : }
458 : }
459 : }
1633 tgl 460 GIC 9537 : if (gotabbr == ts->typecnt)
461 : {
2568 tgl 462 CBC 9537 : sp->charcnt = charcnt;
463 :
2170 tgl 464 ECB : /*
465 : * Ignore any trailing, no-op transitions generated by zic as
466 : * they don't help here and can run afoul of bugs in zic 2016j
467 : * or earlier.
468 : */
2170 tgl 469 GIC 9537 : while (1 < sp->timecnt
470 9537 : && (sp->types[sp->timecnt - 1]
2170 tgl 471 CBC 8572 : == sp->types[sp->timecnt - 2]))
2170 tgl 472 LBC 0 : sp->timecnt--;
2170 tgl 473 ECB :
2568 tgl 474 GBC 2853749 : for (i = 0; i < ts->timecnt; i++)
1633 tgl 475 GIC 2850217 : if (sp->timecnt == 0
1026 tgl 476 CBC 5700434 : || (sp->ats[sp->timecnt - 1]
477 2850217 : < ts->ats[i] + leapcorr(sp, ts->ats[i])))
2568 tgl 478 ECB : break;
2568 tgl 479 CBC 9537 : while (i < ts->timecnt
2568 tgl 480 GIC 9175325 : && sp->timecnt < TZ_MAX_TIMES)
2568 tgl 481 ECB : {
1026 tgl 482 CBC 9165788 : sp->ats[sp->timecnt]
1026 tgl 483 GIC 9165788 : = ts->ats[i] + leapcorr(sp, ts->ats[i]);
2568 tgl 484 CBC 9165788 : sp->types[sp->timecnt] = (sp->typecnt
485 9165788 : + ts->types[i]);
486 9165788 : sp->timecnt++;
487 9165788 : i++;
2568 tgl 488 ECB : }
1633 tgl 489 CBC 25079 : for (i = 0; i < ts->typecnt; i++)
1633 tgl 490 GIC 15542 : sp->ttis[sp->typecnt++] = ts->ttis[i];
5531 tgl 491 ECB : }
492 : }
493 : }
1633 tgl 494 GIC 9537 : if (sp->typecnt == 0)
1633 tgl 495 UIC 0 : return EINVAL;
4777 tgl 496 CBC 9537 : if (sp->timecnt > 1)
4777 tgl 497 EUB : {
4777 tgl 498 CBC 9823718 : for (i = 1; i < sp->timecnt; ++i)
4777 tgl 499 GIC 13979070 : if (typesequiv(sp, sp->types[i], sp->types[0]) &&
4777 tgl 500 CBC 4163924 : differ_by_repeat(sp->ats[i], sp->ats[0]))
4777 tgl 501 ECB : {
2568 tgl 502 LBC 0 : sp->goback = true;
4777 tgl 503 UIC 0 : break;
4777 tgl 504 EUB : }
4777 tgl 505 GBC 4889216 : for (i = sp->timecnt - 2; i >= 0; --i)
4777 tgl 506 GIC 4886649 : if (typesequiv(sp, sp->types[sp->timecnt - 1],
4777 tgl 507 CBC 7313478 : sp->types[i]) &&
508 2426829 : differ_by_repeat(sp->ats[sp->timecnt - 1],
4777 tgl 509 ECB : sp->ats[i]))
510 : {
2568 tgl 511 GIC 6005 : sp->goahead = true;
512 6005 : break;
2568 tgl 513 ECB : }
514 : }
515 :
516 : /*
517 : * Infer sp->defaulttype from the data. Although this default type is
518 : * always zero for data from recent tzdb releases, things are trickier for
519 : * data from tzdb 2018e or earlier.
520 : *
521 : * The first set of heuristics work around bugs in 32-bit data generated
522 : * by tzdb 2013c or earlier. The workaround is for zones like
523 : * Australia/Macquarie where timestamps before the first transition have a
524 : * time type that is not the earliest standard-time type. See:
525 : * https://mm.icann.org/pipermail/tz/2013-May/019368.html
526 : */
527 :
528 : /*
529 : * If type 0 is unused in transitions, it's the type to use for early
530 : * times.
531 : */
2568 tgl 532 GIC 4582513 : for (i = 0; i < sp->timecnt; ++i)
533 4576324 : if (sp->types[i] == 0)
2568 tgl 534 CBC 3348 : break;
535 9537 : i = i < sp->timecnt ? -1 : 0;
2568 tgl 536 ECB :
537 : /*
538 : * Absent the above, if there are transition times and the first
539 : * transition is to a daylight time find the standard type less than and
540 : * closest to the type of the first transition.
541 : */
2568 tgl 542 GIC 9537 : if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
543 : {
2568 tgl 544 CBC 3233 : i = sp->types[0];
2568 tgl 545 GIC 3233 : while (--i >= 0)
2568 tgl 546 CBC 3233 : if (!sp->ttis[i].tt_isdst)
547 3233 : break;
2568 tgl 548 ECB : }
549 :
550 : /*
551 : * The next heuristics are for data generated by tzdb 2018e or earlier,
552 : * for zones like EST5EDT where the first transition is to DST.
553 : */
554 :
555 : /*
556 : * If no result yet, find the first standard type. If there is none, punt
557 : * to type zero.
558 : */
2568 tgl 559 GIC 9537 : if (i < 0)
560 : {
2568 tgl 561 CBC 115 : i = 0;
2568 tgl 562 GIC 115 : while (sp->ttis[i].tt_isdst)
2568 tgl 563 LBC 0 : if (++i >= sp->typecnt)
2568 tgl 564 ECB : {
2568 tgl 565 UBC 0 : i = 0;
4777 tgl 566 UIC 0 : break;
4777 tgl 567 EUB : }
568 : }
569 :
570 : /*
571 : * A simple 'sp->defaulttype = 0;' would suffice here if we didn't have to
572 : * worry about 2018e-or-earlier data. Even simpler would be to remove the
573 : * defaulttype member and just use 0 in its place.
574 : */
2568 tgl 575 GIC 9537 : sp->defaulttype = i;
576 :
6918 bruce 577 CBC 9537 : return 0;
578 : }
6918 bruce 579 ECB :
580 : /* Load tz data from the file named NAME into *SP. Read extended
581 : * format if DOEXTEND. Return 0 on success, an errno value on failure.
582 : * PG: If "canonname" is not NULL, then on success the canonical spelling of
583 : * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
584 : */
585 : int
2118 tgl 586 GIC 9742 : tzload(const char *name, char *canonname, struct state *sp, bool doextend)
587 : {
2467 tgl 588 CBC 9742 : union local_storage *lsp = malloc(sizeof *lsp);
589 :
590 9742 : if (!lsp)
2467 tgl 591 UIC 0 : return errno;
2467 tgl 592 ECB : else
2467 tgl 593 EUB : {
2467 tgl 594 GIC 9742 : int err = tzloadbody(name, canonname, sp, doextend, lsp);
595 :
2467 tgl 596 CBC 9742 : free(lsp);
2467 tgl 597 GIC 9742 : return err;
2467 tgl 598 ECB : }
2568 599 : }
600 :
601 : static bool
2118 tgl 602 GIC 14701795 : typesequiv(const struct state *sp, int a, int b)
603 : {
2568 tgl 604 ECB : bool result;
605 :
5531 tgl 606 GIC 14701795 : if (sp == NULL ||
607 14701795 : a < 0 || a >= sp->typecnt ||
5531 tgl 608 CBC 14701795 : b < 0 || b >= sp->typecnt)
2568 tgl 609 LBC 0 : result = false;
5531 tgl 610 ECB : else
5531 tgl 611 EUB : {
5531 tgl 612 GIC 14701795 : const struct ttinfo *ap = &sp->ttis[a];
613 14701795 : const struct ttinfo *bp = &sp->ttis[b];
5531 tgl 614 ECB :
1362 tgl 615 CBC 14701795 : result = (ap->tt_utoff == bp->tt_utoff
1362 tgl 616 GIC 6650220 : && ap->tt_isdst == bp->tt_isdst
1362 tgl 617 CBC 6610507 : && ap->tt_ttisstd == bp->tt_ttisstd
618 6610507 : && ap->tt_ttisut == bp->tt_ttisut
619 21352015 : && (strcmp(&sp->chars[ap->tt_desigidx],
620 6610507 : &sp->chars[bp->tt_desigidx])
1362 tgl 621 ECB : == 0));
5531 622 : }
5531 tgl 623 GIC 14701795 : return result;
624 : }
5531 tgl 625 ECB :
626 : static const int mon_lengths[2][MONSPERYEAR] = {
627 : {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
628 : {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
629 : };
630 :
631 : static const int year_lengths[2] = {
632 : DAYSPERNYEAR, DAYSPERLYEAR
633 : };
634 :
635 : /*
636 : * Given a pointer into a timezone string, scan until a character that is not
637 : * a valid character in a time zone abbreviation is found.
638 : * Return a pointer to that character.
639 : */
640 :
641 : static const char *
6502 neilc 642 GIC 13626 : getzname(const char *strp)
643 : {
6385 bruce 644 ECB : char c;
645 :
6918 bruce 646 GIC 55909 : while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
647 : c != '+')
6897 bruce 648 CBC 42283 : ++strp;
6918 bruce 649 GIC 13626 : return strp;
6918 bruce 650 ECB : }
651 :
652 : /*
653 : * Given a pointer into an extended timezone string, scan until the ending
654 : * delimiter of the time zone abbreviation is located.
655 : * Return a pointer to the delimiter.
656 : *
657 : * As with getzname above, the legal character set is actually quite
658 : * restricted, with other characters producing undefined results.
659 : * We don't do any checking here; checking is done later in common-case code.
660 : */
661 :
662 : static const char *
1633 tgl 663 GIC 2124 : getqzname(const char *strp, const int delim)
664 : {
5050 bruce 665 ECB : int c;
666 :
5531 tgl 667 GIC 8807 : while ((c = *strp) != '\0' && c != delim)
668 6683 : ++strp;
5531 tgl 669 CBC 2124 : return strp;
5531 tgl 670 ECB : }
671 :
672 : /*
673 : * Given a pointer into a timezone string, extract a number from that string.
674 : * Check that the number is within a specified range; if it is not, return
675 : * NULL.
676 : * Otherwise, return a pointer to the first character not part of the number.
677 : */
678 :
679 : static const char *
1633 tgl 680 GIC 47224 : getnum(const char *strp, int *const nump, const int min, const int max)
681 : {
6385 bruce 682 ECB : char c;
683 : int num;
684 :
6918 bruce 685 GIC 47224 : if (strp == NULL || !is_digit(c = *strp))
6918 bruce 686 UIC 0 : return NULL;
6918 bruce 687 CBC 47224 : num = 0;
6897 bruce 688 EUB : do
6897 bruce 689 ECB : {
6918 bruce 690 GIC 54345 : num = num * 10 + (c - '0');
691 54345 : if (num > max)
6897 bruce 692 LBC 0 : return NULL; /* illegal value */
6918 bruce 693 CBC 54345 : c = *++strp;
6918 bruce 694 GBC 54345 : } while (is_digit(c));
6918 bruce 695 CBC 47224 : if (num < min)
6897 bruce 696 LBC 0 : return NULL; /* illegal value */
6918 bruce 697 CBC 47224 : *nump = num;
6918 bruce 698 GBC 47224 : return strp;
6918 bruce 699 ECB : }
700 :
701 : /*
702 : * Given a pointer into a timezone string, extract a number of seconds,
703 : * in hh[:mm[:ss]] form, from the string.
704 : * If any error occurs, return NULL.
705 : * Otherwise, return a pointer to the first character not part of the number
706 : * of seconds.
707 : */
708 :
709 : static const char *
1633 tgl 710 GIC 10890 : getsecs(const char *strp, int32 *const secsp)
711 : {
6897 bruce 712 ECB : int num;
713 :
714 : /*
715 : * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
716 : * "M10.4.6/26", which does not conform to Posix, but which specifies the
717 : * equivalent of "02:00 on the first Sunday on or after 23 Oct".
718 : */
6918 bruce 719 GIC 10890 : strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
720 10890 : if (strp == NULL)
6918 bruce 721 LBC 0 : return NULL;
2568 tgl 722 CBC 10890 : *secsp = num * (int32) SECSPERHOUR;
6897 bruce 723 GBC 10890 : if (*strp == ':')
6897 bruce 724 ECB : {
6918 bruce 725 CBC 286 : ++strp;
6918 bruce 726 GIC 286 : strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
6918 bruce 727 CBC 286 : if (strp == NULL)
6918 bruce 728 LBC 0 : return NULL;
6918 bruce 729 CBC 286 : *secsp += num * SECSPERMIN;
6897 bruce 730 GBC 286 : if (*strp == ':')
6897 bruce 731 ECB : {
6918 bruce 732 LBC 0 : ++strp;
733 : /* 'SECSPERMIN' allows for leap seconds. */
6918 bruce 734 UBC 0 : strp = getnum(strp, &num, 0, SECSPERMIN);
6918 bruce 735 UIC 0 : if (strp == NULL)
6918 bruce 736 UBC 0 : return NULL;
737 0 : *secsp += num;
6918 bruce 738 EUB : }
739 : }
6918 bruce 740 GIC 10890 : return strp;
741 : }
6918 bruce 742 ECB :
743 : /*
744 : * Given a pointer into a timezone string, extract an offset, in
745 : * [+-]hh[:mm[:ss]] form, from the string.
746 : * If any error occurs, return NULL.
747 : * Otherwise, return a pointer to the first character not part of the time.
748 : */
749 :
750 : static const char *
1633 tgl 751 GIC 10890 : getoffset(const char *strp, int32 *const offsetp)
752 : {
2568 tgl 753 CBC 10890 : bool neg = false;
754 :
6897 bruce 755 10890 : if (*strp == '-')
756 : {
2568 tgl 757 2670 : neg = true;
6918 bruce 758 GIC 2670 : ++strp;
6897 bruce 759 ECB : }
6897 bruce 760 CBC 8220 : else if (*strp == '+')
6918 bruce 761 GIC 64 : ++strp;
6918 bruce 762 CBC 10890 : strp = getsecs(strp, offsetp);
763 10890 : if (strp == NULL)
6897 bruce 764 LBC 0 : return NULL; /* illegal time */
6918 bruce 765 CBC 10890 : if (neg)
6918 bruce 766 GBC 2670 : *offsetp = -*offsetp;
6918 bruce 767 CBC 10890 : return strp;
6918 bruce 768 ECB : }
769 :
770 : /*
771 : * Given a pointer into a timezone string, extract a rule in the form
772 : * date[/time]. See POSIX section 8 for the format of "date" and "time".
773 : * If a valid rule is not found, return NULL.
774 : * Otherwise, return a pointer to the first character not part of the rule.
775 : */
776 :
777 : static const char *
1633 tgl 778 GIC 12016 : getrule(const char *strp, struct rule *const rulep)
779 : {
6897 bruce 780 CBC 12016 : if (*strp == 'J')
781 : {
6918 bruce 782 ECB : /*
783 : * Julian day.
784 : */
6918 bruce 785 UIC 0 : rulep->r_type = JULIAN_DAY;
786 0 : ++strp;
6918 bruce 787 UBC 0 : strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
6897 bruce 788 EUB : }
6897 bruce 789 GBC 12016 : else if (*strp == 'M')
790 : {
6918 bruce 791 ECB : /*
792 : * Month, week, day.
793 : */
6918 bruce 794 GIC 12016 : rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
795 12016 : ++strp;
6918 bruce 796 CBC 12016 : strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
797 12016 : if (strp == NULL)
6918 bruce 798 LBC 0 : return NULL;
6918 bruce 799 CBC 12016 : if (*strp++ != '.')
6918 bruce 800 UBC 0 : return NULL;
6918 bruce 801 CBC 12016 : strp = getnum(strp, &rulep->r_week, 1, 5);
6918 bruce 802 GBC 12016 : if (strp == NULL)
6918 bruce 803 LBC 0 : return NULL;
6918 bruce 804 CBC 12016 : if (*strp++ != '.')
6918 bruce 805 UBC 0 : return NULL;
6918 bruce 806 CBC 12016 : strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
6897 bruce 807 EUB : }
6897 bruce 808 LBC 0 : else if (is_digit(*strp))
809 : {
6918 bruce 810 EUB : /*
811 : * Day of year.
812 : */
6918 bruce 813 UIC 0 : rulep->r_type = DAY_OF_YEAR;
814 0 : strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
6897 bruce 815 EUB : }
816 : else
6897 bruce 817 UIC 0 : return NULL; /* invalid format */
6918 bruce 818 GIC 12016 : if (strp == NULL)
6918 bruce 819 UBC 0 : return NULL;
6897 bruce 820 CBC 12016 : if (*strp == '/')
6897 bruce 821 EUB : {
6918 bruce 822 ECB : /*
823 : * Time specified.
824 : */
6918 bruce 825 GIC 1153 : ++strp;
2568 tgl 826 1153 : strp = getoffset(strp, &rulep->r_time);
6897 bruce 827 ECB : }
828 : else
2118 tgl 829 GIC 10863 : rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
6918 bruce 830 12016 : return strp;
6918 bruce 831 ECB : }
832 :
833 : /*
834 : * Given a year, a rule, and the offset from UT at the time that rule takes
835 : * effect, calculate the year-relative time that rule takes effect.
836 : */
837 :
838 : static int32
1633 tgl 839 GIC 12028016 : transtime(const int year, const struct rule *const rulep,
840 : const int32 offset)
6918 bruce 841 ECB : {
842 : bool leapyear;
843 : int32 value;
844 : int i;
845 : int d,
846 : m1,
847 : yy0,
848 : yy1,
849 : yy2,
850 : dow;
851 :
2568 tgl 852 GIC 12028016 : INITIALIZE(value);
6918 bruce 853 12028016 : leapyear = isleap(year);
6897 bruce 854 CBC 12028016 : switch (rulep->r_type)
6897 bruce 855 ECB : {
6918 856 :
6897 bruce 857 UIC 0 : case JULIAN_DAY:
858 :
6897 bruce 859 EUB : /*
860 : * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
861 : * years. In non-leap years, or if the day number is 59 or less,
862 : * just add SECSPERDAY times the day number-1 to the time of
863 : * January 1, midnight, to get the day.
864 : */
2568 tgl 865 UIC 0 : value = (rulep->r_day - 1) * SECSPERDAY;
6897 bruce 866 0 : if (leapyear && rulep->r_day >= 60)
6897 bruce 867 UBC 0 : value += SECSPERDAY;
868 0 : break;
6918 bruce 869 EUB :
6897 bruce 870 UBC 0 : case DAY_OF_YEAR:
871 :
6897 bruce 872 EUB : /*
873 : * n - day of year. Just add SECSPERDAY times the day number to
874 : * the time of January 1, midnight, to get the day.
875 : */
2568 tgl 876 UIC 0 : value = rulep->r_day * SECSPERDAY;
6897 bruce 877 0 : break;
6897 bruce 878 EUB :
6897 bruce 879 GBC 12028016 : case MONTH_NTH_DAY_OF_WEEK:
880 :
6897 bruce 881 ECB : /*
882 : * Mm.n.d - nth "dth day" of month m.
883 : */
884 :
885 : /*
886 : * Use Zeller's Congruence to get day-of-week of first day of
887 : * month.
888 : */
6897 bruce 889 GIC 12028016 : m1 = (rulep->r_mon + 9) % 12 + 1;
890 12028016 : yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
6897 bruce 891 CBC 12028016 : yy1 = yy0 / 100;
892 12028016 : yy2 = yy0 % 100;
893 12028016 : dow = ((26 * m1 - 2) / 10 +
894 12028016 : 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
895 12028016 : if (dow < 0)
896 2258631 : dow += DAYSPERWEEK;
6897 bruce 897 ECB :
898 : /*
899 : * "dow" is the day-of-week of the first day of the month. Get the
900 : * day-of-month (zero-origin) of the first "dow" day of the month.
901 : */
6897 bruce 902 GIC 12028016 : d = rulep->r_day - dow;
903 12028016 : if (d < 0)
6897 bruce 904 CBC 10181869 : d += DAYSPERWEEK;
905 21821864 : for (i = 1; i < rulep->r_week; ++i)
6897 bruce 906 ECB : {
6897 bruce 907 CBC 10549539 : if (d + DAYSPERWEEK >=
2568 tgl 908 GIC 10549539 : mon_lengths[(int) leapyear][rulep->r_mon - 1])
6918 bruce 909 CBC 755691 : break;
6897 910 9793848 : d += DAYSPERWEEK;
6897 bruce 911 ECB : }
6918 912 :
913 : /*
914 : * "d" is the day-of-month (zero-origin) of the day we want.
915 : */
2568 tgl 916 GIC 12028016 : value = d * SECSPERDAY;
917 83442359 : for (i = 0; i < rulep->r_mon - 1; ++i)
2568 tgl 918 CBC 71414343 : value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
6897 bruce 919 12028016 : break;
6918 bruce 920 ECB : }
921 :
922 : /*
923 : * "value" is the year-relative time of 00:00:00 UT on the day in
924 : * question. To get the year-relative time of the specified local time on
925 : * that day, add the transition time and the current offset from UT.
926 : */
6918 bruce 927 GIC 12028016 : return value + rulep->r_time + offset;
928 : }
6918 bruce 929 ECB :
930 : /*
931 : * Given a POSIX section 8-style TZ string, fill in the rule tables as
932 : * appropriate.
933 : * Returns true on success, false on failure.
934 : */
935 : bool
2118 tgl 936 GIC 11599 : tzparse(const char *name, struct state *sp, bool lastditch)
937 : {
6897 bruce 938 ECB : const char *stdname;
6897 bruce 939 GIC 11599 : const char *dstname = NULL;
940 : size_t stdlen;
6897 bruce 941 ECB : size_t dstlen;
942 : size_t charcnt;
943 : int32 stdoffset;
944 : int32 dstoffset;
945 : char *cp;
946 : bool load_ok;
947 :
6918 bruce 948 GIC 11599 : stdname = name;
6897 949 11599 : if (lastditch)
6897 bruce 950 ECB : {
1635 tgl 951 : /* Unlike IANA, don't assume name is exactly "GMT" */
6918 bruce 952 GIC 1857 : stdlen = strlen(name); /* length of standard zone name */
953 1857 : name += stdlen;
6918 bruce 954 CBC 1857 : stdoffset = 0;
6897 bruce 955 ECB : }
956 : else
957 : {
5531 tgl 958 GIC 9742 : if (*name == '<')
959 : {
5531 tgl 960 CBC 2000 : name++;
5531 tgl 961 GIC 2000 : stdname = name;
5531 tgl 962 CBC 2000 : name = getqzname(name, '>');
963 2000 : if (*name != '>')
2568 tgl 964 LBC 0 : return false;
5531 tgl 965 CBC 2000 : stdlen = name - stdname;
5531 tgl 966 GBC 2000 : name++;
5531 tgl 967 ECB : }
968 : else
969 : {
5531 tgl 970 GIC 7742 : name = getzname(name);
971 7742 : stdlen = name - stdname;
5531 tgl 972 ECB : }
2568 tgl 973 CBC 9742 : if (*name == '\0') /* we allow empty STD abbrev, unlike IANA */
2568 tgl 974 GIC 48 : return false;
6918 bruce 975 CBC 9694 : name = getoffset(name, &stdoffset);
976 9694 : if (name == NULL)
2568 tgl 977 LBC 0 : return false;
6918 bruce 978 ECB : }
1635 tgl 979 GBC 11551 : charcnt = stdlen + 1;
1635 tgl 980 GIC 11551 : if (sizeof sp->chars < charcnt)
1635 tgl 981 LBC 0 : return false;
1635 tgl 982 ECB :
1635 tgl 983 EUB : /*
984 : * The IANA code always tries to tzload(TZDEFRULES) here. We do not want
985 : * to do that; it would be bad news in the lastditch case, where we can't
986 : * assume pg_open_tzfile() is sane yet. Moreover, if we did load it and
987 : * it contains leap-second-dependent info, that would cause problems too.
988 : * Finally, IANA has deprecated the TZDEFRULES feature, so it presumably
989 : * will die at some point. Desupporting it now seems like good
990 : * future-proofing.
991 : */
1014 tgl 992 GIC 11551 : load_ok = false;
1635 993 11551 : sp->goback = sp->goahead = false; /* simulate failed tzload() */
1635 tgl 994 CBC 11551 : sp->leapcnt = 0; /* intentionally assume no leap seconds */
1635 tgl 995 ECB :
6897 bruce 996 CBC 11551 : if (*name != '\0')
997 : {
5531 tgl 998 6008 : if (*name == '<')
999 : {
1000 124 : dstname = ++name;
5531 tgl 1001 GIC 124 : name = getqzname(name, '>');
5531 tgl 1002 CBC 124 : if (*name != '>')
2568 tgl 1003 LBC 0 : return false;
5531 tgl 1004 CBC 124 : dstlen = name - dstname;
5531 tgl 1005 GBC 124 : name++;
5531 tgl 1006 ECB : }
1007 : else
1008 : {
5531 tgl 1009 GIC 5884 : dstname = name;
1010 5884 : name = getzname(name);
1633 tgl 1011 CBC 5884 : dstlen = name - dstname; /* length of DST abbr. */
5531 tgl 1012 ECB : }
2568 tgl 1013 CBC 6008 : if (!dstlen)
2568 tgl 1014 UIC 0 : return false;
2568 tgl 1015 CBC 6008 : charcnt += dstlen + 1;
2568 tgl 1016 GBC 6008 : if (sizeof sp->chars < charcnt)
2568 tgl 1017 LBC 0 : return false;
6897 bruce 1018 CBC 6008 : if (*name != '\0' && *name != ',' && *name != ';')
6897 bruce 1019 EUB : {
6918 bruce 1020 CBC 43 : name = getoffset(name, &dstoffset);
6918 bruce 1021 GIC 43 : if (name == NULL)
2568 tgl 1022 LBC 0 : return false;
6897 bruce 1023 ECB : }
6897 bruce 1024 EUB : else
6897 bruce 1025 GIC 5965 : dstoffset = stdoffset - SECSPERHOUR;
1014 tgl 1026 6008 : if (*name == '\0' && !load_ok)
1014 tgl 1027 LBC 0 : name = TZDEFRULESTRING;
6897 bruce 1028 CBC 6008 : if (*name == ',' || *name == ';')
6897 bruce 1029 GBC 6008 : {
6897 bruce 1030 ECB : struct rule start;
1031 : struct rule end;
1032 : int year;
1033 : int yearlim;
1034 : int timecnt;
1035 : pg_time_t janfirst;
2170 tgl 1036 GIC 6008 : int32 janoffset = 0;
1037 : int yearbeg;
6918 bruce 1038 ECB :
6918 bruce 1039 GIC 6008 : ++name;
1040 6008 : if ((name = getrule(name, &start)) == NULL)
2568 tgl 1041 LBC 0 : return false;
6918 bruce 1042 CBC 6008 : if (*name++ != ',')
2568 tgl 1043 UBC 0 : return false;
6918 bruce 1044 CBC 6008 : if ((name = getrule(name, &end)) == NULL)
2568 tgl 1045 UBC 0 : return false;
6918 bruce 1046 CBC 6008 : if (*name != '\0')
2568 tgl 1047 UBC 0 : return false;
6918 bruce 1048 CBC 6008 : sp->typecnt = 2; /* standard time and DST */
6897 bruce 1049 EUB :
6918 bruce 1050 ECB : /*
1051 : * Two transitions per year, from EPOCH_YEAR forward.
1052 : */
1633 tgl 1053 GIC 6008 : init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1054 6008 : init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
2568 tgl 1055 CBC 6008 : sp->defaulttype = 0;
1056 6008 : timecnt = 0;
6918 bruce 1057 6008 : janfirst = 0;
2170 tgl 1058 6008 : yearbeg = EPOCH_YEAR;
2170 tgl 1059 ECB :
1060 : do
1061 : {
2170 tgl 1062 GIC 1201600 : int32 yearsecs
1063 1201600 : = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
2170 tgl 1064 ECB :
2170 tgl 1065 CBC 1201600 : yearbeg--;
2170 tgl 1066 GIC 1201600 : if (increment_overflow_time(&janfirst, -yearsecs))
2170 tgl 1067 ECB : {
2170 tgl 1068 LBC 0 : janoffset = -yearsecs;
2170 tgl 1069 UIC 0 : break;
2170 tgl 1070 EUB : }
2170 tgl 1071 GBC 1201600 : } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1072 :
2170 tgl 1073 CBC 6008 : yearlim = yearbeg + YEARSPERREPEAT + 1;
2170 tgl 1074 GIC 6014008 : for (year = yearbeg; year < yearlim; year++)
6897 bruce 1075 ECB : {
2568 tgl 1076 : int32
2568 tgl 1077 GIC 6014008 : starttime = transtime(year, &start, stdoffset),
1078 6014008 : endtime = transtime(year, &end, dstoffset);
2568 tgl 1079 ECB : int32
2568 tgl 1080 CBC 6014008 : yearsecs = (year_lengths[isleap(year)]
1081 : * SECSPERDAY);
1082 6014008 : bool reversed = endtime < starttime;
1083 :
1084 6014008 : if (reversed)
1085 : {
1086 255255 : int32 swap = starttime;
1087 :
1088 255255 : starttime = endtime;
2568 tgl 1089 GIC 255255 : endtime = swap;
6897 bruce 1090 ECB : }
2568 tgl 1091 CBC 6014008 : if (reversed
2568 tgl 1092 GIC 5758753 : || (starttime < endtime
2568 tgl 1093 CBC 5758753 : && (endtime - starttime
2568 tgl 1094 ECB : < (yearsecs
2568 tgl 1095 CBC 5758753 : + (stdoffset - dstoffset)))))
1096 : {
1097 6014008 : if (TZ_MAX_TIMES - 2 < timecnt)
2568 tgl 1098 GIC 6008 : break;
2568 tgl 1099 CBC 6008000 : sp->ats[timecnt] = janfirst;
2170 1100 6008000 : if (!increment_overflow_time
2170 tgl 1101 ECB : (&sp->ats[timecnt],
1102 : janoffset + starttime))
1633 tgl 1103 GIC 6008000 : sp->types[timecnt++] = !reversed;
2568 1104 6008000 : sp->ats[timecnt] = janfirst;
2170 tgl 1105 CBC 6008000 : if (!increment_overflow_time
2170 tgl 1106 ECB : (&sp->ats[timecnt],
1107 : janoffset + endtime))
1108 : {
1633 tgl 1109 GIC 6008000 : sp->types[timecnt++] = reversed;
2170 1110 6008000 : yearlim = year + YEARSPERREPEAT + 1;
2170 tgl 1111 ECB : }
6918 bruce 1112 : }
2170 tgl 1113 GIC 6008000 : if (increment_overflow_time
1114 : (&janfirst, janoffset + yearsecs))
5531 tgl 1115 LBC 0 : break;
2170 tgl 1116 GIC 6008000 : janoffset = 0;
6918 bruce 1117 EUB : }
2568 tgl 1118 CBC 6008 : sp->timecnt = timecnt;
2568 tgl 1119 GIC 6008 : if (!timecnt)
1633 tgl 1120 ECB : {
1633 tgl 1121 LBC 0 : sp->ttis[0] = sp->ttis[1];
2568 tgl 1122 UIC 0 : sp->typecnt = 1; /* Perpetual DST. */
1633 tgl 1123 EUB : }
2170 tgl 1124 GBC 6008 : else if (YEARSPERREPEAT < year - yearbeg)
2170 tgl 1125 GIC 6008 : sp->goback = sp->goahead = true;
6897 bruce 1126 ECB : }
1127 : else
1128 : {
1129 : int32 theirstdoffset;
1130 : int32 theirdstoffset;
1131 : int32 theiroffset;
1132 : bool isdst;
1133 : int i;
1134 : int j;
1135 :
6918 bruce 1136 UIC 0 : if (*name != '\0')
2568 tgl 1137 0 : return false;
6897 bruce 1138 EUB :
6918 1139 : /*
1140 : * Initial values of theirstdoffset and theirdstoffset.
1141 : */
6918 bruce 1142 UIC 0 : theirstdoffset = 0;
6897 1143 0 : for (i = 0; i < sp->timecnt; ++i)
6897 bruce 1144 EUB : {
6918 bruce 1145 UBC 0 : j = sp->types[i];
6897 bruce 1146 UIC 0 : if (!sp->ttis[j].tt_isdst)
6897 bruce 1147 EUB : {
6918 bruce 1148 UBC 0 : theirstdoffset =
1362 tgl 1149 UIC 0 : -sp->ttis[j].tt_utoff;
6918 bruce 1150 UBC 0 : break;
6918 bruce 1151 EUB : }
1152 : }
6918 bruce 1153 UIC 0 : theirdstoffset = 0;
6897 1154 0 : for (i = 0; i < sp->timecnt; ++i)
6897 bruce 1155 EUB : {
6918 bruce 1156 UBC 0 : j = sp->types[i];
6897 bruce 1157 UIC 0 : if (sp->ttis[j].tt_isdst)
6897 bruce 1158 EUB : {
6918 bruce 1159 UBC 0 : theirdstoffset =
1362 tgl 1160 UIC 0 : -sp->ttis[j].tt_utoff;
6918 bruce 1161 UBC 0 : break;
6918 bruce 1162 EUB : }
1163 : }
1164 :
1165 : /*
1166 : * Initially we're assumed to be in standard time.
1167 : */
2568 tgl 1168 UIC 0 : isdst = false;
6918 bruce 1169 0 : theiroffset = theirstdoffset;
6897 bruce 1170 EUB :
6918 1171 : /*
1172 : * Now juggle transition times and types tracking offsets as you
1173 : * do.
1174 : */
6897 bruce 1175 UIC 0 : for (i = 0; i < sp->timecnt; ++i)
1176 : {
6918 bruce 1177 UBC 0 : j = sp->types[i];
6918 bruce 1178 UIC 0 : sp->types[i] = sp->ttis[j].tt_isdst;
1362 tgl 1179 UBC 0 : if (sp->ttis[j].tt_ttisut)
6897 bruce 1180 EUB : {
6918 1181 : /* No adjustment to transition time */
1182 : }
1183 : else
1184 : {
1185 : /*
1186 : * If daylight saving time is in effect, and the
1187 : * transition time was not specified as standard time, add
1188 : * the daylight saving time offset to the transition time;
1189 : * otherwise, add the standard time offset to the
1190 : * transition time.
1191 : */
1192 : /*
1193 : * Transitions from DST to DDST will effectively disappear
1194 : * since POSIX provides for only one DST offset.
1195 : */
6897 bruce 1196 UIC 0 : if (isdst && !sp->ttis[j].tt_ttisstd)
1197 : {
6918 bruce 1198 UBC 0 : sp->ats[i] += dstoffset -
1199 : theirdstoffset;
6897 bruce 1200 EUB : }
1201 : else
1202 : {
6918 bruce 1203 UIC 0 : sp->ats[i] += stdoffset -
1204 : theirstdoffset;
6918 bruce 1205 EUB : }
1206 : }
1362 tgl 1207 UIC 0 : theiroffset = -sp->ttis[j].tt_utoff;
6918 bruce 1208 0 : if (sp->ttis[j].tt_isdst)
6918 bruce 1209 UBC 0 : theirdstoffset = theiroffset;
6897 bruce 1210 EUB : else
6897 bruce 1211 UBC 0 : theirstdoffset = theiroffset;
1212 : }
6897 bruce 1213 EUB :
1214 : /*
1215 : * Finally, fill in ttis.
1216 : */
2568 tgl 1217 UIC 0 : init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1218 0 : init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
6918 bruce 1219 UBC 0 : sp->typecnt = 2;
2568 tgl 1220 0 : sp->defaulttype = 0;
6918 bruce 1221 EUB : }
6897 1222 : }
1223 : else
1224 : {
6918 bruce 1225 GIC 5543 : dstlen = 0;
1226 5543 : sp->typecnt = 1; /* only standard time */
6918 bruce 1227 CBC 5543 : sp->timecnt = 0;
2568 tgl 1228 5543 : init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1229 5543 : sp->defaulttype = 0;
6918 bruce 1230 ECB : }
2568 tgl 1231 CBC 11551 : sp->charcnt = charcnt;
6918 bruce 1232 GIC 11551 : cp = sp->chars;
2568 tgl 1233 CBC 11551 : memcpy(cp, stdname, stdlen);
6918 bruce 1234 11551 : cp += stdlen;
1235 11551 : *cp++ = '\0';
6897 1236 11551 : if (dstlen != 0)
6897 bruce 1237 ECB : {
2568 tgl 1238 CBC 6008 : memcpy(cp, dstname, dstlen);
6918 bruce 1239 GIC 6008 : *(cp + dstlen) = '\0';
6918 bruce 1240 ECB : }
2568 tgl 1241 CBC 11551 : return true;
1242 : }
6918 bruce 1243 ECB :
1244 : static void
1633 tgl 1245 GIC 147 : gmtload(struct state *const sp)
1246 : {
2568 tgl 1247 CBC 147 : if (tzload(gmt, NULL, sp, true) != 0)
2568 tgl 1248 UIC 0 : tzparse(gmt, sp, true);
6918 bruce 1249 CBC 147 : }
6918 bruce 1250 EUB :
6918 bruce 1251 ECB :
1252 : /*
1253 : * The easy way to behave "as if no library function calls" localtime
1254 : * is to not call it, so we drop its guts into "localsub", which can be
1255 : * freely called. (And no, the PANS doesn't require the above behavior,
1256 : * but it *is* desirable.)
1257 : */
1258 : static struct pg_tm *
2118 tgl 1259 GIC 338779 : localsub(struct state const *sp, pg_time_t const *timep,
1260 : struct pg_tm *const tmp)
6918 bruce 1261 ECB : {
1262 : const struct ttinfo *ttisp;
1263 : int i;
1264 : struct pg_tm *result;
6884 tgl 1265 GIC 338779 : const pg_time_t t = *timep;
1266 :
2568 tgl 1267 CBC 338779 : if (sp == NULL)
2568 tgl 1268 UIC 0 : return gmtsub(timep, 0, tmp);
5531 tgl 1269 CBC 338779 : if ((sp->goback && t < sp->ats[0]) ||
5531 tgl 1270 GBC 338779 : (sp->goahead && t > sp->ats[sp->timecnt - 1]))
5531 tgl 1271 ECB : {
5531 tgl 1272 CBC 30 : pg_time_t newt = t;
1273 : pg_time_t seconds;
2568 tgl 1274 ECB : pg_time_t years;
1275 :
5531 tgl 1276 GIC 30 : if (t < sp->ats[0])
5531 tgl 1277 UIC 0 : seconds = sp->ats[0] - t;
5050 bruce 1278 ECB : else
5050 bruce 1279 GBC 30 : seconds = t - sp->ats[sp->timecnt - 1];
5531 tgl 1280 GIC 30 : --seconds;
2568 tgl 1281 CBC 30 : years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1282 30 : seconds = years * AVGSECSPERYEAR;
5531 1283 30 : if (t < sp->ats[0])
5531 tgl 1284 LBC 0 : newt += seconds;
5050 bruce 1285 ECB : else
5050 bruce 1286 GBC 30 : newt -= seconds;
5531 tgl 1287 GIC 30 : if (newt < sp->ats[0] ||
5531 tgl 1288 CBC 30 : newt > sp->ats[sp->timecnt - 1])
5050 bruce 1289 LBC 0 : return NULL; /* "cannot happen" */
2568 tgl 1290 CBC 30 : result = localsub(sp, &newt, tmp);
2568 tgl 1291 GBC 30 : if (result)
5531 tgl 1292 ECB : {
2568 1293 : int64 newy;
1294 :
2568 tgl 1295 GIC 30 : newy = result->tm_year;
5531 1296 30 : if (t < sp->ats[0])
2568 tgl 1297 LBC 0 : newy -= years;
5050 bruce 1298 ECB : else
2568 tgl 1299 GBC 30 : newy += years;
2568 tgl 1300 GIC 30 : if (!(INT_MIN <= newy && newy <= INT_MAX))
5531 tgl 1301 LBC 0 : return NULL;
2568 tgl 1302 CBC 30 : result->tm_year = newy;
5531 tgl 1303 EUB : }
5531 tgl 1304 CBC 30 : return result;
1305 : }
6897 bruce 1306 338749 : if (sp->timecnt == 0 || t < sp->ats[0])
1307 : {
2568 tgl 1308 26320 : i = sp->defaulttype;
1309 : }
6897 bruce 1310 ECB : else
1311 : {
5050 bruce 1312 GIC 312429 : int lo = 1;
1313 312429 : int hi = sp->timecnt;
5050 bruce 1314 ECB :
5531 tgl 1315 CBC 3683489 : while (lo < hi)
1316 : {
5050 bruce 1317 3371060 : int mid = (lo + hi) >> 1;
1318 :
5531 tgl 1319 3371060 : if (t < sp->ats[mid])
5531 tgl 1320 GIC 2603905 : hi = mid;
5050 bruce 1321 ECB : else
5050 bruce 1322 CBC 767155 : lo = mid + 1;
1323 : }
5531 tgl 1324 312429 : i = (int) sp->types[lo - 1];
1325 : }
6918 bruce 1326 338749 : ttisp = &sp->ttis[i];
1327 :
1633 tgl 1328 ECB : /*
1329 : * To get (wrong) behavior that's compatible with System V Release 2.0
1330 : * you'd replace the statement below with t += ttisp->tt_utoff;
1331 : * timesub(&t, 0L, sp, tmp);
1332 : */
1362 tgl 1333 GIC 338749 : result = timesub(&t, ttisp->tt_utoff, sp, tmp);
2568 1334 338749 : if (result)
2568 tgl 1335 ECB : {
2568 tgl 1336 CBC 338749 : result->tm_isdst = ttisp->tt_isdst;
1362 tgl 1337 GIC 338749 : result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_desigidx]);
2568 tgl 1338 ECB : }
5531 tgl 1339 CBC 338749 : return result;
1340 : }
6918 bruce 1341 ECB :
1342 :
1343 : struct pg_tm *
6564 bruce 1344 GIC 338749 : pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1345 : {
2568 tgl 1346 CBC 338749 : return localsub(&tz->state, timep, &tm);
1347 : }
6918 bruce 1348 ECB :
1349 :
1350 : /*
1351 : * gmtsub is to gmtime as localsub is to localtime.
1352 : *
1353 : * Except we have a private "struct state" for GMT, so no sp is passed in.
1354 : */
1355 :
1356 : static struct pg_tm *
1633 tgl 1357 GIC 132753 : gmtsub(pg_time_t const *timep, int32 offset,
1358 : struct pg_tm *tmp)
6918 bruce 1359 ECB : {
1360 : struct pg_tm *result;
1361 :
1362 : /* GMT timezone state data is kept here */
1363 : static struct state *gmtptr = NULL;
1364 :
1636 tgl 1365 GIC 132753 : if (gmtptr == NULL)
1366 : {
1636 tgl 1367 ECB : /* Allocate on first use */
1636 tgl 1368 GIC 147 : gmtptr = (struct state *) malloc(sizeof(struct state));
1369 147 : if (gmtptr == NULL)
1636 tgl 1370 LBC 0 : return NULL; /* errno should be set by malloc */
6897 tgl 1371 CBC 147 : gmtload(gmtptr);
6918 bruce 1372 EUB : }
1633 tgl 1373 ECB :
5531 tgl 1374 GIC 132753 : result = timesub(timep, offset, gmtptr, tmp);
1375 :
6918 bruce 1376 ECB : /*
1377 : * Could get fancy here and deliver something such as "+xx" or "-xx" if
1378 : * offset is non-zero, but this is no time for a treasure hunt.
1379 : */
6918 bruce 1380 GIC 132753 : if (offset != 0)
6897 tgl 1381 UIC 0 : tmp->tm_zone = wildabbr;
6897 bruce 1382 ECB : else
6897 tgl 1383 GBC 132753 : tmp->tm_zone = gmtptr->chars;
1384 :
5531 tgl 1385 CBC 132753 : return result;
1386 : }
6918 bruce 1387 ECB :
1388 : struct pg_tm *
6884 tgl 1389 GIC 132753 : pg_gmtime(const pg_time_t *timep)
1390 : {
2568 tgl 1391 CBC 132753 : return gmtsub(timep, 0, &tm);
1392 : }
6918 bruce 1393 ECB :
1394 : /*
1395 : * Return the number of leap years through the end of the given year
1396 : * where, to make the math easy, the answer for year zero is defined as zero.
1397 : */
1398 :
1399 : static int
2025 tgl 1400 GIC 1862208 : leaps_thru_end_of_nonneg(int y)
1401 : {
2025 tgl 1402 CBC 1862208 : return y / 4 - y / 100 + y / 400;
1403 : }
2025 tgl 1404 ECB :
1405 : static int
5531 tgl 1406 GIC 1862208 : leaps_thru_end_of(const int y)
1407 : {
2025 tgl 1408 ECB : return (y < 0
2025 tgl 1409 GIC 1152 : ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1410 1863360 : : leaps_thru_end_of_nonneg(y));
5531 tgl 1411 ECB : }
6918 bruce 1412 :
1413 : static struct pg_tm *
2568 tgl 1414 GIC 471502 : timesub(const pg_time_t *timep, int32 offset,
1415 : const struct state *sp, struct pg_tm *tmp)
6918 bruce 1416 ECB : {
1417 : const struct lsinfo *lp;
1418 : pg_time_t tdays;
1419 : int idays; /* unsigned would be so 2003 */
1420 : int64 rem;
1421 : int y;
1422 : const int *ip;
1423 : int64 corr;
1424 : bool hit;
1425 : int i;
1426 :
6918 bruce 1427 GIC 471502 : corr = 0;
2568 tgl 1428 471502 : hit = false;
2568 tgl 1429 CBC 471502 : i = (sp == NULL) ? 0 : sp->leapcnt;
6897 bruce 1430 471502 : while (--i >= 0)
6897 bruce 1431 ECB : {
6918 bruce 1432 LBC 0 : lp = &sp->lsis[i];
6897 bruce 1433 UIC 0 : if (*timep >= lp->ls_trans)
6897 bruce 1434 EUB : {
6918 bruce 1435 UBC 0 : corr = lp->ls_corr;
2025 tgl 1436 UIC 0 : hit = (*timep == lp->ls_trans
2025 tgl 1437 UBC 0 : && (i == 0 ? 0 : lp[-1].ls_corr) < corr);
6918 bruce 1438 0 : break;
6918 bruce 1439 EUB : }
1440 : }
5531 tgl 1441 GIC 471502 : y = EPOCH_YEAR;
1442 471502 : tdays = *timep / SECSPERDAY;
2568 tgl 1443 CBC 471502 : rem = *timep % SECSPERDAY;
5531 1444 931104 : while (tdays < 0 || tdays >= year_lengths[isleap(y)])
6897 bruce 1445 ECB : {
5050 1446 : int newy;
1447 : pg_time_t tdelta;
1448 : int idelta;
1449 : int leapdays;
1450 :
5531 tgl 1451 GIC 459602 : tdelta = tdays / DAYSPERLYEAR;
1058 1452 459602 : if (!((!TYPE_SIGNED(pg_time_t) || INT_MIN <= tdelta)
2568 tgl 1453 ECB : && tdelta <= INT_MAX))
2568 tgl 1454 LBC 0 : goto out_of_range;
5531 tgl 1455 GIC 459602 : idelta = tdelta;
5531 tgl 1456 GBC 459602 : if (idelta == 0)
5531 tgl 1457 CBC 20792 : idelta = (tdays < 0) ? -1 : 1;
1458 459602 : newy = y;
1459 459602 : if (increment_overflow(&newy, idelta))
2568 tgl 1460 LBC 0 : goto out_of_range;
5531 tgl 1461 CBC 459602 : leapdays = leaps_thru_end_of(newy - 1) -
5531 tgl 1462 GBC 459602 : leaps_thru_end_of(y - 1);
5531 tgl 1463 CBC 459602 : tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1464 459602 : tdays -= leapdays;
1465 459602 : y = newy;
5531 tgl 1466 ECB : }
5050 bruce 1467 :
1468 : /*
1469 : * Given the range, we can now fearlessly cast...
1470 : */
5531 tgl 1471 GIC 471502 : idays = tdays;
1472 471502 : rem += offset - corr;
6897 bruce 1473 CBC 502584 : while (rem < 0)
6897 bruce 1474 ECB : {
6918 bruce 1475 CBC 31082 : rem += SECSPERDAY;
5531 tgl 1476 GIC 31082 : --idays;
6918 bruce 1477 ECB : }
6897 bruce 1478 CBC 474356 : while (rem >= SECSPERDAY)
1479 : {
6918 1480 2854 : rem -= SECSPERDAY;
5531 tgl 1481 GIC 2854 : ++idays;
6918 bruce 1482 ECB : }
5531 tgl 1483 CBC 482564 : while (idays < 0)
1484 : {
1485 11062 : if (increment_overflow(&y, -1))
2568 tgl 1486 UIC 0 : goto out_of_range;
5531 tgl 1487 CBC 11062 : idays += year_lengths[isleap(y)];
5531 tgl 1488 EUB : }
5531 tgl 1489 CBC 471508 : while (idays >= year_lengths[isleap(y)])
1490 : {
1491 6 : idays -= year_lengths[isleap(y)];
5531 tgl 1492 GIC 6 : if (increment_overflow(&y, 1))
2568 tgl 1493 LBC 0 : goto out_of_range;
5531 tgl 1494 ECB : }
5531 tgl 1495 GBC 471502 : tmp->tm_year = y;
5531 tgl 1496 GIC 471502 : if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
2568 tgl 1497 LBC 0 : goto out_of_range;
5531 tgl 1498 CBC 471502 : tmp->tm_yday = idays;
5050 bruce 1499 EUB :
6918 bruce 1500 ECB : /*
1501 : * The "extra" mods below avoid overflow problems.
1502 : */
5531 tgl 1503 GIC 471502 : tmp->tm_wday = EPOCH_WDAY +
1504 471502 : ((y - EPOCH_YEAR) % DAYSPERWEEK) *
5531 tgl 1505 CBC 471502 : (DAYSPERNYEAR % DAYSPERWEEK) +
1506 471502 : leaps_thru_end_of(y - 1) -
1507 471502 : leaps_thru_end_of(EPOCH_YEAR - 1) +
5531 tgl 1508 ECB : idays;
5531 tgl 1509 CBC 471502 : tmp->tm_wday %= DAYSPERWEEK;
6918 bruce 1510 GIC 471502 : if (tmp->tm_wday < 0)
6918 bruce 1511 CBC 830 : tmp->tm_wday += DAYSPERWEEK;
5531 tgl 1512 471502 : tmp->tm_hour = (int) (rem / SECSPERHOUR);
1513 471502 : rem %= SECSPERHOUR;
1514 471502 : tmp->tm_min = (int) (rem / SECSPERMIN);
6797 bruce 1515 ECB :
6884 tgl 1516 : /*
1517 : * A positive leap second requires a special representation. This uses
1518 : * "... ??:59:60" et seq.
1519 : */
5531 tgl 1520 GIC 471502 : tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1521 471502 : ip = mon_lengths[isleap(y)];
5531 tgl 1522 CBC 1856122 : for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1523 1384620 : idays -= ip[tmp->tm_mon];
1524 471502 : tmp->tm_mday = (int) (idays + 1);
6918 bruce 1525 471502 : tmp->tm_isdst = 0;
6897 tgl 1526 471502 : tmp->tm_gmtoff = offset;
5531 1527 471502 : return tmp;
2568 tgl 1528 ECB :
2568 tgl 1529 LBC 0 : out_of_range:
2568 tgl 1530 UIC 0 : errno = EOVERFLOW;
2568 tgl 1531 UBC 0 : return NULL;
5531 tgl 1532 EUB : }
1533 :
1534 : /*
1535 : * Normalize logic courtesy Paul Eggert.
1536 : */
1537 :
1538 : static bool
2568 tgl 1539 GIC 942172 : increment_overflow(int *ip, int j)
1540 : {
2568 tgl 1541 CBC 942172 : int const i = *ip;
1542 :
2568 tgl 1543 ECB : /*----------
1544 : * If i >= 0 there can only be overflow if i + j > INT_MAX
1545 : * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1546 : * If i < 0 there can only be overflow if i + j < INT_MIN
1547 : * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1548 : *----------
1549 : */
2568 tgl 1550 GIC 942172 : if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
2568 tgl 1551 UIC 0 : return true;
2568 tgl 1552 CBC 942172 : *ip += j;
2568 tgl 1553 GBC 942172 : return false;
2568 tgl 1554 ECB : }
5531 1555 :
1556 : static bool
2568 tgl 1557 GIC 19225600 : increment_overflow_time(pg_time_t *tp, int32 j)
1558 : {
2568 tgl 1559 ECB : /*----------
1560 : * This is like
1561 : * 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
1562 : * except that it does the right thing even if *tp + j would overflow.
1563 : *----------
1564 : */
2568 tgl 1565 GIC 38451200 : if (!(j < 0
2025 1566 1201600 : ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
2025 tgl 1567 CBC 18024000 : : *tp <= TIME_T_MAX - j))
2568 tgl 1568 LBC 0 : return true;
2568 tgl 1569 CBC 19225600 : *tp += j;
2568 tgl 1570 GBC 19225600 : return false;
6918 bruce 1571 ECB : }
1572 :
1573 : static int64
1026 tgl 1574 GIC 12016005 : leapcorr(struct state const *sp, pg_time_t t)
1575 : {
1026 tgl 1576 ECB : struct lsinfo const *lp;
1577 : int i;
1578 :
1026 tgl 1579 GIC 12016005 : i = sp->leapcnt;
1580 12016005 : while (--i >= 0)
1026 tgl 1581 ECB : {
1026 tgl 1582 LBC 0 : lp = &sp->lsis[i];
1026 tgl 1583 UIC 0 : if (t >= lp->ls_trans)
1026 tgl 1584 UBC 0 : return lp->ls_corr;
1026 tgl 1585 EUB : }
1026 tgl 1586 GBC 12016005 : return 0;
1587 : }
1026 tgl 1588 ECB :
1589 : /*
1590 : * Find the next DST transition time in the given zone after the given time
1591 : *
1592 : * *timep and *tz are input arguments, the other parameters are output values.
1593 : *
1594 : * When the function result is 1, *boundary is set to the pg_time_t
1595 : * representation of the next DST transition time after *timep,
1596 : * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1597 : * state prevailing just before that boundary (in particular, the state
1598 : * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1599 : * the state prevailing just after that boundary.
1600 : *
1601 : * When the function result is 0, there is no known DST transition
1602 : * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1603 : * offset and isdst state prevailing at *timep. (This would occur in
1604 : * DST-less time zones, or if a zone has permanently ceased using DST.)
1605 : *
1606 : * A function result of -1 indicates failure (this case does not actually
1607 : * occur in our current implementation).
1608 : */
1609 : int
6733 tgl 1610 GIC 26151 : pg_next_dst_boundary(const pg_time_t *timep,
1611 : long int *before_gmtoff,
6733 tgl 1612 ECB : int *before_isdst,
1613 : pg_time_t *boundary,
1614 : long int *after_gmtoff,
1615 : int *after_isdst,
1616 : const pg_tz *tz)
1617 : {
1618 : const struct state *sp;
1619 : const struct ttinfo *ttisp;
1620 : int i;
1621 : int j;
6733 tgl 1622 GIC 26151 : const pg_time_t t = *timep;
1623 :
6564 bruce 1624 CBC 26151 : sp = &tz->state;
6733 tgl 1625 GIC 26151 : if (sp->timecnt == 0)
6733 tgl 1626 ECB : {
1627 : /* non-DST zone, use lowest-numbered standard type */
6733 tgl 1628 GIC 896 : i = 0;
1629 896 : while (sp->ttis[i].tt_isdst)
6733 tgl 1630 LBC 0 : if (++i >= sp->typecnt)
6733 tgl 1631 ECB : {
6733 tgl 1632 UBC 0 : i = 0;
6733 tgl 1633 UIC 0 : break;
6733 tgl 1634 EUB : }
6733 tgl 1635 GBC 896 : ttisp = &sp->ttis[i];
1362 tgl 1636 GIC 896 : *before_gmtoff = ttisp->tt_utoff;
6733 tgl 1637 CBC 896 : *before_isdst = ttisp->tt_isdst;
1638 896 : return 0;
6733 tgl 1639 ECB : }
5531 tgl 1640 CBC 25255 : if ((sp->goback && t < sp->ats[0]) ||
5531 tgl 1641 GIC 25255 : (sp->goahead && t > sp->ats[sp->timecnt - 1]))
5531 tgl 1642 ECB : {
1643 : /* For values outside the transition table, extrapolate */
5531 tgl 1644 GIC 78 : pg_time_t newt = t;
1645 : pg_time_t seconds;
5531 tgl 1646 ECB : pg_time_t tcycles;
1647 : int64 icycles;
1648 : int result;
1649 :
5531 tgl 1650 GIC 78 : if (t < sp->ats[0])
5531 tgl 1651 UIC 0 : seconds = sp->ats[0] - t;
5050 bruce 1652 ECB : else
5050 bruce 1653 GBC 78 : seconds = t - sp->ats[sp->timecnt - 1];
5531 tgl 1654 GIC 78 : --seconds;
5531 tgl 1655 CBC 78 : tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1656 78 : ++tcycles;
1657 78 : icycles = tcycles;
1658 78 : if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
5531 tgl 1659 LBC 0 : return -1;
5531 tgl 1660 CBC 78 : seconds = icycles;
5531 tgl 1661 GBC 78 : seconds *= YEARSPERREPEAT;
5531 tgl 1662 CBC 78 : seconds *= AVGSECSPERYEAR;
1663 78 : if (t < sp->ats[0])
5531 tgl 1664 LBC 0 : newt += seconds;
5050 bruce 1665 ECB : else
5050 bruce 1666 GBC 78 : newt -= seconds;
5531 tgl 1667 GIC 78 : if (newt < sp->ats[0] ||
5531 tgl 1668 CBC 78 : newt > sp->ats[sp->timecnt - 1])
5050 bruce 1669 LBC 0 : return -1; /* "cannot happen" */
5531 tgl 1670 ECB :
5531 tgl 1671 GBC 78 : result = pg_next_dst_boundary(&newt, before_gmtoff,
1672 : before_isdst,
5531 tgl 1673 ECB : boundary,
1674 : after_gmtoff,
1675 : after_isdst,
1676 : tz);
5531 tgl 1677 GIC 78 : if (t < sp->ats[0])
5531 tgl 1678 UIC 0 : *boundary -= seconds;
5531 tgl 1679 ECB : else
5531 tgl 1680 GBC 78 : *boundary += seconds;
5531 tgl 1681 GIC 78 : return result;
5531 tgl 1682 ECB : }
1683 :
4001 tgl 1684 GIC 25177 : if (t >= sp->ats[sp->timecnt - 1])
1685 : {
4001 tgl 1686 ECB : /* No known transition > t, so use last known segment's type */
6733 tgl 1687 GIC 405 : i = sp->types[sp->timecnt - 1];
1688 405 : ttisp = &sp->ttis[i];
1362 tgl 1689 CBC 405 : *before_gmtoff = ttisp->tt_utoff;
6733 1690 405 : *before_isdst = ttisp->tt_isdst;
1691 405 : return 0;
6733 tgl 1692 ECB : }
4001 tgl 1693 CBC 24772 : if (t < sp->ats[0])
1694 : {
6733 tgl 1695 ECB : /* For "before", use lowest-numbered standard type */
6733 tgl 1696 GIC 282 : i = 0;
1697 282 : while (sp->ttis[i].tt_isdst)
6733 tgl 1698 LBC 0 : if (++i >= sp->typecnt)
6733 tgl 1699 ECB : {
6733 tgl 1700 UBC 0 : i = 0;
6733 tgl 1701 UIC 0 : break;
6733 tgl 1702 EUB : }
6733 tgl 1703 GBC 282 : ttisp = &sp->ttis[i];
1362 tgl 1704 GIC 282 : *before_gmtoff = ttisp->tt_utoff;
6733 tgl 1705 CBC 282 : *before_isdst = ttisp->tt_isdst;
1706 282 : *boundary = sp->ats[0];
6733 tgl 1707 ECB : /* And for "after", use the first segment's type */
6733 tgl 1708 CBC 282 : i = sp->types[0];
6733 tgl 1709 GIC 282 : ttisp = &sp->ttis[i];
1362 tgl 1710 CBC 282 : *after_gmtoff = ttisp->tt_utoff;
6733 1711 282 : *after_isdst = ttisp->tt_isdst;
1712 282 : return 1;
6733 tgl 1713 ECB : }
4001 1714 : /* Else search to find the boundary following t */
1715 : {
5050 bruce 1716 GIC 24490 : int lo = 1;
4001 tgl 1717 24490 : int hi = sp->timecnt - 1;
5050 bruce 1718 ECB :
5531 tgl 1719 CBC 279030 : while (lo < hi)
1720 : {
5050 bruce 1721 254540 : int mid = (lo + hi) >> 1;
1722 :
5531 tgl 1723 254540 : if (t < sp->ats[mid])
5531 tgl 1724 GIC 182772 : hi = mid;
5050 bruce 1725 ECB : else
5050 bruce 1726 CBC 71768 : lo = mid + 1;
1727 : }
5531 tgl 1728 24490 : i = lo;
1729 : }
6733 1730 24490 : j = sp->types[i - 1];
6733 tgl 1731 GIC 24490 : ttisp = &sp->ttis[j];
1362 tgl 1732 CBC 24490 : *before_gmtoff = ttisp->tt_utoff;
6733 1733 24490 : *before_isdst = ttisp->tt_isdst;
1734 24490 : *boundary = sp->ats[i];
1735 24490 : j = sp->types[i];
1736 24490 : ttisp = &sp->ttis[j];
1362 1737 24490 : *after_gmtoff = ttisp->tt_utoff;
6733 1738 24490 : *after_isdst = ttisp->tt_isdst;
1739 24490 : return 1;
6733 tgl 1740 ECB : }
6918 bruce 1741 :
1742 : /*
1743 : * Identify a timezone abbreviation's meaning in the given zone
1744 : *
1745 : * Determine the GMT offset and DST flag associated with the abbreviation.
1746 : * This is generally used only when the abbreviation has actually changed
1747 : * meaning over time; therefore, we also take a UTC cutoff time, and return
1748 : * the meaning in use at or most recently before that time, or the meaning
1749 : * in first use after that time if the abbrev was never used before that.
1750 : *
1751 : * On success, returns true and sets *gmtoff and *isdst. If the abbreviation
1752 : * was never used at all in this zone, returns false.
1753 : *
1754 : * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1755 : */
1756 : bool
3097 tgl 1757 GIC 582 : pg_interpret_timezone_abbrev(const char *abbrev,
1758 : const pg_time_t *timep,
3097 tgl 1759 ECB : long int *gmtoff,
1760 : int *isdst,
1761 : const pg_tz *tz)
1762 : {
1763 : const struct state *sp;
1764 : const char *abbrs;
1765 : const struct ttinfo *ttisp;
1766 : int abbrind;
1767 : int cutoff;
1768 : int i;
3097 tgl 1769 GIC 582 : const pg_time_t t = *timep;
1770 :
3097 tgl 1771 CBC 582 : sp = &tz->state;
1772 :
3097 tgl 1773 ECB : /*
1774 : * Locate the abbreviation in the zone's abbreviation list. We assume
1775 : * there are not duplicates in the list.
1776 : */
3097 tgl 1777 GIC 582 : abbrs = sp->chars;
1778 582 : abbrind = 0;
3097 tgl 1779 CBC 3177 : while (abbrind < sp->charcnt)
3097 tgl 1780 ECB : {
3097 tgl 1781 CBC 2730 : if (strcmp(abbrev, abbrs + abbrind) == 0)
3097 tgl 1782 GIC 135 : break;
3097 tgl 1783 CBC 10758 : while (abbrs[abbrind] != '\0')
1784 8163 : abbrind++;
1785 2595 : abbrind++;
3097 tgl 1786 ECB : }
3097 tgl 1787 CBC 582 : if (abbrind >= sp->charcnt)
2568 tgl 1788 GIC 447 : return false; /* not there! */
3097 tgl 1789 ECB :
1790 : /*
1791 : * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1792 : * (goback/goahead zones). Finding the newest or oldest meaning of the
1793 : * abbreviation should get us what we want, since extrapolation would just
1794 : * be repeating the newest or oldest meanings.
1795 : *
1796 : * Use binary search to locate the first transition > cutoff time.
1797 : */
1798 : {
3097 tgl 1799 GIC 135 : int lo = 0;
1800 135 : int hi = sp->timecnt;
3097 tgl 1801 ECB :
3097 tgl 1802 CBC 945 : while (lo < hi)
1803 : {
1804 810 : int mid = (lo + hi) >> 1;
1805 :
1806 810 : if (t < sp->ats[mid])
3097 tgl 1807 GIC 96 : hi = mid;
3097 tgl 1808 ECB : else
3097 tgl 1809 CBC 714 : lo = mid + 1;
1810 : }
1811 135 : cutoff = lo;
1812 : }
3097 tgl 1813 ECB :
1814 : /*
1815 : * Scan backwards to find the latest interval using the given abbrev
1816 : * before the cutoff time.
1817 : */
3097 tgl 1818 GIC 135 : for (i = cutoff - 1; i >= 0; i--)
1819 : {
3097 tgl 1820 CBC 135 : ttisp = &sp->ttis[sp->types[i]];
1362 tgl 1821 GIC 135 : if (ttisp->tt_desigidx == abbrind)
3097 tgl 1822 ECB : {
1362 tgl 1823 CBC 135 : *gmtoff = ttisp->tt_utoff;
3097 tgl 1824 GIC 135 : *isdst = ttisp->tt_isdst;
2568 tgl 1825 CBC 135 : return true;
3097 tgl 1826 ECB : }
1827 : }
1828 :
1829 : /*
1830 : * Not there, so scan forwards to find the first one after.
1831 : */
3097 tgl 1832 UIC 0 : for (i = cutoff; i < sp->timecnt; i++)
1833 : {
3097 tgl 1834 UBC 0 : ttisp = &sp->ttis[sp->types[i]];
1362 tgl 1835 UIC 0 : if (ttisp->tt_desigidx == abbrind)
3097 tgl 1836 EUB : {
1362 tgl 1837 UBC 0 : *gmtoff = ttisp->tt_utoff;
3097 tgl 1838 UIC 0 : *isdst = ttisp->tt_isdst;
2568 tgl 1839 UBC 0 : return true;
3097 tgl 1840 EUB : }
1841 : }
1842 :
2568 tgl 1843 UIC 0 : return false; /* hm, not actually used in any interval? */
1844 : }
3097 tgl 1845 EUB :
1846 : /*
1847 : * If the given timezone uses only one GMT offset, store that offset
1848 : * into *gmtoff and return true, else return false.
1849 : */
1850 : bool
6017 tgl 1851 GIC 605 : pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1852 : {
6017 tgl 1853 ECB : /*
1854 : * The zone could have more than one ttinfo, if it's historically used
1855 : * more than one abbreviation. We return true as long as they all have
1856 : * the same gmtoff.
1857 : */
1858 : const struct state *sp;
1859 : int i;
1860 :
6017 tgl 1861 GIC 605 : sp = &tz->state;
1862 622 : for (i = 1; i < sp->typecnt; i++)
6017 tgl 1863 ECB : {
1362 tgl 1864 CBC 59 : if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
6017 tgl 1865 GIC 42 : return false;
6017 tgl 1866 ECB : }
1362 tgl 1867 CBC 563 : *gmtoff = sp->ttis[0].tt_utoff;
6017 tgl 1868 GIC 563 : return true;
6017 tgl 1869 ECB : }
1870 :
1871 : /*
1872 : * Return the name of the current timezone
1873 : */
1874 : const char *
6564 bruce 1875 GIC 24451 : pg_get_timezone_name(pg_tz *tz)
1876 : {
6564 bruce 1877 CBC 24451 : if (tz)
6564 bruce 1878 GIC 24451 : return tz->TZname;
6897 tgl 1879 LBC 0 : return NULL;
6918 bruce 1880 ECB : }
4230 tgl 1881 EUB :
1882 : /*
1883 : * Check whether timezone is acceptable.
1884 : *
1885 : * What we are doing here is checking for leap-second-aware timekeeping.
1886 : * We need to reject such TZ settings because they'll wreak havoc with our
1887 : * date/time arithmetic.
1888 : */
1889 : bool
4230 tgl 1890 GIC 18827 : pg_tz_acceptable(pg_tz *tz)
1891 : {
4230 tgl 1892 ECB : struct pg_tm *tt;
1893 : pg_time_t time2000;
1894 :
1895 : /*
1896 : * To detect leap-second timekeeping, run pg_localtime for what should be
1897 : * GMT midnight, 2000-01-01. Insist that the tm_sec value be zero; any
1898 : * other result has to be due to leap seconds.
1899 : */
4230 tgl 1900 GIC 18827 : time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
1901 18827 : tt = pg_localtime(&time2000, tz);
4230 tgl 1902 CBC 18827 : if (!tt || tt->tm_sec != 0)
4230 tgl 1903 LBC 0 : return false;
4230 tgl 1904 ECB :
4230 tgl 1905 GBC 18827 : return true;
1906 : }
|