LCOV - code coverage report
Current view: top level - src/timezone - localtime.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 672 803 83.7 %
Date: 2019-11-13 22:07:24 Functions: 30 30 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13