LCOV - code coverage report
Current view: top level - src/timezone - localtime.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 82.8 % 793 657
Test Date: 2026-07-03 19:57:34 Functions: 94.6 % 37 35
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 67.4 % 546 368

             Branch data     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.1-1988 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                 :             : /*
      29                 :             :  * Pacify gcc -Wcast-qual on char const * exprs.
      30                 :             :  * Use this carefully, as the casts disable type checking.
      31                 :             :  * This is a macro so that it can be used in static initializers.
      32                 :             :  */
      33                 :             : #define UNCONST(a) unconstify(char *, a)
      34                 :             : 
      35                 :             : #ifndef WILDABBR
      36                 :             : /*
      37                 :             :  * Someone might make incorrect use of a time zone abbreviation:
      38                 :             :  *  1.  They might reference tzname[0] before calling tzset (explicitly
      39                 :             :  *      or implicitly).
      40                 :             :  *  2.  They might reference tzname[1] before calling tzset (explicitly
      41                 :             :  *      or implicitly).
      42                 :             :  *  3.  They might reference tzname[1] after setting to a time zone
      43                 :             :  *      in which Daylight Saving Time is never observed.
      44                 :             :  *  4.  They might reference tzname[0] after setting to a time zone
      45                 :             :  *      in which Standard Time is never observed.
      46                 :             :  *  5.  They might reference tm.TM_ZONE after calling offtime.
      47                 :             :  * What's best to do in the above cases is open to debate;
      48                 :             :  * for now, we just set things up so that in any of the five cases
      49                 :             :  * WILDABBR is used. Another possibility: initialize tzname[0] to the
      50                 :             :  * string "tzname[0] used before set", and similarly for the other cases.
      51                 :             :  * And another: initialize tzname[0] to "ERA", with an explanation in the
      52                 :             :  * manual page of what this "time zone abbreviation" means (doing this so
      53                 :             :  * that tzname[0] has the "normal" length of three characters).
      54                 :             :  */
      55                 :             : #define WILDABBR "   "
      56                 :             : #endif                          /* !defined WILDABBR */
      57                 :             : 
      58                 :             : static const char wildabbr[] = WILDABBR;
      59                 :             : 
      60                 :             : /*
      61                 :             :  * The DST rules to use if TZ has no rules.
      62                 :             :  * Default to US rules as of 2017-05-07.
      63                 :             :  * POSIX does not specify the default DST rules;
      64                 :             :  * for historical reasons, US rules are a common default.
      65                 :             :  */
      66                 :             : #ifndef TZDEFRULESTRING
      67                 :             : #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
      68                 :             : #endif
      69                 :             : 
      70                 :             : /* TZNAME_MAXIMUM and types ttinfo, lsinfo, state have been moved to pgtz.h */
      71                 :             : 
      72                 :             : static int
      73                 :     7003175 : leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp)
      74                 :             : {
      75                 :             : #if TZ_RUNTIME_LEAPS
      76                 :     7003175 :     return sp->leapcnt;
      77                 :             : #else
      78                 :             :     return 0;
      79                 :             : #endif
      80                 :             : }
      81                 :             : static void
      82                 :       37775 : set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp,
      83                 :             :               ATTRIBUTE_MAYBE_UNUSED int leapcnt)
      84                 :             : {
      85                 :             : #if TZ_RUNTIME_LEAPS
      86                 :       37775 :     sp->leapcnt = leapcnt;
      87                 :             : #endif
      88                 :       37775 : }
      89                 :             : static struct lsinfo
      90                 :           0 : lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const *sp,
      91                 :             :        ATTRIBUTE_MAYBE_UNUSED int i)
      92                 :             : {
      93                 :             : #if TZ_RUNTIME_LEAPS
      94                 :           0 :     return sp->lsis[i];
      95                 :             : #else
      96                 :             :     unreachable();
      97                 :             : #endif
      98                 :             : }
      99                 :             : static void
     100                 :           0 : set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp,
     101                 :             :            ATTRIBUTE_MAYBE_UNUSED int i,
     102                 :             :            ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo)
     103                 :             : {
     104                 :             : #if TZ_RUNTIME_LEAPS
     105                 :           0 :     sp->lsis[i] = lsinfo;
     106                 :             : #endif
     107                 :           0 : }
     108                 :             : 
     109                 :             : enum r_type
     110                 :             : {
     111                 :             :     JULIAN_DAY,                 /* Jn = Julian day */
     112                 :             :     DAY_OF_YEAR,                /* n = day of year */
     113                 :             :     MONTH_NTH_DAY_OF_WEEK       /* Mm.n.d = month, week, day of week */
     114                 :             : };
     115                 :             : 
     116                 :             : struct rule
     117                 :             : {
     118                 :             :     enum r_type r_type;         /* type of rule */
     119                 :             :     int         r_day;          /* day number of rule */
     120                 :             :     int         r_week;         /* week number of rule */
     121                 :             :     int         r_mon;          /* month number of rule */
     122                 :             :     int_fast32_t r_time;        /* transition time of rule */
     123                 :             : };
     124                 :             : 
     125                 :             : /*
     126                 :             :  * Prototypes for static functions.
     127                 :             :  */
     128                 :             : 
     129                 :             : static struct pg_tm *gmtsub(pg_time_t const *timep, int_fast32_t offset,
     130                 :             :                             struct pg_tm *tmp);
     131                 :             : static bool increment_overflow(int *ip, int j);
     132                 :             : static bool increment_overflow_time(pg_time_t *tp, int_fast32_2s j);
     133                 :             : static int_fast32_2s leapcorr(struct state const *sp, pg_time_t t);
     134                 :             : static struct pg_tm *timesub(pg_time_t const *timep,
     135                 :             :                              int_fast32_t offset, struct state const *sp,
     136                 :             :                              struct pg_tm *tmp);
     137                 :             : static bool tzparse(const char *name, struct state *sp, struct state const *basep);
     138                 :             : 
     139                 :             : 
     140                 :             : /*
     141                 :             :  * Section 4.12.3 of X3.159-1989 requires that
     142                 :             :  *  Except for the strftime function, these functions [asctime,
     143                 :             :  *  ctime, gmtime, localtime] return values in one of two static
     144                 :             :  *  objects: a broken-down time structure and an array of char.
     145                 :             :  * Thanks to Paul Eggert for noting this.
     146                 :             :  */
     147                 :             : 
     148                 :             : static struct pg_tm tm;
     149                 :             : 
     150                 :             : /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
     151                 :             : static void
     152                 :       20442 : init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst,
     153                 :             :             desigidx_type desigidx)
     154                 :             : {
     155                 :       20442 :     s->tt_utoff = utoff;
     156                 :       20442 :     s->tt_isdst = isdst;
     157                 :       20442 :     s->tt_desigidx = desigidx;
     158                 :       20442 :     s->tt_ttisstd = false;
     159                 :       20442 :     s->tt_ttisut = false;
     160                 :       20442 : }
     161                 :             : 
     162                 :             : static int_fast32_2s
     163                 :      196466 : detzcode(const char *const codep)
     164                 :             : {
     165                 :             :     int         i;
     166                 :             :     int_fast32_2s
     167                 :      196466 :                 maxval = TWO_31_MINUS_1,
     168                 :      196466 :                 minval = -1 - maxval,
     169                 :             :                 result;
     170                 :             : 
     171                 :      196466 :     result = codep[0] & 0x7f;
     172         [ +  + ]:      785864 :     for (i = 1; i < 4; ++i)
     173                 :      589398 :         result = (result << 8) | (codep[i] & 0xff);
     174                 :             : 
     175         [ +  + ]:      196466 :     if (codep[0] & 0x80)
     176                 :             :     {
     177                 :             :         /*
     178                 :             :          * Do two's-complement negation even on non-two's-complement machines.
     179                 :             :          * This cannot overflow, as int_fast32_2s is wide enough.
     180                 :             :          */
     181                 :       35899 :         result += minval;
     182                 :             :     }
     183                 :      196466 :     return result;
     184                 :             : }
     185                 :             : 
     186                 :             : static int_fast64_t
     187                 :      881121 : detzcode64(const char *const codep)
     188                 :             : {
     189                 :             :     int_fast64_t result;
     190                 :             :     int         i;
     191                 :      881121 :     int_fast64_t one = 1;
     192                 :      881121 :     int_fast64_t halfmaxval = one << (64 - 2);
     193                 :      881121 :     int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
     194                 :      881121 :     int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
     195                 :             : 
     196                 :      881121 :     result = codep[0] & 0x7f;
     197         [ +  + ]:     7048968 :     for (i = 1; i < 8; ++i)
     198                 :     6167847 :         result = (result << 8) | (codep[i] & 0xff);
     199                 :             : 
     200         [ +  + ]:      881121 :     if (codep[0] & 0x80)
     201                 :             :     {
     202                 :             :         /*
     203                 :             :          * Do two's-complement negation even on non-two's-complement machines.
     204                 :             :          * If the result would be minval - 1, return minval.
     205                 :             :          */
     206                 :      338189 :         result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
     207                 :      338189 :         result += minval;
     208                 :             :     }
     209                 :      881121 :     return result;
     210                 :             : }
     211                 :             : 
     212                 :             : /* Input buffer for data read from a compiled tz file.  */
     213                 :             : union input_buffer
     214                 :             : {
     215                 :             :     /* The first part of the buffer, interpreted as a header.  */
     216                 :             :     struct tzhead tzhead;
     217                 :             : 
     218                 :             :     /*
     219                 :             :      * The entire buffer.  Ideally this would have no size limits; the
     220                 :             :      * following should suffice for practical use.
     221                 :             :      */
     222                 :             :     char        buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
     223                 :             :                     + 4 * TZ_MAX_TIMES];
     224                 :             : };
     225                 :             : 
     226                 :             : /* Local storage needed for 'tzloadbody'.  */
     227                 :             : union local_storage
     228                 :             : {
     229                 :             :     /* The results of analyzing the file's contents after it is opened.  */
     230                 :             :     struct file_analysis
     231                 :             :     {
     232                 :             :         /* The input buffer.  */
     233                 :             :         union input_buffer u;
     234                 :             : 
     235                 :             :         /* A temporary state used for parsing a TZ string in the file.  */
     236                 :             :         struct state st;
     237                 :             :     }           u;
     238                 :             : 
     239                 :             :     /* PG: we don't need the "fullname" member */
     240                 :             : };
     241                 :             : 
     242                 :             : /* These tzload flags can be ORed together, and fit into 'char'.  */
     243                 :             : enum
     244                 :             : {
     245                 :             : TZLOAD_FROMENV = 1};            /* The TZ string came from the environment.  */
     246                 :             : enum
     247                 :             : {
     248                 :             : TZLOAD_TZSTRING = 2};           /* Read any newline-surrounded TZ string.  */
     249                 :             : enum
     250                 :             : {
     251                 :             : TZLOAD_TZDIR_SUB = 4};          /* TZ should be a file under TZDIR.  */
     252                 :             : 
     253                 :             : /*
     254                 :             :  * Load tz data from the file named NAME into *SP.  Respect TZLOADFLAGS.
     255                 :             :  * Use **LSPP for temporary storage.  Return 0 on
     256                 :             :  * success, an errno value on failure.
     257                 :             :  * PG: If "canonname" is not NULL, then on success the canonical spelling of
     258                 :             :  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
     259                 :             :  */
     260                 :             : static int
     261                 :       12304 : tzloadbody(char const *name, char *canonname,
     262                 :             :            struct state *sp, char tzloadflags,
     263                 :             :            union local_storage **lspp)
     264                 :             : {
     265                 :             :     int         i;
     266                 :             :     int         fid;
     267                 :             :     int         stored;
     268                 :             :     ssize_t     nread;
     269                 :       12304 :     union local_storage *lsp = *lspp;
     270                 :             :     union input_buffer *up;
     271                 :       12304 :     int         tzheadsize = sizeof(struct tzhead);
     272                 :             : 
     273                 :       12304 :     sp->goback = sp->goahead = false;
     274                 :             : 
     275         [ -  + ]:       12304 :     if (!name)
     276                 :             :     {
     277                 :           0 :         name = TZDEFAULT;
     278         [ #  # ]:           0 :         if (!name)
     279                 :           0 :             return EINVAL;
     280                 :             :     }
     281                 :             : 
     282         [ -  + ]:       12304 :     if (name[0] == ':')
     283                 :           0 :         ++name;
     284                 :             : 
     285                 :             :     /*
     286                 :             :      * The IANA code goes to a great deal of trouble here to try to prevent
     287                 :             :      * inappropriate file accesses.  That seems unnecessary for PG since we
     288                 :             :      * won't run as root.  pg_open_tzfile() does go to some effort to prevent
     289                 :             :      * accesses outside the designated zoneinfo tree, though.
     290                 :             :      */
     291                 :       12304 :     fid = pg_open_tzfile(name, canonname);
     292         [ +  + ]:       12304 :     if (fid < 0)
     293                 :         289 :         return ENOENT;          /* pg_open_tzfile may not set errno */
     294                 :             : 
     295                 :       12015 :     up = &lsp->u.u;
     296                 :       12015 :     nread = read(fid, up->buf, sizeof up->buf);
     297         [ -  + ]:       12015 :     if (nread < tzheadsize)
     298                 :             :     {
     299         [ #  # ]:           0 :         int         err = nread < 0 ? errno : EINVAL;
     300                 :             : 
     301                 :           0 :         close(fid);
     302                 :           0 :         return err;
     303                 :             :     }
     304         [ -  + ]:       12015 :     if (close(fid) < 0)
     305                 :           0 :         return errno;
     306                 :             : 
     307         [ +  + ]:       36045 :     for (stored = 4; stored <= 8; stored *= 2)
     308                 :             :     {
     309                 :       24030 :         char        version = up->tzhead.tzh_version[0];
     310   [ +  +  +  - ]:       24030 :         bool        skip_datablock = stored == 4 && version;
     311                 :             :         int_fast32_t datablock_size;
     312                 :             :         int_fast32_2s
     313                 :       24030 :                     ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt),
     314                 :       24030 :                     ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt),
     315                 :       24030 :                     leapcnt = detzcode(up->tzhead.tzh_leapcnt),
     316                 :       24030 :                     timecnt = detzcode(up->tzhead.tzh_timecnt),
     317                 :       24030 :                     typecnt = detzcode(up->tzhead.tzh_typecnt),
     318                 :       24030 :                     charcnt = detzcode(up->tzhead.tzh_charcnt);
     319                 :       24030 :         char const *p = up->buf + tzheadsize;
     320                 :             : 
     321                 :             :         /*
     322                 :             :          * Although tzfile(5) currently requires typecnt to be nonzero,
     323                 :             :          * support future formats that may allow zero typecnt in files that
     324                 :             :          * have a TZ string and no transitions.
     325                 :             :          */
     326   [ +  -  -  + ]:       48060 :         if (!(0 <= leapcnt
     327         [ +  - ]:       24030 :               && leapcnt <= (TZ_RUNTIME_LEAPS ? TZ_MAX_LEAPS : 0)
     328   [ +  -  +  - ]:       24030 :               && 0 <= typecnt && typecnt <= TZ_MAX_TYPES
     329   [ +  -  +  - ]:       24030 :               && 0 <= timecnt && timecnt <= TZ_MAX_TIMES
     330   [ +  -  +  - ]:       24030 :               && 0 <= charcnt && charcnt <= TZ_MAX_CHARS
     331   [ +  -  +  - ]:       24030 :               && 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES
     332         [ +  - ]:       24030 :               && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES))
     333                 :           0 :             return EINVAL;
     334                 :             :         datablock_size
     335                 :       24030 :             = (timecnt * stored /* ats */
     336                 :       24030 :                + timecnt        /* types */
     337                 :       24030 :                + typecnt * 6    /* ttinfos */
     338                 :       24030 :                + charcnt        /* chars */
     339                 :       24030 :                + leapcnt * (stored + 4) /* lsinfos */
     340                 :       24030 :                + ttisstdcnt     /* ttisstds */
     341                 :             :                + ttisutcnt);    /* ttisuts */
     342         [ -  + ]:       24030 :         if (nread < tzheadsize + datablock_size)
     343                 :           0 :             return EINVAL;
     344         [ +  + ]:       24030 :         if (skip_datablock)
     345                 :       12015 :             p += datablock_size;
     346   [ +  -  +  -  :       12015 :         else if (!((ttisstdcnt == typecnt || ttisstdcnt == 0)
                   +  - ]
     347         [ -  + ]:       12015 :                    && (ttisutcnt == typecnt || ttisutcnt == 0)))
     348                 :           0 :             return EINVAL;
     349                 :             :         else
     350                 :             :         {
     351                 :       12015 :             int_fast64_t prevtr = -1;
     352                 :       12015 :             int_fast32_2s prevcorr = -1;
     353                 :             : 
     354                 :       12015 :             set_leapcount(sp, leapcnt);
     355                 :       12015 :             sp->timecnt = timecnt;
     356                 :       12015 :             sp->typecnt = typecnt;
     357                 :       12015 :             sp->charcnt = charcnt;
     358                 :             : 
     359                 :             :             /*
     360                 :             :              * Read transitions, discarding those out of pg_time_t range. But
     361                 :             :              * pretend the last transition before TIME_T_MIN occurred at
     362                 :             :              * TIME_T_MIN.
     363                 :             :              */
     364                 :       12015 :             timecnt = 0;
     365         [ +  + ]:      893136 :             for (i = 0; i < sp->timecnt; ++i)
     366                 :             :             {
     367                 :      881121 :                 int_fast64_t at
     368         [ -  + ]:      881121 :                 = stored == 4 ? detzcode(p) : detzcode64(p);
     369                 :             : 
     370                 :      881121 :                 sp->types[i] = at <= TIME_T_MAX;
     371         [ +  - ]:      881121 :                 if (sp->types[i])
     372                 :             :                 {
     373                 :      881121 :                     pg_time_t   attime
     374                 :             :                     = ((TYPE_SIGNED(pg_time_t) ? at < TIME_T_MIN : at < 0)
     375                 :             :                        ? TIME_T_MIN : at);
     376                 :             : 
     377   [ +  +  -  + ]:      881121 :                     if (timecnt && attime <= sp->ats[timecnt - 1])
     378                 :             :                     {
     379         [ #  # ]:           0 :                         if (attime < sp->ats[timecnt - 1])
     380                 :           0 :                             return EINVAL;
     381                 :           0 :                         sp->types[i - 1] = 0;
     382                 :           0 :                         timecnt--;
     383                 :             :                     }
     384                 :      881121 :                     sp->ats[timecnt++] = attime;
     385                 :             :                 }
     386                 :      881121 :                 p += stored;
     387                 :             :             }
     388                 :             : 
     389                 :       12015 :             timecnt = 0;
     390         [ +  + ]:      893136 :             for (i = 0; i < sp->timecnt; ++i)
     391                 :             :             {
     392                 :      881121 :                 unsigned char typ = *p++;
     393                 :             : 
     394         [ -  + ]:      881121 :                 if (sp->typecnt <= typ)
     395                 :           0 :                     return EINVAL;
     396         [ +  - ]:      881121 :                 if (sp->types[i])
     397                 :      881121 :                     sp->types[timecnt++] = typ;
     398                 :             :             }
     399                 :       12015 :             sp->timecnt = timecnt;
     400         [ +  + ]:       64301 :             for (i = 0; i < sp->typecnt; ++i)
     401                 :             :             {
     402                 :             :                 struct ttinfo *ttisp;
     403                 :             :                 unsigned char isdst,
     404                 :             :                             desigidx;
     405                 :       52286 :                 int_fast32_2s utoff = detzcode(p);
     406                 :             : 
     407                 :             :                 /*
     408                 :             :                  * Reject a UT offset equal to -2**31, as it might cause
     409                 :             :                  * trouble both in this file and in callers. Also, it violates
     410                 :             :                  * RFC 9636 section 3.2.
     411                 :             :                  */
     412         [ -  + ]:       52286 :                 if (utoff < -TWO_31_MINUS_1)
     413                 :           0 :                     return EINVAL;
     414                 :             : 
     415                 :       52286 :                 ttisp = &sp->ttis[i];
     416                 :       52286 :                 ttisp->tt_utoff = utoff;
     417                 :       52286 :                 p += 4;
     418                 :       52286 :                 isdst = *p++;
     419         [ -  + ]:       52286 :                 if (!(isdst < 2))
     420                 :           0 :                     return EINVAL;
     421                 :       52286 :                 ttisp->tt_isdst = isdst;
     422                 :       52286 :                 desigidx = *p++;
     423         [ -  + ]:       52286 :                 if (!(desigidx < sp->charcnt))
     424                 :           0 :                     return EINVAL;
     425                 :       52286 :                 ttisp->tt_desigidx = desigidx;
     426                 :             :             }
     427         [ +  + ]:      217396 :             for (i = 0; i < sp->charcnt; ++i)
     428                 :      205381 :                 sp->chars[i] = *p++;
     429                 :             : 
     430                 :             :             /*
     431                 :             :              * Ensure '\0'-terminated, and make it safe to call ttunspecified
     432                 :             :              * later.
     433                 :             :              */
     434                 :       12015 :             memset(&sp->chars[i], 0, CHARS_EXTRA);
     435                 :             : 
     436                 :             :             /* Read leap seconds, discarding those out of pg_time_t range.  */
     437                 :       12015 :             leapcnt = 0;
     438         [ -  + ]:       12015 :             for (i = 0; i < leapcount(sp); i++)
     439                 :             :             {
     440         [ #  # ]:           0 :                 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
     441                 :           0 :                 int_fast32_2s corr = detzcode(p + stored);
     442                 :             : 
     443                 :           0 :                 p += stored + 4;
     444                 :             : 
     445                 :             :                 /*
     446                 :             :                  * Leap seconds cannot occur before the Epoch, or out of
     447                 :             :                  * order.
     448                 :             :                  */
     449         [ #  # ]:           0 :                 if (tr <= prevtr)
     450                 :           0 :                     return EINVAL;
     451                 :             : 
     452                 :             :                 /*
     453                 :             :                  * To avoid other botches in this code, each leap second's
     454                 :             :                  * correction must differ from the previous one's by 1 second
     455                 :             :                  * or less, except that the first correction can be any value;
     456                 :             :                  * these requirements are more generous than RFC 9636, to
     457                 :             :                  * allow future RFC extensions.
     458                 :             :                  */
     459   [ #  #  #  # ]:           0 :                 if (!(i == 0
     460         [ #  # ]:           0 :                       || (prevcorr < corr
     461                 :           0 :                           ? corr == prevcorr + 1
     462                 :             :                           : (corr == prevcorr
     463   [ #  #  #  # ]:           0 :                              || corr == prevcorr - 1))))
     464                 :           0 :                     return EINVAL;
     465                 :           0 :                 prevtr = tr;
     466                 :           0 :                 prevcorr = corr;
     467                 :             : 
     468                 :             :                 if (tr <= TIME_T_MAX)
     469                 :             :                 {
     470                 :             :                     struct lsinfo ls;
     471                 :             : 
     472                 :           0 :                     ls.ls_trans = tr;
     473                 :           0 :                     ls.ls_corr = corr;
     474                 :           0 :                     set_lsinfo(sp, leapcnt, ls);
     475                 :           0 :                     leapcnt++;
     476                 :             :                 }
     477                 :             :             }
     478                 :       12015 :             set_leapcount(sp, leapcnt);
     479                 :             : 
     480         [ +  + ]:       64301 :             for (i = 0; i < sp->typecnt; ++i)
     481                 :             :             {
     482                 :             :                 struct ttinfo *ttisp;
     483                 :             : 
     484                 :       52286 :                 ttisp = &sp->ttis[i];
     485         [ +  - ]:       52286 :                 if (ttisstdcnt == 0)
     486                 :       52286 :                     ttisp->tt_ttisstd = false;
     487                 :             :                 else
     488                 :             :                 {
     489   [ #  #  #  # ]:           0 :                     if (*p != true && *p != false)
     490                 :           0 :                         return EINVAL;
     491                 :           0 :                     ttisp->tt_ttisstd = *p++;
     492                 :             :                 }
     493                 :             :             }
     494         [ +  + ]:       64301 :             for (i = 0; i < sp->typecnt; ++i)
     495                 :             :             {
     496                 :             :                 struct ttinfo *ttisp;
     497                 :             : 
     498                 :       52286 :                 ttisp = &sp->ttis[i];
     499         [ +  - ]:       52286 :                 if (ttisutcnt == 0)
     500                 :       52286 :                     ttisp->tt_ttisut = false;
     501                 :             :                 else
     502                 :             :                 {
     503   [ #  #  #  # ]:           0 :                     if (*p != true && *p != false)
     504                 :           0 :                         return EINVAL;
     505                 :           0 :                     ttisp->tt_ttisut = *p++;
     506                 :             :                 }
     507                 :             :             }
     508                 :             :         }
     509                 :             : 
     510                 :       24030 :         nread -= p - up->buf;
     511                 :       24030 :         memmove(up->buf, p, nread);
     512                 :             : 
     513                 :             :         /* If this is an old file, we're done.  */
     514         [ -  + ]:       24030 :         if (!version)
     515                 :           0 :             break;
     516                 :             :     }
     517   [ +  -  +  - ]:       12015 :     if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 &&
     518   [ +  -  +  - ]:       12015 :         up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
     519         [ +  - ]:       12015 :         sp->typecnt + 2 <= TZ_MAX_TYPES)
     520                 :             :     {
     521                 :       12015 :         struct state *ts = &lsp->u.st;
     522                 :             : 
     523                 :       12015 :         up->buf[nread - 1] = '\0';
     524         [ +  - ]:       12015 :         if (tzparse(&up->buf[1], ts, sp))
     525                 :             :         {
     526                 :             : 
     527                 :             :             /*
     528                 :             :              * Attempt to reuse existing abbreviations. Without this,
     529                 :             :              * America/Anchorage would consume 50 bytes for abbreviations, as
     530                 :             :              * sp->charcnt equals 40 (for LMT AST AWT APT AHST AHDT YST AKDT
     531                 :             :              * AKST) and ts->charcnt equals 10 (for AKST AKDT).  Reusing means
     532                 :             :              * sp->charcnt can stay 40 in this example.
     533                 :             :              */
     534                 :       12015 :             int         gotabbr = 0;
     535                 :       12015 :             int         charcnt = sp->charcnt;
     536                 :             : 
     537         [ +  + ]:       30714 :             for (i = 0; i < ts->typecnt; i++)
     538                 :             :             {
     539                 :       18699 :                 char       *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
     540                 :             :                 int         j;
     541                 :             : 
     542         [ +  + ]:      157166 :                 for (j = 0; j < charcnt; j++)
     543         [ +  + ]:      157106 :                     if (strcmp(sp->chars + j, tsabbr) == 0)
     544                 :             :                     {
     545                 :       18639 :                         ts->ttis[i].tt_desigidx = j;
     546                 :       18639 :                         gotabbr++;
     547                 :       18639 :                         break;
     548                 :             :                     }
     549         [ +  + ]:       18699 :                 if (!(j < charcnt))
     550                 :             :                 {
     551                 :          60 :                     int         tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j);
     552                 :             : 
     553         [ +  - ]:          60 :                     if (j + tsabbrlen < TZ_MAX_CHARS)
     554                 :             :                     {
     555                 :          60 :                         char       *cp = sp->chars + j;
     556                 :             : 
     557                 :          60 :                         memcpy(cp, tsabbr, tsabbrlen);
     558                 :          60 :                         cp += tsabbrlen;
     559                 :          60 :                         *cp = '\0';
     560                 :          60 :                         charcnt = j + tsabbrlen + 1;
     561                 :          60 :                         ts->ttis[i].tt_desigidx = j;
     562                 :          60 :                         gotabbr++;
     563                 :             :                     }
     564                 :             :                 }
     565                 :             :             }
     566         [ +  - ]:       12015 :             if (gotabbr == ts->typecnt)
     567                 :             :             {
     568                 :       12015 :                 sp->charcnt = charcnt;
     569                 :             : 
     570                 :             :                 /*
     571                 :             :                  * Ignore any trailing, no-op transitions generated by zic as
     572                 :             :                  * they don't help here and can run afoul of bugs in zic 2016j
     573                 :             :                  * or earlier.
     574                 :             :                  */
     575                 :       12015 :                 while (1 < sp->timecnt
     576         [ +  + ]:       12363 :                        && (sp->types[sp->timecnt - 1]
     577         [ +  + ]:       10293 :                            == sp->types[sp->timecnt - 2]))
     578                 :         348 :                     sp->timecnt--;
     579                 :             : 
     580                 :       12015 :                 sp->goahead = ts->goahead;
     581                 :             : 
     582         [ +  + ]:     5385305 :                 for (i = 0; i < ts->timecnt; i++)
     583                 :             :                 {
     584                 :     5373290 :                     pg_time_t   t = ts->ats[i];
     585                 :             : 
     586         [ +  - ]:     5373290 :                     if (increment_overflow_time(&t, leapcorr(sp, t))
     587         [ +  - ]:     5373290 :                         || (0 < sp->timecnt
     588         [ +  + ]:     5373290 :                             && t <= sp->ats[sp->timecnt - 1]))
     589                 :        6266 :                         continue;
     590         [ -  + ]:     5367024 :                     if (TZ_MAX_TIMES <= sp->timecnt)
     591                 :             :                     {
     592                 :           0 :                         sp->goahead = false;
     593                 :           0 :                         break;
     594                 :             :                     }
     595                 :     5367024 :                     sp->ats[sp->timecnt] = t;
     596                 :     5367024 :                     sp->types[sp->timecnt] = (sp->typecnt
     597                 :     5367024 :                                               + ts->types[i]);
     598                 :     5367024 :                     sp->timecnt++;
     599                 :             :                 }
     600         [ +  + ]:       30714 :                 for (i = 0; i < ts->typecnt; i++)
     601                 :       18699 :                     sp->ttis[sp->typecnt++] = ts->ttis[i];
     602                 :             :             }
     603                 :             :         }
     604                 :             :     }
     605         [ -  + ]:       12015 :     if (sp->typecnt == 0)
     606                 :           0 :         return EINVAL;
     607                 :             : 
     608                 :       12015 :     return 0;
     609                 :             : }
     610                 :             : 
     611                 :             : /*
     612                 :             :  * Load tz data from the file named NAME into *SP.  Respect TZLOADFLAGS.
     613                 :             :  * Return 0 on success, an errno value on failure.
     614                 :             :  * PG: If "canonname" is not NULL, then on success the canonical spelling of
     615                 :             :  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
     616                 :             :  */
     617                 :             : static int
     618                 :       12304 : tzload(char const *name, char *canonname, struct state *sp, char tzloadflags)
     619                 :             : {
     620                 :             :     /* PG: our version of tzloadbody never reallocates *lspp */
     621                 :             :     union local_storage *lsp;
     622                 :             :     union local_storage ls;
     623                 :             : 
     624                 :       12304 :     lsp = &ls;
     625                 :       12304 :     return tzloadbody(name, canonname, sp, tzloadflags, &lsp);
     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                 :             : /* Is C an ASCII digit?  */
     638                 :             : static bool
     639                 :      193025 : is_digit(char c)
     640                 :             : {
     641   [ +  +  +  + ]:      193025 :     return '0' <= c && c <= '9';
     642                 :             : }
     643                 :             : 
     644                 :             : /*
     645                 :             :  * Given a pointer into a timezone string, scan until a character that is not
     646                 :             :  * a valid character in a time zone abbreviation is found.
     647                 :             :  * Return a pointer to that character.
     648                 :             :  */
     649                 :             : 
     650                 :             : ATTRIBUTE_PURE_114833 static const char *
     651                 :       17839 : getzname(const char *strp)
     652                 :             : {
     653                 :             :     char        c;
     654                 :             : 
     655   [ +  +  +  +  :       73163 :     while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
          +  +  +  +  +  
                      + ]
     656                 :             :            c != '+')
     657                 :       55324 :         ++strp;
     658                 :       17839 :     return strp;
     659                 :             : }
     660                 :             : 
     661                 :             : /*
     662                 :             :  * Given a pointer into an extended timezone string, scan until the ending
     663                 :             :  * delimiter of the time zone abbreviation is located.
     664                 :             :  * Return a pointer to the delimiter.
     665                 :             :  *
     666                 :             :  * As with getzname above, the legal character set is actually quite
     667                 :             :  * restricted, with other characters producing undefined results.
     668                 :             :  * We don't do any checking here; checking is done later in common-case code.
     669                 :             :  */
     670                 :             : 
     671                 :             : ATTRIBUTE_PURE_114833 static const char *
     672                 :        2671 : getqzname(const char *strp, const int delim)
     673                 :             : {
     674                 :             :     int         c;
     675                 :             : 
     676   [ +  -  +  + ]:       11076 :     while ((c = *strp) != '\0' && c != delim)
     677                 :        8405 :         ++strp;
     678                 :        2671 :     return strp;
     679                 :             : }
     680                 :             : 
     681                 :             : /*
     682                 :             :  * Given a pointer into a timezone string, extract a number from that string.
     683                 :             :  * Check that the number is within a specified range; if it is not, return
     684                 :             :  * NULL.
     685                 :             :  * Otherwise, return a pointer to the first character not part of the number.
     686                 :             :  */
     687                 :             : 
     688                 :             : static const char *
     689                 :       55935 : getnum(const char *strp, int *const nump, const int min, const int max)
     690                 :             : {
     691                 :             :     char        c;
     692                 :             :     int         num;
     693                 :             : 
     694   [ +  -  +  + ]:       55935 :     if (strp == NULL || !is_digit(c = *strp))
     695                 :          68 :         return NULL;
     696                 :       55867 :     num = 0;
     697                 :             :     do
     698                 :             :     {
     699                 :       63999 :         num = num * 10 + (c - '0');
     700         [ -  + ]:       63999 :         if (num > max)
     701                 :           0 :             return NULL;        /* illegal value */
     702                 :       63999 :         c = *++strp;
     703         [ +  + ]:       63999 :     } while (is_digit(c));
     704         [ -  + ]:       55867 :     if (num < min)
     705                 :           0 :         return NULL;            /* illegal value */
     706                 :       55867 :     *nump = num;
     707                 :       55867 :     return strp;
     708                 :             : }
     709                 :             : 
     710                 :             : /*
     711                 :             :  * Given a pointer into a timezone string, extract a number of seconds,
     712                 :             :  * in hh[:mm[:ss]] form, from the string.
     713                 :             :  * If any error occurs, return NULL.
     714                 :             :  * Otherwise, return a pointer to the first character not part of the number
     715                 :             :  * of seconds.
     716                 :             :  */
     717                 :             : 
     718                 :             : static const char *
     719                 :       15387 : getsecs(const char *strp, int_fast32_t *const secsp)
     720                 :             : {
     721                 :             :     int         num;
     722                 :       15387 :     int_fast32_t secsperhour = SECSPERHOUR;
     723                 :             : 
     724                 :             :     /*
     725                 :             :      * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
     726                 :             :      * "M10.4.6/26", which does not conform to POSIX, but which specifies the
     727                 :             :      * equivalent of "02:00 on the first Sunday on or after 23 Oct".
     728                 :             :      */
     729                 :       15387 :     strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
     730         [ +  + ]:       15387 :     if (strp == NULL)
     731                 :          68 :         return NULL;
     732                 :       15319 :     *secsp = num * secsperhour;
     733         [ +  + ]:       15319 :     if (*strp == ':')
     734                 :             :     {
     735                 :         366 :         ++strp;
     736                 :         366 :         strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
     737         [ -  + ]:         366 :         if (strp == NULL)
     738                 :           0 :             return NULL;
     739                 :         366 :         *secsp += num * SECSPERMIN;
     740         [ -  + ]:         366 :         if (*strp == ':')
     741                 :             :         {
     742                 :           0 :             ++strp;
     743                 :             :             /* 'SECSPERMIN' allows for leap seconds.  */
     744                 :           0 :             strp = getnum(strp, &num, 0, SECSPERMIN);
     745         [ #  # ]:           0 :             if (strp == NULL)
     746                 :           0 :                 return NULL;
     747                 :           0 :             *secsp += num;
     748                 :             :         }
     749                 :             :     }
     750                 :       15319 :     return strp;
     751                 :             : }
     752                 :             : 
     753                 :             : /*
     754                 :             :  * Given a pointer into a timezone string, extract an offset, in
     755                 :             :  * [+-]hh[:mm[:ss]] form, from the string.
     756                 :             :  * If any error occurs, return NULL.
     757                 :             :  * Otherwise, return a pointer to the first character not part of the time.
     758                 :             :  */
     759                 :             : 
     760                 :             : static const char *
     761                 :       15387 : getoffset(const char *strp, int_fast32_t *const offsetp)
     762                 :             : {
     763                 :       15387 :     bool        neg = false;
     764                 :             : 
     765         [ +  + ]:       15387 :     if (*strp == '-')
     766                 :             :     {
     767                 :        3387 :         neg = true;
     768                 :        3387 :         ++strp;
     769                 :             :     }
     770         [ +  + ]:       12000 :     else if (*strp == '+')
     771                 :          85 :         ++strp;
     772                 :       15387 :     strp = getsecs(strp, offsetp);
     773         [ +  + ]:       15387 :     if (strp == NULL)
     774                 :          68 :         return NULL;            /* illegal time */
     775         [ +  + ]:       15319 :     if (neg)
     776                 :        3387 :         *offsetp = -*offsetp;
     777                 :       15319 :     return strp;
     778                 :             : }
     779                 :             : 
     780                 :             : /*
     781                 :             :  * Given a pointer into a timezone string, extract a rule in the form
     782                 :             :  * date[/time]. See POSIX Base Definitions section 8.3 variable TZ
     783                 :             :  * for the format of "date" and "time".
     784                 :             :  * If a valid rule is not found, return NULL.
     785                 :             :  * Otherwise, return a pointer to the first character not part of the rule.
     786                 :             :  */
     787                 :             : 
     788                 :             : static const char *
     789                 :       13394 : getrule(const char *strp, struct rule *const rulep)
     790                 :             : {
     791         [ -  + ]:       13394 :     if (*strp == 'J')
     792                 :             :     {
     793                 :             :         /*
     794                 :             :          * Julian day.
     795                 :             :          */
     796                 :           0 :         rulep->r_type = JULIAN_DAY;
     797                 :           0 :         ++strp;
     798                 :           0 :         strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
     799                 :             :     }
     800         [ +  - ]:       13394 :     else if (*strp == 'M')
     801                 :             :     {
     802                 :             :         /*
     803                 :             :          * Month, week, day.
     804                 :             :          */
     805                 :       13394 :         rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
     806                 :       13394 :         ++strp;
     807                 :       13394 :         strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
     808         [ -  + ]:       13394 :         if (strp == NULL)
     809                 :           0 :             return NULL;
     810         [ -  + ]:       13394 :         if (*strp++ != '.')
     811                 :           0 :             return NULL;
     812                 :       13394 :         strp = getnum(strp, &rulep->r_week, 1, 5);
     813         [ -  + ]:       13394 :         if (strp == NULL)
     814                 :           0 :             return NULL;
     815         [ -  + ]:       13394 :         if (*strp++ != '.')
     816                 :           0 :             return NULL;
     817                 :       13394 :         strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
     818                 :             :     }
     819         [ #  # ]:           0 :     else if (is_digit(*strp))
     820                 :             :     {
     821                 :             :         /*
     822                 :             :          * Day of year.
     823                 :             :          */
     824                 :           0 :         rulep->r_type = DAY_OF_YEAR;
     825                 :           0 :         strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
     826                 :             :     }
     827                 :             :     else
     828                 :           0 :         return NULL;            /* invalid format */
     829         [ -  + ]:       13394 :     if (strp == NULL)
     830                 :           0 :         return NULL;
     831         [ +  + ]:       13394 :     if (*strp == '/')
     832                 :             :     {
     833                 :             :         /*
     834                 :             :          * Time specified.
     835                 :             :          */
     836                 :        1520 :         ++strp;
     837                 :        1520 :         strp = getoffset(strp, &rulep->r_time);
     838                 :             :     }
     839                 :             :     else
     840                 :       11874 :         rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
     841                 :       13394 :     return strp;
     842                 :             : }
     843                 :             : 
     844                 :             : /*
     845                 :             :  * Given a year, a rule, and the offset from UT at the time that rule takes
     846                 :             :  * effect, calculate the year-relative time that rule takes effect.
     847                 :             :  */
     848                 :             : 
     849                 :             : static int_fast32_t
     850                 :     5384388 : transtime(const int year, const struct rule *const rulep,
     851                 :             :           const int_fast32_t offset)
     852                 :             : {
     853                 :             :     bool        leapyear;
     854                 :             :     int_fast32_t value;
     855                 :             :     int         i;
     856                 :             :     int         d,
     857                 :             :                 m1,
     858                 :             :                 yy0,
     859                 :             :                 yy1,
     860                 :             :                 yy2,
     861                 :             :                 dow;
     862                 :             : 
     863   [ +  +  +  +  :     5384388 :     leapyear = isleap(year);
                   +  + ]
     864   [ -  -  +  - ]:     5384388 :     switch (rulep->r_type)
     865                 :             :     {
     866                 :             : 
     867                 :           0 :         case JULIAN_DAY:
     868                 :             : 
     869                 :             :             /*
     870                 :             :              * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
     871                 :             :              * years. In non-leap years, or if the day number is 59 or less,
     872                 :             :              * just add SECSPERDAY times the day number-1 to the time of
     873                 :             :              * January 1, midnight, to get the day.
     874                 :             :              */
     875                 :           0 :             value = (rulep->r_day - 1) * SECSPERDAY;
     876   [ #  #  #  # ]:           0 :             if (leapyear && rulep->r_day >= 60)
     877                 :           0 :                 value += SECSPERDAY;
     878                 :           0 :             break;
     879                 :             : 
     880                 :           0 :         case DAY_OF_YEAR:
     881                 :             : 
     882                 :             :             /*
     883                 :             :              * n - day of year. Just add SECSPERDAY times the day number to
     884                 :             :              * the time of January 1, midnight, to get the day.
     885                 :             :              */
     886                 :           0 :             value = rulep->r_day * SECSPERDAY;
     887                 :           0 :             break;
     888                 :             : 
     889                 :     5384388 :         case MONTH_NTH_DAY_OF_WEEK:
     890                 :             : 
     891                 :             :             /*
     892                 :             :              * Mm.n.d - nth "dth day" of month m.
     893                 :             :              */
     894                 :             : 
     895                 :             :             /*
     896                 :             :              * Use Zeller's Congruence to get day-of-week of first day of
     897                 :             :              * month.
     898                 :             :              */
     899                 :     5384388 :             m1 = (rulep->r_mon + 9) % 12 + 1;
     900         [ -  + ]:     5384388 :             yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
     901                 :     5384388 :             yy1 = yy0 / 100;
     902                 :     5384388 :             yy2 = yy0 % 100;
     903                 :     5384388 :             dow = ((26 * m1 - 2) / 10 +
     904                 :     5384388 :                    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
     905         [ +  + ]:     5384388 :             if (dow < 0)
     906                 :      970123 :                 dow += DAYSPERWEEK;
     907                 :             : 
     908                 :             :             /*
     909                 :             :              * "dow" is the day-of-week of the first day of the month. Get the
     910                 :             :              * day-of-month (zero-origin) of the first "dow" day of the month.
     911                 :             :              */
     912                 :     5384388 :             d = rulep->r_day - dow;
     913         [ +  + ]:     5384388 :             if (d < 0)
     914                 :     4549985 :                 d += DAYSPERWEEK;
     915         [ +  + ]:    10068750 :             for (i = 1; i < rulep->r_week; ++i)
     916                 :             :             {
     917                 :     5085702 :                 if (d + DAYSPERWEEK >=
     918         [ +  + ]:     5085702 :                     mon_lengths[leapyear][rulep->r_mon - 1])
     919                 :      401340 :                     break;
     920                 :     4684362 :                 d += DAYSPERWEEK;
     921                 :             :             }
     922                 :             : 
     923                 :             :             /*
     924                 :             :              * "d" is the day-of-month (zero-origin) of the day we want.
     925                 :             :              */
     926                 :     5384388 :             value = d * SECSPERDAY;
     927         [ +  + ]:    37307610 :             for (i = 0; i < rulep->r_mon - 1; ++i)
     928                 :    31923222 :                 value += mon_lengths[leapyear][i] * SECSPERDAY;
     929                 :     5384388 :             break;
     930                 :             : 
     931                 :           0 :         default:
     932                 :           0 :             unreachable();
     933                 :             :     }
     934                 :             : 
     935                 :             :     /*
     936                 :             :      * "value" is the year-relative time of 00:00:00 UT on the day in
     937                 :             :      * question. To get the year-relative time of the specified local time on
     938                 :             :      * that day, add the transition time and the current offset from UT.
     939                 :             :      */
     940                 :     5384388 :     return value + rulep->r_time + offset;
     941                 :             : }
     942                 :             : 
     943                 :             : /*
     944                 :             :  * Given a POSIX.1 proleptic TZ string, fill in the rule tables as
     945                 :             :  * appropriate.
     946                 :             :  */
     947                 :             : 
     948                 :             : static bool
     949                 :       13813 : tzparse(const char *name, struct state *sp, struct state const *basep)
     950                 :             : {
     951                 :             :     const char *stdname;
     952                 :       13813 :     const char *dstname = NULL;
     953                 :             :     int_fast32_t stdoffset;
     954                 :             :     int_fast32_t dstoffset;
     955                 :             :     char       *cp;
     956                 :             :     ptrdiff_t   stdlen,
     957                 :             :                 dstlen,
     958                 :             :                 charcnt;
     959                 :       13813 :     pg_time_t   atlo = TIME_T_MIN,
     960                 :       13813 :                 leaplo = TIME_T_MIN;
     961                 :             : 
     962                 :       13813 :     stdname = name;
     963         [ +  + ]:       13813 :     if (*name == '<')
     964                 :             :     {
     965                 :        2509 :         name++;
     966                 :        2509 :         stdname = name;
     967                 :        2509 :         name = getqzname(name, '>');
     968         [ -  + ]:        2509 :         if (*name != '>')
     969                 :           0 :             return false;
     970                 :        2509 :         stdlen = name - stdname;
     971                 :        2509 :         name++;
     972                 :             :     }
     973                 :             :     else
     974                 :             :     {
     975                 :       11304 :         name = getzname(name);
     976                 :       11304 :         stdlen = name - stdname;
     977                 :             :     }
     978         [ -  + ]:       13813 :     if (stdlen > TZNAME_MAXIMUM) /* allow empty STD abbrev, unlike IANA */
     979                 :           0 :         return false;
     980                 :       13813 :     name = getoffset(name, &stdoffset);
     981         [ +  + ]:       13813 :     if (name == NULL)
     982                 :          68 :         return false;
     983                 :       13745 :     charcnt = stdlen + 1;
     984         [ +  + ]:       13745 :     if (basep)
     985                 :             :     {
     986         [ +  + ]:       12015 :         if (0 < basep->timecnt)
     987                 :       10405 :             atlo = basep->ats[basep->timecnt - 1];
     988                 :       12015 :         set_leapcount(sp, leapcount(basep));
     989         [ -  + ]:       12015 :         if (0 < leapcount(sp))
     990                 :             :         {
     991                 :             :             int         i;
     992                 :             : 
     993         [ #  # ]:           0 :             for (i = 0; i < leapcount(sp); i++)
     994                 :           0 :                 set_lsinfo(sp, i, lsinfo(basep, i));
     995                 :           0 :             leaplo = lsinfo(sp, leapcount(sp) - 1).ls_trans;
     996                 :             :         }
     997                 :             :     }
     998                 :             :     else
     999                 :        1730 :         set_leapcount(sp, 0);   /* So, we're off a little.  */
    1000                 :       13745 :     sp->goback = sp->goahead = false;
    1001         [ +  + ]:       13745 :     if (*name != '\0')
    1002                 :             :     {
    1003                 :             :         struct rule start,
    1004                 :             :                     end;
    1005                 :             :         int         year,
    1006                 :             :                     yearbeg,
    1007                 :             :                     yearlim,
    1008                 :             :                     timecnt;
    1009                 :             :         pg_time_t   janfirst;
    1010                 :        6697 :         int_fast32_t janoffset = 0;
    1011                 :             : 
    1012         [ +  + ]:        6697 :         if (*name == '<')
    1013                 :             :         {
    1014                 :         162 :             dstname = ++name;
    1015                 :         162 :             name = getqzname(name, '>');
    1016         [ -  + ]:         162 :             if (*name != '>')
    1017                 :           0 :                 return false;
    1018                 :         162 :             dstlen = name - dstname;
    1019                 :         162 :             name++;
    1020                 :             :         }
    1021                 :             :         else
    1022                 :             :         {
    1023                 :        6535 :             dstname = name;
    1024                 :        6535 :             name = getzname(name);
    1025                 :        6535 :             dstlen = name - dstname;    /* length of DST abbr. */
    1026                 :             :         }
    1027   [ +  -  -  + ]:        6697 :         if (!(0 < dstlen && dstlen <= TZNAME_MAXIMUM))
    1028                 :           0 :             return false;
    1029                 :        6697 :         charcnt += dstlen + 1;
    1030   [ +  +  +  +  :        6697 :         if (*name != '\0' && *name != ',' && *name != ';')
                   +  - ]
    1031                 :             :         {
    1032                 :          54 :             name = getoffset(name, &dstoffset);
    1033         [ -  + ]:          54 :             if (name == NULL)
    1034                 :           0 :                 return false;
    1035                 :             :         }
    1036                 :             :         else
    1037                 :        6643 :             dstoffset = stdoffset - SECSPERHOUR;
    1038                 :             : 
    1039         [ +  + ]:        6697 :         if (*name == '\0')
    1040                 :           4 :             name = TZDEFRULESTRING;
    1041   [ -  +  -  - ]:        6697 :         if (!(*name == ',' || *name == ';'))
    1042                 :           0 :             return false;
    1043                 :             : 
    1044                 :        6697 :         name = getrule(name + 1, &start);
    1045         [ -  + ]:        6697 :         if (!name)
    1046                 :           0 :             return false;
    1047         [ -  + ]:        6697 :         if (*name++ != ',')
    1048                 :           0 :             return false;
    1049                 :        6697 :         name = getrule(name, &end);
    1050   [ +  -  -  + ]:        6697 :         if (!name || *name)
    1051                 :           0 :             return false;
    1052                 :        6697 :         sp->typecnt = 2;     /* standard time and DST */
    1053                 :             : 
    1054                 :             :         /*
    1055                 :             :          * Two transitions per year, from EPOCH_YEAR forward.
    1056                 :             :          */
    1057                 :        6697 :         init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
    1058                 :        6697 :         init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
    1059                 :        6697 :         timecnt = 0;
    1060                 :        6697 :         janfirst = 0;
    1061                 :        6697 :         yearbeg = EPOCH_YEAR;
    1062                 :             : 
    1063                 :             :         do
    1064                 :             :         {
    1065                 :        9284 :             int_fast32_t yearsecs
    1066   [ +  +  +  +  :        9284 :             = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
                   -  + ]
    1067                 :        9284 :             pg_time_t   janfirst1 = janfirst;
    1068                 :             : 
    1069                 :        9284 :             yearbeg--;
    1070         [ -  + ]:        9284 :             if (increment_overflow_time(&janfirst1, -yearsecs))
    1071                 :             :             {
    1072                 :           0 :                 janoffset = -yearsecs;
    1073                 :           0 :                 break;
    1074                 :             :             }
    1075                 :        9284 :             janfirst = janfirst1;
    1076                 :        9284 :         } while (atlo < janfirst
    1077   [ +  +  +  + ]:        9284 :                  && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
    1078                 :             : 
    1079                 :             :         while (true)
    1080                 :      251185 :         {
    1081                 :      257882 :             int_fast32_t yearsecs
    1082   [ +  +  +  +  :      257882 :             = year_lengths[isleap(yearbeg)] * SECSPERDAY;
                   +  - ]
    1083                 :      257882 :             int         yearbeg1 = yearbeg;
    1084                 :      257882 :             pg_time_t   janfirst1 = janfirst;
    1085                 :             : 
    1086         [ +  - ]:      257882 :             if (increment_overflow_time(&janfirst1, yearsecs)
    1087         [ +  - ]:      257882 :                 || increment_overflow(&yearbeg1, 1)
    1088         [ +  + ]:      257882 :                 || atlo <= janfirst1)
    1089                 :             :                 break;
    1090                 :      251185 :             yearbeg = yearbeg1;
    1091                 :      251185 :             janfirst = janfirst1;
    1092                 :             :         }
    1093                 :             : 
    1094                 :        6697 :         yearlim = yearbeg;
    1095         [ -  + ]:        6697 :         if (increment_overflow(&yearlim, years_of_observations))
    1096                 :           0 :             yearlim = INT_MAX;
    1097         [ +  + ]:     2698891 :         for (year = yearbeg; year < yearlim; year++)
    1098                 :             :         {
    1099                 :             :             int_fast32_t
    1100                 :     2692194 :                         starttime = transtime(year, &start, stdoffset),
    1101                 :     2692194 :                         endtime = transtime(year, &end, dstoffset),
    1102   [ +  +  +  +  :     2692194 :                         yearsecs = year_lengths[isleap(year)] * SECSPERDAY;
                   +  + ]
    1103                 :     2692194 :             bool        reversed = endtime < starttime;
    1104                 :             : 
    1105         [ +  + ]:     2692194 :             if (reversed)
    1106                 :             :             {
    1107                 :      123012 :                 int_fast32_t swap = starttime;
    1108                 :             : 
    1109                 :      123012 :                 starttime = endtime;
    1110                 :      123012 :                 endtime = swap;
    1111                 :             :             }
    1112         [ +  + ]:     2692194 :             if (reversed
    1113         [ +  - ]:     2569182 :                 || (starttime < endtime
    1114         [ +  - ]:     2569182 :                     && endtime - starttime < yearsecs))
    1115                 :             :             {
    1116         [ -  + ]:     2692194 :                 if (TZ_MAX_TIMES - 2 < timecnt)
    1117                 :           0 :                     break;
    1118                 :     2692194 :                 sp->ats[timecnt] = janfirst;
    1119         [ +  - ]:     2692194 :                 if (!increment_overflow_time(&sp->ats[timecnt],
    1120                 :             :                                              janoffset + starttime)
    1121         [ +  + ]:     2692194 :                     && atlo <= sp->ats[timecnt])
    1122                 :     2691736 :                     sp->types[timecnt++] = !reversed;
    1123                 :     2692194 :                 sp->ats[timecnt] = janfirst;
    1124         [ +  - ]:     2692194 :                 if (!increment_overflow_time(&sp->ats[timecnt],
    1125                 :             :                                              janoffset + endtime)
    1126         [ +  + ]:     2692194 :                     && atlo <= sp->ats[timecnt])
    1127                 :             :                 {
    1128                 :     2692006 :                     sp->types[timecnt++] = reversed;
    1129                 :             :                 }
    1130                 :             :             }
    1131         [ -  + ]:     2692194 :             if (endtime < leaplo)
    1132                 :             :             {
    1133                 :           0 :                 yearlim = year;
    1134         [ #  # ]:           0 :                 if (increment_overflow(&yearlim, years_of_observations))
    1135                 :           0 :                     yearlim = INT_MAX;
    1136                 :             :             }
    1137         [ -  + ]:     2692194 :             if (increment_overflow_time(&janfirst, janoffset + yearsecs))
    1138                 :           0 :                 break;
    1139                 :     2692194 :             janoffset = 0;
    1140                 :             :         }
    1141                 :        6697 :         sp->timecnt = timecnt;
    1142         [ -  + ]:        6697 :         if (!timecnt)
    1143                 :             :         {
    1144                 :           0 :             sp->ttis[0] = sp->ttis[1];
    1145                 :           0 :             sp->typecnt = 1; /* Perpetual DST.  */
    1146                 :             :         }
    1147         [ +  - ]:        6697 :         else if (years_of_observations <= year - yearbeg)
    1148                 :        6697 :             sp->goback = sp->goahead = true;
    1149                 :             :     }
    1150                 :             :     else
    1151                 :             :     {
    1152                 :        7048 :         dstlen = 0;
    1153                 :        7048 :         sp->typecnt = 1;     /* only standard time */
    1154                 :        7048 :         sp->timecnt = 0;
    1155                 :        7048 :         init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
    1156                 :             :     }
    1157                 :       13745 :     sp->charcnt = charcnt;
    1158                 :       13745 :     cp = sp->chars;
    1159                 :       13745 :     memcpy(cp, stdname, stdlen);
    1160                 :       13745 :     cp += stdlen;
    1161                 :       13745 :     *cp++ = '\0';
    1162         [ +  + ]:       13745 :     if (dstlen != 0)
    1163                 :             :     {
    1164                 :        6697 :         memcpy(cp, dstname, dstlen);
    1165                 :        6697 :         cp += dstlen;
    1166                 :        6697 :         *cp = '\0';
    1167                 :             :     }
    1168                 :       13745 :     return true;
    1169                 :             : }
    1170                 :             : 
    1171                 :             : static void
    1172                 :        1509 : gmtload(struct state *const sp)
    1173                 :             : {
    1174                 :             :     /* PG: for historical compatibility, use "GMT" not "UTC" as TZ abbrev */
    1175                 :        1509 :     tzparse("GMT0", sp, NULL);
    1176                 :        1509 : }
    1177                 :             : 
    1178                 :             : 
    1179                 :             : /*
    1180                 :             :  * The easy way to behave "as if no library function calls" localtime
    1181                 :             :  * is to not call it, so we drop its guts into "localsub", which can be
    1182                 :             :  * freely called. (And no, the PANS doesn't require the above behavior,
    1183                 :             :  * but it *is* desirable.)
    1184                 :             :  */
    1185                 :             : static struct pg_tm *
    1186                 :     1393051 : localsub(struct state const *sp, pg_time_t const *timep,
    1187                 :             :          struct pg_tm *const tmp)
    1188                 :             : {
    1189                 :             :     const struct ttinfo *ttisp;
    1190                 :             :     int         i;
    1191                 :             :     struct pg_tm *result;
    1192                 :     1393051 :     const pg_time_t t = *timep;
    1193                 :             : 
    1194         [ -  + ]:     1393051 :     if (sp == NULL)
    1195                 :           0 :         return gmtsub(timep, 0, tmp);
    1196   [ +  +  +  - ]:     1393051 :     if ((sp->goback && t < sp->ats[0]) ||
    1197   [ +  +  +  + ]:     1393051 :         (sp->goahead && t > sp->ats[sp->timecnt - 1]))
    1198                 :             :     {
    1199                 :             :         pg_time_t   newt;
    1200                 :             :         pg_time_t   seconds;
    1201                 :             :         pg_time_t   years;
    1202                 :             : 
    1203         [ -  + ]:          44 :         if (t < sp->ats[0])
    1204                 :           0 :             seconds = sp->ats[0] - t;
    1205                 :             :         else
    1206                 :          44 :             seconds = t - sp->ats[sp->timecnt - 1];
    1207                 :          44 :         --seconds;
    1208                 :             : 
    1209                 :             :         /*
    1210                 :             :          * Beware integer overflow, as SECONDS might be close to the maximum
    1211                 :             :          * pg_time_t.
    1212                 :             :          */
    1213                 :          44 :         years = seconds / SECSPERREPEAT * YEARSPERREPEAT;
    1214                 :          44 :         seconds = years * AVGSECSPERYEAR;
    1215                 :          44 :         years += YEARSPERREPEAT;
    1216         [ -  + ]:          44 :         if (t < sp->ats[0])
    1217                 :           0 :             newt = t + seconds + SECSPERREPEAT;
    1218                 :             :         else
    1219                 :          44 :             newt = t - seconds - SECSPERREPEAT;
    1220                 :             : 
    1221         [ +  - ]:          44 :         if (newt < sp->ats[0] ||
    1222         [ -  + ]:          44 :             newt > sp->ats[sp->timecnt - 1])
    1223                 :           0 :             return NULL;        /* "cannot happen" */
    1224                 :          44 :         result = localsub(sp, &newt, tmp);
    1225         [ +  - ]:          44 :         if (result)
    1226                 :             :         {
    1227                 :             : #if defined ckd_add && defined ckd_sub
    1228   [ -  +  -  + ]:          88 :             if (t < sp->ats[0]
    1229                 :           0 :                 ? ckd_sub(&result->tm_year,
    1230                 :             :                           result->tm_year, years)
    1231                 :          44 :                 : ckd_add(&result->tm_year,
    1232                 :             :                           result->tm_year, years))
    1233                 :           0 :                 return NULL;
    1234                 :             : #else
    1235                 :             :             int_fast64_t newy;
    1236                 :             : 
    1237                 :             :             newy = result->tm_year;
    1238                 :             :             if (t < sp->ats[0])
    1239                 :             :                 newy -= years;
    1240                 :             :             else
    1241                 :             :                 newy += years;
    1242                 :             :             if (!(INT_MIN <= newy && newy <= INT_MAX))
    1243                 :             :                 return NULL;
    1244                 :             :             result->tm_year = newy;
    1245                 :             : #endif
    1246                 :             :         }
    1247                 :          44 :         return result;
    1248                 :             :     }
    1249   [ +  +  +  + ]:     1393007 :     if (sp->timecnt == 0 || t < sp->ats[0])
    1250                 :             :     {
    1251                 :     1312960 :         i = 0;
    1252                 :             :     }
    1253                 :             :     else
    1254                 :             :     {
    1255                 :       80047 :         int         lo = 1;
    1256                 :       80047 :         int         hi = sp->timecnt;
    1257                 :             : 
    1258         [ +  + ]:      825992 :         while (lo < hi)
    1259                 :             :         {
    1260                 :      745945 :             int         mid = (lo + hi) >> 1;
    1261                 :             : 
    1262         [ +  + ]:      745945 :             if (t < sp->ats[mid])
    1263                 :      432322 :                 hi = mid;
    1264                 :             :             else
    1265                 :      313623 :                 lo = mid + 1;
    1266                 :             :         }
    1267                 :       80047 :         i = sp->types[lo - 1];
    1268                 :             :     }
    1269                 :     1393007 :     ttisp = &sp->ttis[i];
    1270                 :             : 
    1271                 :             :     /*
    1272                 :             :      * To get (wrong) behavior that's compatible with System V Release 2.0
    1273                 :             :      * you'd replace the statement below with t += ttisp->tt_utoff;
    1274                 :             :      * timesub(&t, 0, sp, tmp);
    1275                 :             :      */
    1276                 :     1393007 :     result = timesub(&t, ttisp->tt_utoff, sp, tmp);
    1277         [ +  - ]:     1393007 :     if (result)
    1278                 :             :     {
    1279                 :     1393007 :         result->tm_isdst = ttisp->tt_isdst;
    1280                 :             : #ifdef TM_ZONE
    1281                 :     1393007 :         result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]);
    1282                 :             : #endif
    1283                 :             :     }
    1284                 :     1393007 :     return result;
    1285                 :             : }
    1286                 :             : 
    1287                 :             : 
    1288                 :             : struct pg_tm *
    1289                 :     1393007 : pg_localtime(const pg_time_t *timep, const pg_tz *tz)
    1290                 :             : {
    1291                 :     1393007 :     return localsub(&tz->state, timep, &tm);
    1292                 :             : }
    1293                 :             : 
    1294                 :             : 
    1295                 :             : /*
    1296                 :             :  * gmtsub is to gmtime as localsub is to localtime.
    1297                 :             :  *
    1298                 :             :  * PG: except we have a private "struct state" for GMT, so no sp is passed in.
    1299                 :             :  */
    1300                 :             : 
    1301                 :             : static struct pg_tm *
    1302                 :      200833 : gmtsub(pg_time_t const *timep,
    1303                 :             :        int_fast32_t offset, struct pg_tm *tmp)
    1304                 :             : {
    1305                 :             :     struct pg_tm *result;
    1306                 :             : 
    1307                 :             :     /* GMT timezone state data is kept here */
    1308                 :             :     static struct state *gmtptr = NULL;
    1309                 :             : 
    1310         [ +  + ]:      200833 :     if (gmtptr == NULL)
    1311                 :             :     {
    1312                 :             :         /* Allocate on first use */
    1313                 :         208 :         gmtptr = (struct state *) malloc(sizeof(struct state));
    1314         [ -  + ]:         208 :         if (gmtptr == NULL)
    1315                 :           0 :             return NULL;        /* errno should be set by malloc */
    1316                 :         208 :         gmtload(gmtptr);
    1317                 :             :     }
    1318                 :             : 
    1319                 :      200833 :     result = timesub(timep, offset, gmtptr, tmp);
    1320                 :             : #ifdef TM_ZONE
    1321                 :             : 
    1322                 :             :     /*
    1323                 :             :      * Could get fancy here and deliver something such as "+xx" or "-xx" if
    1324                 :             :      * offset is non-zero, but this is no time for a treasure hunt.
    1325                 :             :      */
    1326         [ +  - ]:      200833 :     tmp->TM_ZONE = UNCONST(offset ? wildabbr
    1327                 :             :                            : gmtptr->chars);
    1328                 :             : #endif                          /* defined TM_ZONE */
    1329                 :      200833 :     return result;
    1330                 :             : }
    1331                 :             : 
    1332                 :             : struct pg_tm *
    1333                 :      200833 : pg_gmtime(const pg_time_t *timep)
    1334                 :             : {
    1335                 :      200833 :     return gmtsub(timep, 0, &tm);
    1336                 :             : }
    1337                 :             : 
    1338                 :             : /*
    1339                 :             :  * Return the number of leap years through the end of the given year
    1340                 :             :  * where, to make the math easy, the answer for year zero is defined as zero.
    1341                 :             :  */
    1342                 :             : 
    1343                 :             : static pg_time_t
    1344                 :     6345998 : leaps_thru_end_of_nonneg(pg_time_t y)
    1345                 :             : {
    1346                 :     6345998 :     return y / 4 - y / 100 + y / 400;
    1347                 :             : }
    1348                 :             : 
    1349                 :             : static pg_time_t
    1350                 :     6345998 : leaps_thru_end_of(pg_time_t y)
    1351                 :             : {
    1352                 :             :     return (y < 0
    1353                 :        1496 :             ? -1 - leaps_thru_end_of_nonneg(-1 - y)
    1354         [ +  + ]:     6347494 :             : leaps_thru_end_of_nonneg(y));
    1355                 :             : }
    1356                 :             : 
    1357                 :             : static struct pg_tm *
    1358                 :     1593840 : timesub(const pg_time_t *timep, int_fast32_t offset,
    1359                 :             :         const struct state *sp, struct pg_tm *tmp)
    1360                 :             : {
    1361                 :             :     pg_time_t   tdays;
    1362                 :             :     const int  *ip;
    1363                 :             :     int_fast32_2s corr;
    1364                 :             :     int         i;
    1365                 :             :     int_fast32_t idays,
    1366                 :             :                 rem,
    1367                 :             :                 dayoff,
    1368                 :             :                 dayrem;
    1369                 :             :     pg_time_t   y;
    1370                 :             : 
    1371                 :             :     /*
    1372                 :             :      * If less than SECSPERMIN, the number of seconds since the most recent
    1373                 :             :      * positive leap second; otherwise, do not add 1 to localtime tm_sec
    1374                 :             :      * because of leap seconds.
    1375                 :             :      */
    1376                 :     1593840 :     pg_time_t   secs_since_posleap = SECSPERMIN;
    1377                 :             : 
    1378                 :     1593840 :     corr = 0;
    1379         [ +  - ]:     1593840 :     i = sp ? leapcount(sp) : 0;
    1380         [ -  + ]:     1593840 :     while (--i >= 0)
    1381                 :             :     {
    1382                 :           0 :         struct lsinfo ls = lsinfo(sp, i);
    1383                 :             : 
    1384         [ #  # ]:           0 :         if (ls.ls_trans <= *timep)
    1385                 :             :         {
    1386                 :           0 :             corr = ls.ls_corr;
    1387   [ #  #  #  # ]:           0 :             if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr)
    1388                 :           0 :                 secs_since_posleap = *timep - ls.ls_trans;
    1389                 :           0 :             break;
    1390                 :             :         }
    1391                 :             :     }
    1392                 :             : 
    1393                 :             :     /*
    1394                 :             :      * Calculate the year, avoiding integer overflow even if pg_time_t is
    1395                 :             :      * unsigned.
    1396                 :             :      */
    1397                 :     1593840 :     tdays = *timep / SECSPERDAY;
    1398                 :     1593840 :     rem = *timep % SECSPERDAY;
    1399                 :     1593840 :     rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
    1400                 :     1593840 :     dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
    1401                 :     1593840 :     rem %= SECSPERDAY;
    1402                 :             : 
    1403                 :             :     /*
    1404                 :             :      * y = (EPOCH_YEAR + floor((tdays + dayoff) / DAYSPERREPEAT) *
    1405                 :             :      * YEARSPERREPEAT), sans overflow.  But calculate against 1570 (EPOCH_YEAR
    1406                 :             :      * - YEARSPERREPEAT) instead of against 1970 so that things work for
    1407                 :             :      * localtime values before 1970 when pg_time_t is unsigned.
    1408                 :             :      */
    1409                 :     1593840 :     dayrem = tdays % DAYSPERREPEAT;
    1410                 :     1593840 :     dayrem += dayoff % DAYSPERREPEAT;
    1411                 :     1593840 :     y = (EPOCH_YEAR - YEARSPERREPEAT
    1412                 :     1593840 :          + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
    1413                 :     1593840 :              - ((dayrem % DAYSPERREPEAT) < 0)
    1414                 :     1593840 :              + tdays / DAYSPERREPEAT)
    1415                 :             :             * YEARSPERREPEAT));
    1416                 :             :     /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow.  */
    1417                 :     1593840 :     idays = tdays % DAYSPERREPEAT;
    1418                 :     1593840 :     idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
    1419                 :     1593840 :     idays %= DAYSPERREPEAT;
    1420                 :             :     /* Increase Y and decrease IDAYS until IDAYS is in range for Y.  */
    1421   [ +  +  +  +  :     3172999 :     while (year_lengths[isleap(y)] <= idays)
             +  +  +  + ]
    1422                 :             :     {
    1423                 :     1579159 :         int         tdelta = idays / DAYSPERLYEAR;
    1424                 :     1579159 :         int_fast32_t ydelta = tdelta + !tdelta;
    1425                 :     1579159 :         pg_time_t   newy = y + ydelta;
    1426                 :             :         int         leapdays;
    1427                 :             : 
    1428                 :     1579159 :         leapdays = leaps_thru_end_of(newy - 1) -
    1429                 :     1579159 :             leaps_thru_end_of(y - 1);
    1430                 :     1579159 :         idays -= ydelta * DAYSPERNYEAR;
    1431                 :     1579159 :         idays -= leapdays;
    1432                 :     1579159 :         y = newy;
    1433                 :             :     }
    1434                 :             : 
    1435                 :             : #ifdef ckd_add
    1436         [ -  + ]:     1593840 :     if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE))
    1437                 :             :     {
    1438                 :           0 :         errno = EOVERFLOW;
    1439                 :           0 :         return NULL;
    1440                 :             :     }
    1441                 :             : #else
    1442                 :             :     if (!TYPE_SIGNED(pg_time_t) && y < TM_YEAR_BASE)
    1443                 :             :     {
    1444                 :             :         int         signed_y = y;
    1445                 :             : 
    1446                 :             :         tmp->tm_year = signed_y - TM_YEAR_BASE;
    1447                 :             :     }
    1448                 :             :     else if ((!TYPE_SIGNED(pg_time_t) || INT_MIN + TM_YEAR_BASE <= y)
    1449                 :             :              && y - TM_YEAR_BASE <= INT_MAX)
    1450                 :             :         tmp->tm_year = y - TM_YEAR_BASE;
    1451                 :             :     else
    1452                 :             :     {
    1453                 :             :         errno = EOVERFLOW;
    1454                 :             :         return NULL;
    1455                 :             :     }
    1456                 :             : #endif
    1457                 :     1593840 :     tmp->tm_yday = idays;
    1458                 :             : 
    1459                 :             :     /*
    1460                 :             :      * The "extra" mods below avoid overflow problems.
    1461                 :             :      */
    1462                 :     1593840 :     tmp->tm_wday = (TM_WDAY_BASE
    1463                 :     1593840 :                     + ((tmp->tm_year % DAYSPERWEEK)
    1464                 :     1593840 :                        * (DAYSPERNYEAR % DAYSPERWEEK))
    1465                 :     1593840 :                     + leaps_thru_end_of(y - 1)
    1466                 :     1593840 :                     - leaps_thru_end_of(TM_YEAR_BASE - 1)
    1467                 :     1593840 :                     + idays);
    1468                 :     1593840 :     tmp->tm_wday %= DAYSPERWEEK;
    1469         [ +  + ]:     1593840 :     if (tmp->tm_wday < 0)
    1470                 :        1093 :         tmp->tm_wday += DAYSPERWEEK;
    1471                 :     1593840 :     tmp->tm_hour = rem / SECSPERHOUR;
    1472                 :     1593840 :     rem %= SECSPERHOUR;
    1473                 :     1593840 :     tmp->tm_min = rem / SECSPERMIN;
    1474                 :     1593840 :     tmp->tm_sec = rem % SECSPERMIN;
    1475                 :             : 
    1476                 :             :     /*
    1477                 :             :      * Use "... ??:??:60" at the end of the localtime minute containing the
    1478                 :             :      * second just before the positive leap second.
    1479                 :             :      */
    1480                 :     1593840 :     tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
    1481                 :             : 
    1482   [ +  +  +  +  :     1593840 :     ip = mon_lengths[isleap(y)];
                   +  + ]
    1483         [ +  + ]:    10750176 :     for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
    1484                 :     9156336 :         idays -= ip[tmp->tm_mon];
    1485                 :     1593840 :     tmp->tm_mday = idays + 1;
    1486                 :     1593840 :     tmp->tm_isdst = 0;
    1487                 :             : #ifdef TM_GMTOFF
    1488                 :     1593840 :     tmp->TM_GMTOFF = offset;
    1489                 :             : #endif                          /* defined TM_GMTOFF */
    1490                 :     1593840 :     return tmp;
    1491                 :             : }
    1492                 :             : 
    1493                 :             : /*
    1494                 :             :  * Adapted from code provided by Robert Elz, who writes:
    1495                 :             :  *  The "best" way to do mktime I think is based on an idea of Bob
    1496                 :             :  *  Kridle's (so its said...) from a long time ago.
    1497                 :             :  *  It does a binary search of the pg_time_t space. Since pg_time_t's are
    1498                 :             :  *  just 32 bits, its a max of 32 iterations (even at 64 bits it
    1499                 :             :  *  would still be very reasonable).
    1500                 :             :  */
    1501                 :             : 
    1502                 :             : #ifndef WRONG
    1503                 :             : #define WRONG (-1)
    1504                 :             : #endif                          /* !defined WRONG */
    1505                 :             : 
    1506                 :             : /*
    1507                 :             :  * Normalize logic courtesy Paul Eggert.
    1508                 :             :  */
    1509                 :             : 
    1510                 :             : static bool
    1511                 :      264579 : increment_overflow(int *ip, int j)
    1512                 :             : {
    1513                 :             : #ifdef ckd_add
    1514                 :      264579 :     return ckd_add(ip, *ip, j);
    1515                 :             : #else
    1516                 :             :     int const   i = *ip;
    1517                 :             : 
    1518                 :             :     /*----------
    1519                 :             :      * If i >= 0 there can only be overflow if i + j > INT_MAX
    1520                 :             :      * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
    1521                 :             :      * If i < 0 there can only be overflow if i + j < INT_MIN
    1522                 :             :      * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
    1523                 :             :      *----------
    1524                 :             :      */
    1525                 :             :     if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
    1526                 :             :         return true;
    1527                 :             :     *ip += j;
    1528                 :             :     return false;
    1529                 :             : #endif
    1530                 :             : }
    1531                 :             : 
    1532                 :             : static bool
    1533                 :    13717038 : increment_overflow_time(pg_time_t *tp, int_fast32_2s j)
    1534                 :             : {
    1535                 :             : #ifdef ckd_add
    1536                 :    13717038 :     return ckd_add(tp, *tp, j);
    1537                 :             : #else
    1538                 :             :     /*----------
    1539                 :             :      * This is like
    1540                 :             :      * 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
    1541                 :             :      * except that it does the right thing even if *tp + j would overflow.
    1542                 :             :      *----------
    1543                 :             :      */
    1544                 :             :     if (!(j < 0
    1545                 :             :           ? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
    1546                 :             :           : *tp <= TIME_T_MAX - j))
    1547                 :             :         return true;
    1548                 :             :     *tp += j;
    1549                 :             :     return false;
    1550                 :             : #endif
    1551                 :             : }
    1552                 :             : 
    1553                 :             : static int_fast32_2s
    1554                 :     5373290 : leapcorr(struct state const *sp, pg_time_t t)
    1555                 :             : {
    1556                 :             :     int         i;
    1557                 :             : 
    1558                 :     5373290 :     i = leapcount(sp);
    1559         [ -  + ]:     5373290 :     while (--i >= 0)
    1560                 :             :     {
    1561                 :           0 :         struct lsinfo ls = lsinfo(sp, i);
    1562                 :             : 
    1563         [ #  # ]:           0 :         if (ls.ls_trans <= t)
    1564                 :           0 :             return ls.ls_corr;
    1565                 :             :     }
    1566                 :     5373290 :     return 0;
    1567                 :             : }
    1568                 :             : 
    1569                 :             : /*
    1570                 :             :  * Postgres-specific functions begin here.
    1571                 :             :  */
    1572                 :             : 
    1573                 :             : /*
    1574                 :             :  * Load the definition of the given time zone name into *sp.
    1575                 :             :  * Return true if successful, false if not.
    1576                 :             :  * If "canonname" is not NULL, then on success the canonical spelling of
    1577                 :             :  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
    1578                 :             :  *
    1579                 :             :  * "GMT" is always interpreted as the gmtload() definition, without attempting
    1580                 :             :  * to load a definition from the filesystem.  This has a number of benefits:
    1581                 :             :  * 1. It's guaranteed to succeed, so we don't have the failure mode wherein
    1582                 :             :  * the bootstrap default timezone setting doesn't work (as could happen if
    1583                 :             :  * the OS attempts to supply a leap-second-aware version of "GMT").
    1584                 :             :  * 2. Because we aren't accessing the filesystem, we can safely initialize
    1585                 :             :  * the "GMT" zone definition before my_exec_path is known.
    1586                 :             :  * 3. It's quick enough that we don't waste much time when the bootstrap
    1587                 :             :  * default timezone setting is later overridden from postgresql.conf.
    1588                 :             :  */
    1589                 :             : bool
    1590                 :       13605 : pg_tzload(const char *name, char *canonname, struct state *sp)
    1591                 :             : {
    1592         [ +  + ]:       13605 :     if (strcmp(name, "GMT") == 0)
    1593                 :             :     {
    1594                 :        1301 :         gmtload(sp);
    1595                 :             :         /* Use given name as canonical */
    1596         [ +  + ]:        1301 :         if (canonname)
    1597                 :        1291 :             strcpy(canonname, name);
    1598                 :             :     }
    1599         [ +  + ]:       12304 :     else if (tzload(name, canonname, sp, TZLOAD_TZSTRING) != 0)
    1600                 :             :     {
    1601   [ +  -  +  + ]:         289 :         if (name[0] == ':' || !tzparse(name, sp, NULL))
    1602                 :             :         {
    1603                 :             :             /* Unknown timezone. Fail our call instead of loading GMT! */
    1604                 :          68 :             return false;
    1605                 :             :         }
    1606                 :             :         /* For POSIX timezone specs, use given name as canonical */
    1607         [ +  - ]:         221 :         if (canonname)
    1608                 :         221 :             strcpy(canonname, name);
    1609                 :             :     }
    1610                 :       13537 :     return true;
    1611                 :             : }
    1612                 :             : 
    1613                 :             : /*
    1614                 :             :  * Find the next DST transition time in the given zone after the given time
    1615                 :             :  *
    1616                 :             :  * *timep and *tz are input arguments, the other parameters are output values.
    1617                 :             :  *
    1618                 :             :  * When the function result is 1, *boundary is set to the pg_time_t
    1619                 :             :  * representation of the next DST transition time after *timep,
    1620                 :             :  * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
    1621                 :             :  * state prevailing just before that boundary (in particular, the state
    1622                 :             :  * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
    1623                 :             :  * the state prevailing just after that boundary.
    1624                 :             :  *
    1625                 :             :  * When the function result is 0, there is no known DST transition
    1626                 :             :  * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
    1627                 :             :  * offset and isdst state prevailing at *timep.  (This would occur in
    1628                 :             :  * DST-less time zones, or if a zone has permanently ceased using DST.)
    1629                 :             :  *
    1630                 :             :  * A function result of -1 indicates failure (this case does not actually
    1631                 :             :  * occur in our current implementation).
    1632                 :             :  */
    1633                 :             : int
    1634                 :      110386 : pg_next_dst_boundary(const pg_time_t *timep,
    1635                 :             :                      long int *before_gmtoff,
    1636                 :             :                      int *before_isdst,
    1637                 :             :                      pg_time_t *boundary,
    1638                 :             :                      long int *after_gmtoff,
    1639                 :             :                      int *after_isdst,
    1640                 :             :                      const pg_tz *tz)
    1641                 :             : {
    1642                 :             :     const struct state *sp;
    1643                 :             :     const struct ttinfo *ttisp;
    1644                 :             :     int         i;
    1645                 :             :     int         j;
    1646                 :      110386 :     const pg_time_t t = *timep;
    1647                 :             : 
    1648                 :      110386 :     sp = &tz->state;
    1649         [ +  + ]:      110386 :     if (sp->timecnt == 0)
    1650                 :             :     {
    1651                 :             :         /* non-DST zone, use the defaulttype (now always 0) */
    1652                 :        2631 :         ttisp = &sp->ttis[0];
    1653                 :        2631 :         *before_gmtoff = ttisp->tt_utoff;
    1654                 :        2631 :         *before_isdst = ttisp->tt_isdst;
    1655                 :        2631 :         return 0;
    1656                 :             :     }
    1657   [ +  +  +  - ]:      107755 :     if ((sp->goback && t < sp->ats[0]) ||
    1658   [ +  +  +  + ]:      107755 :         (sp->goahead && t > sp->ats[sp->timecnt - 1]))
    1659                 :             :     {
    1660                 :             :         /* For values outside the transition table, extrapolate */
    1661                 :       34052 :         pg_time_t   newt = t;
    1662                 :             :         pg_time_t   seconds;
    1663                 :             :         pg_time_t   tcycles;
    1664                 :             :         int64       icycles;
    1665                 :             :         int         result;
    1666                 :             : 
    1667         [ -  + ]:       34052 :         if (t < sp->ats[0])
    1668                 :           0 :             seconds = sp->ats[0] - t;
    1669                 :             :         else
    1670                 :       34052 :             seconds = t - sp->ats[sp->timecnt - 1];
    1671                 :       34052 :         --seconds;
    1672                 :       34052 :         tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
    1673                 :       34052 :         ++tcycles;
    1674                 :       34052 :         icycles = tcycles;
    1675   [ +  -  -  + ]:       34052 :         if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
    1676                 :           0 :             return -1;
    1677                 :       34052 :         seconds = icycles;
    1678                 :       34052 :         seconds *= YEARSPERREPEAT;
    1679                 :       34052 :         seconds *= AVGSECSPERYEAR;
    1680         [ -  + ]:       34052 :         if (t < sp->ats[0])
    1681                 :           0 :             newt += seconds;
    1682                 :             :         else
    1683                 :       34052 :             newt -= seconds;
    1684         [ +  - ]:       34052 :         if (newt < sp->ats[0] ||
    1685         [ -  + ]:       34052 :             newt > sp->ats[sp->timecnt - 1])
    1686                 :           0 :             return -1;          /* "cannot happen" */
    1687                 :             : 
    1688                 :       34052 :         result = pg_next_dst_boundary(&newt, before_gmtoff,
    1689                 :             :                                       before_isdst,
    1690                 :             :                                       boundary,
    1691                 :             :                                       after_gmtoff,
    1692                 :             :                                       after_isdst,
    1693                 :             :                                       tz);
    1694         [ -  + ]:       34052 :         if (t < sp->ats[0])
    1695                 :           0 :             *boundary -= seconds;
    1696                 :             :         else
    1697                 :       34052 :             *boundary += seconds;
    1698                 :       34052 :         return result;
    1699                 :             :     }
    1700                 :             : 
    1701         [ +  + ]:       73703 :     if (t >= sp->ats[sp->timecnt - 1])
    1702                 :             :     {
    1703                 :             :         /* No known transition > t, so use last known segment's type */
    1704                 :         720 :         i = sp->types[sp->timecnt - 1];
    1705                 :         720 :         ttisp = &sp->ttis[i];
    1706                 :         720 :         *before_gmtoff = ttisp->tt_utoff;
    1707                 :         720 :         *before_isdst = ttisp->tt_isdst;
    1708                 :         720 :         return 0;
    1709                 :             :     }
    1710         [ +  + ]:       72983 :     if (t < sp->ats[0])
    1711                 :             :     {
    1712                 :             :         /* For "before", use the defaulttype (now always 0) */
    1713                 :         380 :         ttisp = &sp->ttis[0];
    1714                 :         380 :         *before_gmtoff = ttisp->tt_utoff;
    1715                 :         380 :         *before_isdst = ttisp->tt_isdst;
    1716                 :         380 :         *boundary = sp->ats[0];
    1717                 :             :         /* And for "after", use the first segment's type */
    1718                 :         380 :         i = sp->types[0];
    1719                 :         380 :         ttisp = &sp->ttis[i];
    1720                 :         380 :         *after_gmtoff = ttisp->tt_utoff;
    1721                 :         380 :         *after_isdst = ttisp->tt_isdst;
    1722                 :         380 :         return 1;
    1723                 :             :     }
    1724                 :             :     /* Else search to find the boundary following t */
    1725                 :             :     {
    1726                 :       72603 :         int         lo = 1;
    1727                 :       72603 :         int         hi = sp->timecnt - 1;
    1728                 :             : 
    1729         [ +  + ]:      790392 :         while (lo < hi)
    1730                 :             :         {
    1731                 :      717789 :             int         mid = (lo + hi) >> 1;
    1732                 :             : 
    1733         [ +  + ]:      717789 :             if (t < sp->ats[mid])
    1734                 :      406879 :                 hi = mid;
    1735                 :             :             else
    1736                 :      310910 :                 lo = mid + 1;
    1737                 :             :         }
    1738                 :       72603 :         i = lo;
    1739                 :             :     }
    1740                 :       72603 :     j = sp->types[i - 1];
    1741                 :       72603 :     ttisp = &sp->ttis[j];
    1742                 :       72603 :     *before_gmtoff = ttisp->tt_utoff;
    1743                 :       72603 :     *before_isdst = ttisp->tt_isdst;
    1744                 :       72603 :     *boundary = sp->ats[i];
    1745                 :       72603 :     j = sp->types[i];
    1746                 :       72603 :     ttisp = &sp->ttis[j];
    1747                 :       72603 :     *after_gmtoff = ttisp->tt_utoff;
    1748                 :       72603 :     *after_isdst = ttisp->tt_isdst;
    1749                 :       72603 :     return 1;
    1750                 :             : }
    1751                 :             : 
    1752                 :             : /*
    1753                 :             :  * Identify a timezone abbreviation's meaning in the given zone
    1754                 :             :  *
    1755                 :             :  * Determine the GMT offset and DST flag associated with the abbreviation.
    1756                 :             :  * This is generally used only when the abbreviation has actually changed
    1757                 :             :  * meaning over time; therefore, we also take a UTC cutoff time, and return
    1758                 :             :  * the meaning in use at or most recently before that time, or the meaning
    1759                 :             :  * in first use after that time if the abbrev was never used before that.
    1760                 :             :  *
    1761                 :             :  * On success, returns true and sets *gmtoff and *isdst.  If the abbreviation
    1762                 :             :  * was never used at all in this zone, returns false.
    1763                 :             :  *
    1764                 :             :  * Note: abbrev is matched case-sensitively; it should be all-upper-case.
    1765                 :             :  */
    1766                 :             : bool
    1767                 :        1134 : pg_interpret_timezone_abbrev(const char *abbrev,
    1768                 :             :                              const pg_time_t *timep,
    1769                 :             :                              long int *gmtoff,
    1770                 :             :                              int *isdst,
    1771                 :             :                              const pg_tz *tz)
    1772                 :             : {
    1773                 :             :     const struct state *sp;
    1774                 :             :     const char *abbrs;
    1775                 :             :     const struct ttinfo *ttisp;
    1776                 :             :     int         abbrind;
    1777                 :             :     int         cutoff;
    1778                 :             :     int         i;
    1779                 :        1134 :     const pg_time_t t = *timep;
    1780                 :             : 
    1781                 :        1134 :     sp = &tz->state;
    1782                 :             : 
    1783                 :             :     /*
    1784                 :             :      * Locate the abbreviation in the zone's abbreviation list.  We assume
    1785                 :             :      * there are not duplicates in the list.
    1786                 :             :      */
    1787                 :        1134 :     abbrs = sp->chars;
    1788                 :        1134 :     abbrind = 0;
    1789         [ +  + ]:        5872 :     while (abbrind < sp->charcnt)
    1790                 :             :     {
    1791         [ +  + ]:        5092 :         if (strcmp(abbrev, abbrs + abbrind) == 0)
    1792                 :         354 :             break;
    1793         [ +  + ]:       19598 :         while (abbrs[abbrind] != '\0')
    1794                 :       14860 :             abbrind++;
    1795                 :        4738 :         abbrind++;
    1796                 :             :     }
    1797         [ +  + ]:        1134 :     if (abbrind >= sp->charcnt)
    1798                 :         780 :         return false;           /* not there! */
    1799                 :             : 
    1800                 :             :     /*
    1801                 :             :      * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
    1802                 :             :      * (goback/goahead zones).  Finding the newest or oldest meaning of the
    1803                 :             :      * abbreviation should get us what we want, since extrapolation would just
    1804                 :             :      * be repeating the newest or oldest meanings.
    1805                 :             :      *
    1806                 :             :      * Use binary search to locate the first transition > cutoff time.  (Note
    1807                 :             :      * that sp->timecnt could be zero, in which case this loop does nothing
    1808                 :             :      * and only the defaulttype entry will be checked.)
    1809                 :             :      */
    1810                 :             :     {
    1811                 :         354 :         int         lo = 0;
    1812                 :         354 :         int         hi = sp->timecnt;
    1813                 :             : 
    1814         [ +  + ]:        3038 :         while (lo < hi)
    1815                 :             :         {
    1816                 :        2684 :             int         mid = (lo + hi) >> 1;
    1817                 :             : 
    1818         [ +  + ]:        2684 :             if (t < sp->ats[mid])
    1819                 :         992 :                 hi = mid;
    1820                 :             :             else
    1821                 :        1692 :                 lo = mid + 1;
    1822                 :             :         }
    1823                 :         354 :         cutoff = lo;
    1824                 :             :     }
    1825                 :             : 
    1826                 :             :     /*
    1827                 :             :      * Scan backwards to find the latest interval using the given abbrev
    1828                 :             :      * before the cutoff time.
    1829                 :             :      */
    1830         [ +  + ]:       13710 :     for (i = cutoff - 1; i >= 0; i--)
    1831                 :             :     {
    1832                 :       13682 :         ttisp = &sp->ttis[sp->types[i]];
    1833         [ +  + ]:       13682 :         if (ttisp->tt_desigidx == abbrind)
    1834                 :             :         {
    1835                 :         326 :             *gmtoff = ttisp->tt_utoff;
    1836                 :         326 :             *isdst = ttisp->tt_isdst;
    1837                 :         326 :             return true;
    1838                 :             :         }
    1839                 :             :     }
    1840                 :             : 
    1841                 :             :     /*
    1842                 :             :      * Not found yet; check the defaulttype, which is notionally the era
    1843                 :             :      * before any of the entries in sp->types[].
    1844                 :             :      */
    1845                 :          28 :     ttisp = &sp->ttis[0];
    1846         [ +  - ]:          28 :     if (ttisp->tt_desigidx == abbrind)
    1847                 :             :     {
    1848                 :          28 :         *gmtoff = ttisp->tt_utoff;
    1849                 :          28 :         *isdst = ttisp->tt_isdst;
    1850                 :          28 :         return true;
    1851                 :             :     }
    1852                 :             : 
    1853                 :             :     /*
    1854                 :             :      * Not there, so scan forwards to find the first one after the cutoff.
    1855                 :             :      */
    1856         [ #  # ]:           0 :     for (i = cutoff; i < sp->timecnt; i++)
    1857                 :             :     {
    1858                 :           0 :         ttisp = &sp->ttis[sp->types[i]];
    1859         [ #  # ]:           0 :         if (ttisp->tt_desigidx == abbrind)
    1860                 :             :         {
    1861                 :           0 :             *gmtoff = ttisp->tt_utoff;
    1862                 :           0 :             *isdst = ttisp->tt_isdst;
    1863                 :           0 :             return true;
    1864                 :             :         }
    1865                 :             :     }
    1866                 :             : 
    1867                 :           0 :     return false;               /* hm, not actually used in any interval? */
    1868                 :             : }
    1869                 :             : 
    1870                 :             : /*
    1871                 :             :  * Detect whether a timezone abbreviation is defined within the given zone.
    1872                 :             :  *
    1873                 :             :  * This is similar to pg_interpret_timezone_abbrev() but is not concerned
    1874                 :             :  * with a specific point in time.  We want to know if the abbreviation is
    1875                 :             :  * known at all, and if so whether it has one meaning or several.
    1876                 :             :  *
    1877                 :             :  * Returns true if the abbreviation is known, false if not.
    1878                 :             :  * If the abbreviation is known and has a single meaning (only one value
    1879                 :             :  * of gmtoff/isdst), sets *isfixed = true and sets *gmtoff and *isdst.
    1880                 :             :  * If there are multiple meanings, sets *isfixed = false.
    1881                 :             :  *
    1882                 :             :  * Note: abbrev is matched case-sensitively; it should be all-upper-case.
    1883                 :             :  */
    1884                 :             : bool
    1885                 :        4961 : pg_timezone_abbrev_is_known(const char *abbrev,
    1886                 :             :                             bool *isfixed,
    1887                 :             :                             long int *gmtoff,
    1888                 :             :                             int *isdst,
    1889                 :             :                             const pg_tz *tz)
    1890                 :             : {
    1891                 :        4961 :     bool        result = false;
    1892                 :        4961 :     const struct state *sp = &tz->state;
    1893                 :             :     const char *abbrs;
    1894                 :             :     int         abbrind;
    1895                 :             : 
    1896                 :             :     /*
    1897                 :             :      * Locate the abbreviation in the zone's abbreviation list.  We assume
    1898                 :             :      * there are not duplicates in the list.
    1899                 :             :      */
    1900                 :        4961 :     abbrs = sp->chars;
    1901                 :        4961 :     abbrind = 0;
    1902         [ +  + ]:       28349 :     while (abbrind < sp->charcnt)
    1903                 :             :     {
    1904         [ +  + ]:       23541 :         if (strcmp(abbrev, abbrs + abbrind) == 0)
    1905                 :         153 :             break;
    1906         [ +  + ]:       93592 :         while (abbrs[abbrind] != '\0')
    1907                 :       70204 :             abbrind++;
    1908                 :       23388 :         abbrind++;
    1909                 :             :     }
    1910         [ +  + ]:        4961 :     if (abbrind >= sp->charcnt)
    1911                 :        4808 :         return false;           /* definitely not there */
    1912                 :             : 
    1913                 :             :     /*
    1914                 :             :      * Scan the ttinfo array to find uses of the abbreviation.
    1915                 :             :      */
    1916         [ +  + ]:        1211 :     for (int i = 0; i < sp->typecnt; i++)
    1917                 :             :     {
    1918                 :        1058 :         const struct ttinfo *ttisp = &sp->ttis[i];
    1919                 :             : 
    1920         [ +  + ]:        1058 :         if (ttisp->tt_desigidx == abbrind)
    1921                 :             :         {
    1922         [ +  + ]:         290 :             if (!result)
    1923                 :             :             {
    1924                 :             :                 /* First usage */
    1925                 :         153 :                 *isfixed = true;    /* for the moment */
    1926                 :         153 :                 *gmtoff = ttisp->tt_utoff;
    1927                 :         153 :                 *isdst = ttisp->tt_isdst;
    1928                 :         153 :                 result = true;
    1929                 :             :             }
    1930                 :             :             else
    1931                 :             :             {
    1932                 :             :                 /* Second or later usage, does it match? */
    1933         [ +  - ]:         137 :                 if (*gmtoff != ttisp->tt_utoff ||
    1934         [ -  + ]:         137 :                     *isdst != ttisp->tt_isdst)
    1935                 :             :                 {
    1936                 :           0 :                     *isfixed = false;
    1937                 :           0 :                     break;      /* no point in looking further */
    1938                 :             :                 }
    1939                 :             :             }
    1940                 :             :         }
    1941                 :             :     }
    1942                 :             : 
    1943                 :         153 :     return result;
    1944                 :             : }
    1945                 :             : 
    1946                 :             : /*
    1947                 :             :  * Iteratively fetch all the abbreviations used in the given time zone.
    1948                 :             :  *
    1949                 :             :  * *indx is a state counter that the caller must initialize to zero
    1950                 :             :  * before the first call, and not touch between calls.
    1951                 :             :  *
    1952                 :             :  * Returns the next known abbreviation, or NULL if there are no more.
    1953                 :             :  *
    1954                 :             :  * Note: the caller typically applies pg_interpret_timezone_abbrev()
    1955                 :             :  * to each result.  While that nominally results in O(N^2) time spent
    1956                 :             :  * searching the sp->chars[] array, we don't expect any zone to have
    1957                 :             :  * enough abbreviations to make that meaningful.
    1958                 :             :  */
    1959                 :             : const char *
    1960                 :         168 : pg_get_next_timezone_abbrev(int *indx,
    1961                 :             :                             const pg_tz *tz)
    1962                 :             : {
    1963                 :             :     const char *result;
    1964                 :         168 :     const struct state *sp = &tz->state;
    1965                 :             :     const char *abbrs;
    1966                 :             :     int         abbrind;
    1967                 :             : 
    1968                 :             :     /* If we're still in range, the result is the current abbrev. */
    1969                 :         168 :     abbrs = sp->chars;
    1970                 :         168 :     abbrind = *indx;
    1971   [ +  -  +  + ]:         168 :     if (abbrind < 0 || abbrind >= sp->charcnt)
    1972                 :          28 :         return NULL;
    1973                 :         140 :     result = abbrs + abbrind;
    1974                 :             : 
    1975                 :             :     /* Advance *indx past this abbrev and its trailing null. */
    1976         [ +  + ]:         560 :     while (abbrs[abbrind] != '\0')
    1977                 :         420 :         abbrind++;
    1978                 :         140 :     abbrind++;
    1979                 :         140 :     *indx = abbrind;
    1980                 :             : 
    1981                 :         140 :     return result;
    1982                 :             : }
    1983                 :             : 
    1984                 :             : /*
    1985                 :             :  * If the given timezone uses only one GMT offset, store that offset
    1986                 :             :  * into *gmtoff and return true, else return false.
    1987                 :             :  */
    1988                 :             : bool
    1989                 :         621 : pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
    1990                 :             : {
    1991                 :             :     /*
    1992                 :             :      * The zone could have more than one ttinfo, if it's historically used
    1993                 :             :      * more than one abbreviation.  We return true as long as they all have
    1994                 :             :      * the same gmtoff.
    1995                 :             :      */
    1996                 :             :     const struct state *sp;
    1997                 :             :     int         i;
    1998                 :             : 
    1999                 :         621 :     sp = &tz->state;
    2000         [ +  + ]:         639 :     for (i = 1; i < sp->typecnt; i++)
    2001                 :             :     {
    2002         [ +  + ]:          74 :         if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
    2003                 :          56 :             return false;
    2004                 :             :     }
    2005                 :         565 :     *gmtoff = sp->ttis[0].tt_utoff;
    2006                 :         565 :     return true;
    2007                 :             : }
    2008                 :             : 
    2009                 :             : /*
    2010                 :             :  * Return the name of the current timezone
    2011                 :             :  */
    2012                 :             : const char *
    2013                 :       40498 : pg_get_timezone_name(pg_tz *tz)
    2014                 :             : {
    2015         [ +  - ]:       40498 :     if (tz)
    2016                 :       40498 :         return tz->TZname;
    2017                 :           0 :     return NULL;
    2018                 :             : }
    2019                 :             : 
    2020                 :             : /*
    2021                 :             :  * Check whether timezone is acceptable.
    2022                 :             :  *
    2023                 :             :  * What we are doing here is checking for leap-second-aware timekeeping.
    2024                 :             :  * We need to reject such TZ settings because they'll wreak havoc with our
    2025                 :             :  * date/time arithmetic.
    2026                 :             :  */
    2027                 :             : bool
    2028                 :       23473 : pg_tz_acceptable(pg_tz *tz)
    2029                 :             : {
    2030                 :             :     struct pg_tm *tt;
    2031                 :             :     pg_time_t   time2000;
    2032                 :             : 
    2033                 :             :     /*
    2034                 :             :      * To detect leap-second timekeeping, run pg_localtime for what should be
    2035                 :             :      * GMT midnight, 2000-01-01.  Insist that the tm_sec value be zero; any
    2036                 :             :      * other result has to be due to leap seconds.
    2037                 :             :      */
    2038                 :       23473 :     time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
    2039                 :       23473 :     tt = pg_localtime(&time2000, tz);
    2040   [ +  -  -  + ]:       23473 :     if (!tt || tt->tm_sec != 0)
    2041                 :           0 :         return false;
    2042                 :             : 
    2043                 :       23473 :     return true;
    2044                 :             : }
        

Generated by: LCOV version 2.0-1