LCOV - differential code coverage report
Current view: top level - src/timezone - localtime.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 78.6 % 807 634 52 72 49 44 266 324 80 258
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 31 31 31 31
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 78.6 % 807 634 52 72 49 44 266 324 80 257
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 62 31 31 31

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

Generated by: LCOV version v1.16-55-g56c0a2a