LCOV - differential code coverage report
Current view: top level - src/backend/utils/misc - tzparser.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 68.3 % 164 112 52 112
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 5 5 5
Baseline: lcov-20250906-005545-baseline Branches: 61.3 % 106 65 41 65
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(360..) days: 68.3 % 164 112 52 112
Function coverage date bins:
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(360..) days: 61.3 % 106 65 41 65

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * tzparser.c
                                  4                 :                :  *    Functions for parsing timezone offset files
                                  5                 :                :  *
                                  6                 :                :  * Note: this code is invoked from the check_hook for the GUC variable
                                  7                 :                :  * timezone_abbreviations.  Therefore, it should report problems using
                                  8                 :                :  * GUC_check_errmsg() and related functions, and try to avoid throwing
                                  9                 :                :  * elog(ERROR).  This is not completely bulletproof at present --- in
                                 10                 :                :  * particular out-of-memory will throw an error.  Could probably fix with
                                 11                 :                :  * PG_TRY if necessary.
                                 12                 :                :  *
                                 13                 :                :  *
                                 14                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                 15                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 16                 :                :  *
                                 17                 :                :  * IDENTIFICATION
                                 18                 :                :  *    src/backend/utils/misc/tzparser.c
                                 19                 :                :  *
                                 20                 :                :  *-------------------------------------------------------------------------
                                 21                 :                :  */
                                 22                 :                : 
                                 23                 :                : #include "postgres.h"
                                 24                 :                : 
                                 25                 :                : #include <ctype.h>
                                 26                 :                : 
                                 27                 :                : #include "miscadmin.h"
                                 28                 :                : #include "storage/fd.h"
                                 29                 :                : #include "utils/datetime.h"
                                 30                 :                : #include "utils/guc.h"
                                 31                 :                : #include "utils/memutils.h"
                                 32                 :                : #include "utils/tzparser.h"
                                 33                 :                : 
                                 34                 :                : 
                                 35                 :                : #define WHITESPACE " \t\n\r"
                                 36                 :                : 
                                 37                 :                : static bool validateTzEntry(tzEntry *tzentry);
                                 38                 :                : static bool splitTzLine(const char *filename, int lineno,
                                 39                 :                :                         char *line, tzEntry *tzentry);
                                 40                 :                : static int  addToArray(tzEntry **base, int *arraysize, int n,
                                 41                 :                :                        tzEntry *entry, bool override);
                                 42                 :                : static int  ParseTzFile(const char *filename, int depth,
                                 43                 :                :                         tzEntry **base, int *arraysize, int n);
                                 44                 :                : 
                                 45                 :                : 
                                 46                 :                : /*
                                 47                 :                :  * Apply additional validation checks to a tzEntry
                                 48                 :                :  *
                                 49                 :                :  * Returns true if OK, else false
                                 50                 :                :  */
                                 51                 :                : static bool
 6983 tgl@sss.pgh.pa.us          52                 :CBC     1255431 : validateTzEntry(tzEntry *tzentry)
                                 53                 :                : {
                                 54                 :                :     unsigned char *p;
                                 55                 :                : 
                                 56                 :                :     /*
                                 57                 :                :      * Check restrictions imposed by datetktbl storage format (see datetime.c)
                                 58                 :                :      */
                                 59         [ -  + ]:        1255431 :     if (strlen(tzentry->abbrev) > TOKMAXLEN)
                                 60                 :                :     {
 5266 tgl@sss.pgh.pa.us          61                 :UBC           0 :         GUC_check_errmsg("time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d",
                                 62                 :                :                          tzentry->abbrev, TOKMAXLEN,
                                 63                 :                :                          tzentry->filename, tzentry->lineno);
 6983                            64                 :              0 :         return false;
                                 65                 :                :     }
                                 66                 :                : 
                                 67                 :                :     /*
                                 68                 :                :      * Sanity-check the offset: shouldn't exceed 14 hours
                                 69                 :                :      */
  652 bruce@momjian.us           70         [ +  - ]:CBC     1255431 :     if (tzentry->offset > 14 * SECS_PER_HOUR ||
                                 71         [ -  + ]:        1255431 :         tzentry->offset < -14 * SECS_PER_HOUR)
                                 72                 :                :     {
 5266 tgl@sss.pgh.pa.us          73                 :UBC           0 :         GUC_check_errmsg("time zone offset %d is out of range in time zone file \"%s\", line %d",
                                 74                 :                :                          tzentry->offset,
                                 75                 :                :                          tzentry->filename, tzentry->lineno);
 6983                            76                 :              0 :         return false;
                                 77                 :                :     }
                                 78                 :                : 
                                 79                 :                :     /*
                                 80                 :                :      * Convert abbrev to lowercase (must match datetime.c's conversion)
                                 81                 :                :      */
 6983 tgl@sss.pgh.pa.us          82         [ +  + ]:CBC     5820042 :     for (p = (unsigned char *) tzentry->abbrev; *p; p++)
                                 83                 :        4564611 :         *p = pg_tolower(*p);
                                 84                 :                : 
                                 85                 :        1255431 :     return true;
                                 86                 :                : }
                                 87                 :                : 
                                 88                 :                : /*
                                 89                 :                :  * Attempt to parse the line as a timezone abbrev spec
                                 90                 :                :  *
                                 91                 :                :  * Valid formats are:
                                 92                 :                :  *  name  zone
                                 93                 :                :  *  name  offset  dst
                                 94                 :                :  *
                                 95                 :                :  * Returns true if OK, else false; data is stored in *tzentry
                                 96                 :                :  */
                                 97                 :                : static bool
                                 98                 :        1255431 : splitTzLine(const char *filename, int lineno, char *line, tzEntry *tzentry)
                                 99                 :                : {
                                100                 :                :     char       *brkl;
                                101                 :                :     char       *abbrev;
                                102                 :                :     char       *offset;
                                103                 :                :     char       *offset_endptr;
                                104                 :                :     char       *remain;
                                105                 :                :     char       *is_dst;
                                106                 :                : 
                                107                 :        1255431 :     tzentry->lineno = lineno;
                                108                 :        1255431 :     tzentry->filename = filename;
                                109                 :                : 
  410 peter@eisentraut.org      110                 :        1255431 :     abbrev = strtok_r(line, WHITESPACE, &brkl);
 6983 tgl@sss.pgh.pa.us         111         [ -  + ]:        1255431 :     if (!abbrev)
                                112                 :                :     {
 5266 tgl@sss.pgh.pa.us         113                 :UBC           0 :         GUC_check_errmsg("missing time zone abbreviation in time zone file \"%s\", line %d",
                                114                 :                :                          filename, lineno);
 6983                           115                 :              0 :         return false;
                                116                 :                :     }
 3978 tgl@sss.pgh.pa.us         117                 :CBC     1255431 :     tzentry->abbrev = pstrdup(abbrev);
                                118                 :                : 
  410 peter@eisentraut.org      119                 :        1255431 :     offset = strtok_r(NULL, WHITESPACE, &brkl);
 6983 tgl@sss.pgh.pa.us         120         [ -  + ]:        1255431 :     if (!offset)
                                121                 :                :     {
 5266 tgl@sss.pgh.pa.us         122                 :UBC           0 :         GUC_check_errmsg("missing time zone offset in time zone file \"%s\", line %d",
                                123                 :                :                          filename, lineno);
 6983                           124                 :              0 :         return false;
                                125                 :                :     }
                                126                 :                : 
                                127                 :                :     /* We assume zone names don't begin with a digit or sign */
 3978 tgl@sss.pgh.pa.us         128   [ +  +  +  -  :CBC     1255431 :     if (isdigit((unsigned char) *offset) || *offset == '+' || *offset == '-')
                                              +  + ]
                                129                 :                :     {
                                130                 :         933531 :         tzentry->zone = NULL;
                                131                 :         933531 :         tzentry->offset = strtol(offset, &offset_endptr, 10);
                                132   [ +  -  -  + ]:         933531 :         if (offset_endptr == offset || *offset_endptr != '\0')
                                133                 :                :         {
 3978 tgl@sss.pgh.pa.us         134                 :UBC           0 :             GUC_check_errmsg("invalid number for time zone offset in time zone file \"%s\", line %d",
                                135                 :                :                              filename, lineno);
                                136                 :              0 :             return false;
                                137                 :                :         }
                                138                 :                : 
  410 peter@eisentraut.org      139                 :CBC      933531 :         is_dst = strtok_r(NULL, WHITESPACE, &brkl);
 3978 tgl@sss.pgh.pa.us         140   [ +  -  +  + ]:         933531 :         if (is_dst && pg_strcasecmp(is_dst, "D") == 0)
                                141                 :                :         {
                                142                 :         309024 :             tzentry->is_dst = true;
  410 peter@eisentraut.org      143                 :         309024 :             remain = strtok_r(NULL, WHITESPACE, &brkl);
                                144                 :                :         }
                                145                 :                :         else
                                146                 :                :         {
                                147                 :                :             /* there was no 'D' dst specifier */
 3978 tgl@sss.pgh.pa.us         148                 :         624507 :             tzentry->is_dst = false;
                                149                 :         624507 :             remain = is_dst;
                                150                 :                :         }
                                151                 :                :     }
                                152                 :                :     else
                                153                 :                :     {
                                154                 :                :         /*
                                155                 :                :          * Assume entry is a zone name.  We do not try to validate it by
                                156                 :                :          * looking up the zone, because that would force loading of a lot of
                                157                 :                :          * zones that probably will never be used in the current session.
                                158                 :                :          */
                                159                 :         321900 :         tzentry->zone = pstrdup(offset);
  652 bruce@momjian.us          160                 :         321900 :         tzentry->offset = 0 * SECS_PER_HOUR;
 6983 tgl@sss.pgh.pa.us         161                 :         321900 :         tzentry->is_dst = false;
  410 peter@eisentraut.org      162                 :         321900 :         remain = strtok_r(NULL, WHITESPACE, &brkl);
                                163                 :                :     }
                                164                 :                : 
 6912 bruce@momjian.us          165         [ -  + ]:        1255431 :     if (!remain)                /* no more non-whitespace chars */
 6983 tgl@sss.pgh.pa.us         166                 :UBC           0 :         return true;
                                167                 :                : 
 6983 tgl@sss.pgh.pa.us         168         [ -  + ]:CBC     1255431 :     if (remain[0] != '#')       /* must be a comment */
                                169                 :                :     {
 5266 tgl@sss.pgh.pa.us         170                 :UBC           0 :         GUC_check_errmsg("invalid syntax in time zone file \"%s\", line %d",
                                171                 :                :                          filename, lineno);
 6983                           172                 :              0 :         return false;
                                173                 :                :     }
 6983 tgl@sss.pgh.pa.us         174                 :CBC     1255431 :     return true;
                                175                 :                : }
                                176                 :                : 
                                177                 :                : /*
                                178                 :                :  * Insert entry into sorted array
                                179                 :                :  *
                                180                 :                :  * *base: base address of array (changeable if must enlarge array)
                                181                 :                :  * *arraysize: allocated length of array (changeable if must enlarge array)
                                182                 :                :  * n: current number of valid elements in array
                                183                 :                :  * entry: new data to insert
                                184                 :                :  * override: true if OK to override
                                185                 :                :  *
                                186                 :                :  * Returns the new array length (new value for n), or -1 if error
                                187                 :                :  */
                                188                 :                : static int
                                189                 :        1255431 : addToArray(tzEntry **base, int *arraysize, int n,
                                190                 :                :            tzEntry *entry, bool override)
                                191                 :                : {
                                192                 :                :     tzEntry    *arrayptr;
                                193                 :                :     int         low;
                                194                 :                :     int         high;
                                195                 :                : 
                                196                 :                :     /*
                                197                 :                :      * Search the array for a duplicate; as a useful side effect, the array is
                                198                 :                :      * maintained in sorted order.  We use strcmp() to ensure we match the
                                199                 :                :      * sort order datetime.c expects.
                                200                 :                :      */
                                201                 :        1255431 :     arrayptr = *base;
                                202                 :        1255431 :     low = 0;
 6912 bruce@momjian.us          203                 :        1255431 :     high = n - 1;
 6983 tgl@sss.pgh.pa.us         204         [ +  + ]:        9187176 :     while (low <= high)
                                205                 :                :     {
 6912 bruce@momjian.us          206                 :        7931760 :         int         mid = (low + high) >> 1;
                                207                 :        7931760 :         tzEntry    *midptr = arrayptr + mid;
                                208                 :                :         int         cmp;
                                209                 :                : 
 6983 tgl@sss.pgh.pa.us         210                 :        7931760 :         cmp = strcmp(entry->abbrev, midptr->abbrev);
                                211         [ +  + ]:        7931760 :         if (cmp < 0)
                                212                 :        3154683 :             high = mid - 1;
                                213         [ +  + ]:        4777077 :         else if (cmp > 0)
                                214                 :        4777062 :             low = mid + 1;
                                215                 :                :         else
                                216                 :                :         {
                                217                 :                :             /*
                                218                 :                :              * Found a duplicate entry; complain unless it's the same.
                                219                 :                :              */
 3978                           220   [ +  +  +  - ]:             15 :             if ((midptr->zone == NULL && entry->zone == NULL &&
                                221         [ -  + ]:             12 :                  midptr->offset == entry->offset &&
 3978 tgl@sss.pgh.pa.us         222         [ #  # ]:UBC           0 :                  midptr->is_dst == entry->is_dst) ||
 3978 tgl@sss.pgh.pa.us         223   [ +  +  -  + ]:CBC          15 :                 (midptr->zone != NULL && entry->zone != NULL &&
 3978 tgl@sss.pgh.pa.us         224         [ #  # ]:UBC           0 :                  strcmp(midptr->zone, entry->zone) == 0))
                                225                 :                :             {
                                226                 :                :                 /* return unchanged array */
 6983                           227                 :              0 :                 return n;
                                228                 :                :             }
 6983 tgl@sss.pgh.pa.us         229         [ +  - ]:CBC          15 :             if (override)
                                230                 :                :             {
                                231                 :                :                 /* same abbrev but something is different, override */
 3978                           232                 :             15 :                 midptr->zone = entry->zone;
 6983                           233                 :             15 :                 midptr->offset = entry->offset;
                                234                 :             15 :                 midptr->is_dst = entry->is_dst;
                                235                 :             15 :                 return n;
                                236                 :                :             }
                                237                 :                :             /* same abbrev but something is different, complain */
 5266 tgl@sss.pgh.pa.us         238                 :UBC           0 :             GUC_check_errmsg("time zone abbreviation \"%s\" is multiply defined",
                                239                 :                :                              entry->abbrev);
                                240                 :              0 :             GUC_check_errdetail("Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d.",
                                241                 :                :                                 midptr->filename, midptr->lineno,
                                242                 :                :                                 entry->filename, entry->lineno);
 6983                           243                 :              0 :             return -1;
                                244                 :                :         }
                                245                 :                :     }
                                246                 :                : 
                                247                 :                :     /*
                                248                 :                :      * No match, insert at position "low".
                                249                 :                :      */
 6983 tgl@sss.pgh.pa.us         250         [ +  + ]:CBC     1255416 :     if (n >= *arraysize)
                                251                 :                :     {
                                252                 :           6438 :         *arraysize *= 2;
                                253                 :           6438 :         *base = (tzEntry *) repalloc(*base, *arraysize * sizeof(tzEntry));
                                254                 :                :     }
                                255                 :                : 
                                256                 :        1255416 :     arrayptr = *base + low;
                                257                 :                : 
                                258                 :        1255416 :     memmove(arrayptr + 1, arrayptr, (n - low) * sizeof(tzEntry));
                                259                 :                : 
                                260                 :        1255416 :     memcpy(arrayptr, entry, sizeof(tzEntry));
                                261                 :                : 
 6912 bruce@momjian.us          262                 :        1255416 :     return n + 1;
                                263                 :                : }
                                264                 :                : 
                                265                 :                : /*
                                266                 :                :  * Parse a single timezone abbrev file --- can recurse to handle @INCLUDE
                                267                 :                :  *
                                268                 :                :  * filename: user-specified file name (does not include path)
                                269                 :                :  * depth: current recursion depth
                                270                 :                :  * *base: array for results (changeable if must enlarge array)
                                271                 :                :  * *arraysize: allocated length of array (changeable if must enlarge array)
                                272                 :                :  * n: current number of valid elements in array
                                273                 :                :  *
                                274                 :                :  * Returns the new array length (new value for n), or -1 if error
                                275                 :                :  */
                                276                 :                : static int
 6983 tgl@sss.pgh.pa.us         277                 :           6444 : ParseTzFile(const char *filename, int depth,
                                278                 :                :             tzEntry **base, int *arraysize, int n)
                                279                 :                : {
                                280                 :                :     char        share_path[MAXPGPATH];
                                281                 :                :     char        file_path[MAXPGPATH];
                                282                 :                :     FILE       *tzFile;
                                283                 :                :     char        tzbuf[1024];
                                284                 :                :     char       *line;
                                285                 :                :     tzEntry     tzentry;
 6912 bruce@momjian.us          286                 :           6444 :     int         lineno = 0;
                                287                 :           6444 :     bool        override = false;
                                288                 :                :     const char *p;
                                289                 :                : 
                                290                 :                :     /*
                                291                 :                :      * We enforce that the filename is all alpha characters.  This may be
                                292                 :                :      * overly restrictive, but we don't want to allow access to anything
                                293                 :                :      * outside the timezonesets directory, so for instance '/' *must* be
                                294                 :                :      * rejected.
                                295                 :                :      */
 6983 tgl@sss.pgh.pa.us         296         [ +  + ]:          51552 :     for (p = filename; *p; p++)
                                297                 :                :     {
                                298         [ -  + ]:          45108 :         if (!isalpha((unsigned char) *p))
                                299                 :                :         {
                                300                 :                :             /* at level 0, just use guc.c's regular "invalid value" message */
 6983 tgl@sss.pgh.pa.us         301         [ #  # ]:UBC           0 :             if (depth > 0)
 5266                           302                 :              0 :                 GUC_check_errmsg("invalid time zone file name \"%s\"",
                                303                 :                :                                  filename);
 6983                           304                 :              0 :             return -1;
                                305                 :                :         }
                                306                 :                :     }
                                307                 :                : 
                                308                 :                :     /*
                                309                 :                :      * The maximal recursion depth is a pretty arbitrary setting. It is hard
                                310                 :                :      * to imagine that someone needs more than 3 levels so stick with this
                                311                 :                :      * conservative setting until someone complains.
                                312                 :                :      */
 6983 tgl@sss.pgh.pa.us         313         [ -  + ]:CBC        6444 :     if (depth > 3)
                                314                 :                :     {
 5266 tgl@sss.pgh.pa.us         315                 :UBC           0 :         GUC_check_errmsg("time zone file recursion limit exceeded in file \"%s\"",
                                316                 :                :                          filename);
 6983                           317                 :              0 :         return -1;
                                318                 :                :     }
                                319                 :                : 
 6983 tgl@sss.pgh.pa.us         320                 :CBC        6444 :     get_share_path(my_exec_path, share_path);
                                321                 :           6444 :     snprintf(file_path, sizeof(file_path), "%s/timezonesets/%s",
                                322                 :                :              share_path, filename);
                                323                 :           6444 :     tzFile = AllocateFile(file_path, "r");
                                324         [ -  + ]:           6444 :     if (!tzFile)
                                325                 :                :     {
                                326                 :                :         /*
                                327                 :                :          * Check to see if the problem is not the filename but the directory.
                                328                 :                :          * This is worth troubling over because if the installation share/
                                329                 :                :          * directory is missing or unreadable, this is likely to be the first
                                330                 :                :          * place we notice a problem during postmaster startup.
                                331                 :                :          */
 5971 tgl@sss.pgh.pa.us         332                 :UBC           0 :         int         save_errno = errno;
                                333                 :                :         DIR        *tzdir;
                                334                 :                : 
                                335                 :              0 :         snprintf(file_path, sizeof(file_path), "%s/timezonesets",
                                336                 :                :                  share_path);
                                337                 :              0 :         tzdir = AllocateDir(file_path);
                                338         [ #  # ]:              0 :         if (tzdir == NULL)
                                339                 :                :         {
 5266                           340                 :              0 :             GUC_check_errmsg("could not open directory \"%s\": %m",
                                341                 :                :                              file_path);
                                342                 :              0 :             GUC_check_errhint("This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location.",
                                343                 :                :                               my_exec_path);
 5971                           344                 :              0 :             return -1;
                                345                 :                :         }
                                346                 :              0 :         FreeDir(tzdir);
                                347                 :              0 :         errno = save_errno;
                                348                 :                : 
                                349                 :                :         /*
                                350                 :                :          * otherwise, if file doesn't exist and it's level 0, guc.c's
                                351                 :                :          * complaint is enough
                                352                 :                :          */
 6983                           353   [ #  #  #  # ]:              0 :         if (errno != ENOENT || depth > 0)
 5266                           354                 :              0 :             GUC_check_errmsg("could not read time zone file \"%s\": %m",
                                355                 :                :                              filename);
                                356                 :                : 
 6983                           357                 :              0 :         return -1;
                                358                 :                :     }
                                359                 :                : 
 6983 tgl@sss.pgh.pa.us         360         [ +  - ]:CBC     4056084 :     while (!feof(tzFile))
                                361                 :                :     {
                                362                 :        4056084 :         lineno++;
                                363         [ +  + ]:        4056084 :         if (fgets(tzbuf, sizeof(tzbuf), tzFile) == NULL)
                                364                 :                :         {
                                365         [ -  + ]:           6444 :             if (ferror(tzFile))
                                366                 :                :             {
 5266 tgl@sss.pgh.pa.us         367                 :UBC           0 :                 GUC_check_errmsg("could not read time zone file \"%s\": %m",
                                368                 :                :                                  filename);
 1194                           369                 :              0 :                 n = -1;
                                370                 :              0 :                 break;
                                371                 :                :             }
                                372                 :                :             /* else we're at EOF after all */
 6983 tgl@sss.pgh.pa.us         373                 :CBC        6444 :             break;
                                374                 :                :         }
 6912 bruce@momjian.us          375         [ -  + ]:        4049640 :         if (strlen(tzbuf) == sizeof(tzbuf) - 1)
                                376                 :                :         {
                                377                 :                :             /* the line is too long for tzbuf */
 5266 tgl@sss.pgh.pa.us         378                 :UBC           0 :             GUC_check_errmsg("line is too long in time zone file \"%s\", line %d",
                                379                 :                :                              filename, lineno);
 1194                           380                 :              0 :             n = -1;
                                381                 :              0 :             break;
                                382                 :                :         }
                                383                 :                : 
                                384                 :                :         /* skip over whitespace */
 6983 tgl@sss.pgh.pa.us         385                 :CBC     4049640 :         line = tzbuf;
                                386   [ +  +  +  + ]:       42935244 :         while (*line && isspace((unsigned char) *line))
                                387                 :       38885604 :             line++;
                                388                 :                : 
 6912 bruce@momjian.us          389         [ +  + ]:        4049640 :         if (*line == '\0')      /* empty line */
 6983 tgl@sss.pgh.pa.us         390                 :         141669 :             continue;
 6912 bruce@momjian.us          391         [ +  + ]:        3907971 :         if (*line == '#')       /* comment line */
 6983 tgl@sss.pgh.pa.us         392                 :        2652528 :             continue;
                                393                 :                : 
                                394         [ +  + ]:        1255443 :         if (pg_strncasecmp(line, "@INCLUDE", strlen("@INCLUDE")) == 0)
                                395                 :              6 :         {
                                396                 :                :             /* pstrdup so we can use filename in result data structure */
 6912 bruce@momjian.us          397                 :              6 :             char       *includeFile = pstrdup(line + strlen("@INCLUDE"));
                                398                 :                :             char       *brki;
                                399                 :                : 
  410 peter@eisentraut.org      400                 :              6 :             includeFile = strtok_r(includeFile, WHITESPACE, &brki);
 6983 tgl@sss.pgh.pa.us         401   [ +  -  -  + ]:              6 :             if (!includeFile || !*includeFile)
                                402                 :                :             {
 5266 tgl@sss.pgh.pa.us         403                 :UBC           0 :                 GUC_check_errmsg("@INCLUDE without file name in time zone file \"%s\", line %d",
                                404                 :                :                                  filename, lineno);
 1194                           405                 :              0 :                 n = -1;
                                406                 :              0 :                 break;
                                407                 :                :             }
 6983 tgl@sss.pgh.pa.us         408                 :CBC           6 :             n = ParseTzFile(includeFile, depth + 1,
                                409                 :                :                             base, arraysize, n);
                                410         [ -  + ]:              6 :             if (n < 0)
 1194 tgl@sss.pgh.pa.us         411                 :UBC           0 :                 break;
 6983 tgl@sss.pgh.pa.us         412                 :CBC           6 :             continue;
                                413                 :                :         }
                                414                 :                : 
                                415         [ +  + ]:        1255437 :         if (pg_strncasecmp(line, "@OVERRIDE", strlen("@OVERRIDE")) == 0)
                                416                 :                :         {
                                417                 :              6 :             override = true;
                                418                 :              6 :             continue;
                                419                 :                :         }
                                420                 :                : 
                                421         [ -  + ]:        1255431 :         if (!splitTzLine(filename, lineno, line, &tzentry))
                                422                 :                :         {
 1194 tgl@sss.pgh.pa.us         423                 :UBC           0 :             n = -1;
                                424                 :              0 :             break;
                                425                 :                :         }
 6983 tgl@sss.pgh.pa.us         426         [ -  + ]:CBC     1255431 :         if (!validateTzEntry(&tzentry))
                                427                 :                :         {
 1194 tgl@sss.pgh.pa.us         428                 :UBC           0 :             n = -1;
                                429                 :              0 :             break;
                                430                 :                :         }
 6983 tgl@sss.pgh.pa.us         431                 :CBC     1255431 :         n = addToArray(base, arraysize, n, &tzentry, override);
                                432         [ -  + ]:        1255431 :         if (n < 0)
 1194 tgl@sss.pgh.pa.us         433                 :UBC           0 :             break;
                                434                 :                :     }
                                435                 :                : 
 6983 tgl@sss.pgh.pa.us         436                 :CBC        6444 :     FreeFile(tzFile);
                                437                 :                : 
                                438                 :           6444 :     return n;
                                439                 :                : }
                                440                 :                : 
                                441                 :                : /*
                                442                 :                :  * load_tzoffsets --- read and parse the specified timezone offset file
                                443                 :                :  *
                                444                 :                :  * On success, return a filled-in TimeZoneAbbrevTable, which must have been
                                445                 :                :  * guc_malloc'd not palloc'd.  On failure, return NULL, using GUC_check_errmsg
                                446                 :                :  * and friends to give details of the problem.
                                447                 :                :  */
                                448                 :                : TimeZoneAbbrevTable *
 5266                           449                 :           6438 : load_tzoffsets(const char *filename)
                                450                 :                : {
                                451                 :           6438 :     TimeZoneAbbrevTable *result = NULL;
                                452                 :                :     MemoryContext tmpContext;
                                453                 :                :     MemoryContext oldContext;
                                454                 :                :     tzEntry    *array;
                                455                 :                :     int         arraysize;
                                456                 :                :     int         n;
                                457                 :                : 
                                458                 :                :     /*
                                459                 :                :      * Create a temp memory context to work in.  This makes it easy to clean
                                460                 :                :      * up afterwards.
                                461                 :                :      */
 6983                           462                 :           6438 :     tmpContext = AllocSetContextCreate(CurrentMemoryContext,
                                463                 :                :                                        "TZParserMemory",
                                464                 :                :                                        ALLOCSET_SMALL_SIZES);
                                465                 :           6438 :     oldContext = MemoryContextSwitchTo(tmpContext);
                                466                 :                : 
                                467                 :                :     /* Initialize array at a reasonable size */
                                468                 :           6438 :     arraysize = 128;
                                469                 :           6438 :     array = (tzEntry *) palloc(arraysize * sizeof(tzEntry));
                                470                 :                : 
                                471                 :                :     /* Parse the file(s) */
                                472                 :           6438 :     n = ParseTzFile(filename, 0, &array, &arraysize, 0);
                                473                 :                : 
                                474                 :                :     /* If no errors so far, let datetime.c allocate memory & convert format */
 5266                           475         [ +  - ]:           6438 :     if (n >= 0)
                                476                 :                :     {
 3978                           477                 :           6438 :         result = ConvertTimeZoneAbbrevs(array, n);
 5266                           478         [ -  + ]:           6438 :         if (!result)
 5266 tgl@sss.pgh.pa.us         479                 :UBC           0 :             GUC_check_errmsg("out of memory");
                                480                 :                :     }
                                481                 :                : 
                                482                 :                :     /* Clean up */
 6983 tgl@sss.pgh.pa.us         483                 :CBC        6438 :     MemoryContextSwitchTo(oldContext);
                                484                 :           6438 :     MemoryContextDelete(tmpContext);
                                485                 :                : 
 5266                           486                 :           6438 :     return result;
                                487                 :                : }
        

Generated by: LCOV version 2.4-beta