]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Ensure ParseTzFile() closes the input file after failing.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2022 18:47:44 +0000 (14:47 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2022 18:47:44 +0000 (14:47 -0400)
We hadn't noticed this because (a) few people feed invalid
timezone abbreviation files to the server, and (b) in typical
scenarios guc.c would throw ereport(ERROR) and then transaction
abort handling would silently clean up the leaked file reference.
However, it was possible to observe file leakage warnings if one
breaks an already-active abbreviation file, because guc.c does
not throw ERROR when loading supposedly-validated settings during
session start or SIGHUP processing.

Report and fix by Kyotaro Horiguchi (cosmetic adjustments by me)

Discussion: https://postgr.es/m/20220530.173740.748502979257582392.horikyota.ntt@gmail.com

src/backend/utils/misc/tzparser.c

index d2aa5ee87d5daa04c85ac97accd5aa38fee9a5d7..65e667371ec3f4cae899c20f1e04d51bb6380f9c 100644 (file)
@@ -364,7 +364,8 @@ ParseTzFile(const char *filename, int depth,
                        {
                                GUC_check_errmsg("could not read time zone file \"%s\": %m",
                                                                 filename);
-                               return -1;
+                               n = -1;
+                               break;
                        }
                        /* else we're at EOF after all */
                        break;
@@ -374,7 +375,8 @@ ParseTzFile(const char *filename, int depth,
                        /* the line is too long for tzbuf */
                        GUC_check_errmsg("line is too long in time zone file \"%s\", line %d",
                                                         filename, lineno);
-                       return -1;
+                       n = -1;
+                       break;
                }
 
                /* skip over whitespace */
@@ -397,12 +399,13 @@ ParseTzFile(const char *filename, int depth,
                        {
                                GUC_check_errmsg("@INCLUDE without file name in time zone file \"%s\", line %d",
                                                                 filename, lineno);
-                               return -1;
+                               n = -1;
+                               break;
                        }
                        n = ParseTzFile(includeFile, depth + 1,
                                                        base, arraysize, n);
                        if (n < 0)
-                               return -1;
+                               break;
                        continue;
                }
 
@@ -413,12 +416,18 @@ ParseTzFile(const char *filename, int depth,
                }
 
                if (!splitTzLine(filename, lineno, line, &tzentry))
-                       return -1;
+               {
+                       n = -1;
+                       break;
+               }
                if (!validateTzEntry(&tzentry))
-                       return -1;
+               {
+                       n = -1;
+                       break;
+               }
                n = addToArray(base, arraysize, n, &tzentry, override);
                if (n < 0)
-                       return -1;
+                       break;
        }
 
        FreeFile(tzFile);