LCOV - code coverage report
Current view: top level - src/timezone - localtime.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 81.7 % 1049 857
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 33 33
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 65.3 % 636 415

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

Generated by: LCOV version 2.3.2-1