While working on some patch, I saw the following error message when a
transaction ended successfully after a failed call to
parse_and_validate_value().

The cause is ParseTzFile() returns leaving an open file descriptor
unfreed in some error cases.

This happens only in a special case when the errors are ignored, but
in principle the file descriptor should be released before exiting the
function.

I'm not sure it's worth fixing but the attached fixes that.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From a81f2fd6f0293f3e813575d76a59beda93bc030a Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota....@gmail.com>
Date: Mon, 30 May 2022 15:49:16 +0900
Subject: [PATCH 1/2] Fix ParseTzFile to call FreeFile() on error

ParseTzFile() forgot to FreeFile() zone file on error. Thus when this
is called within a successfully-ended transaction, it leaves an open
file descriptor, which leads to the error "n temporary files and
directories not closed at end-of-transaction".
---
 src/backend/utils/misc/tzparser.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/backend/utils/misc/tzparser.c b/src/backend/utils/misc/tzparser.c
index a69cb2d268..bfb259b3c3 100644
--- a/src/backend/utils/misc/tzparser.c
+++ b/src/backend/utils/misc/tzparser.c
@@ -364,7 +364,7 @@ ParseTzFile(const char *filename, int depth,
 			{
 				GUC_check_errmsg("could not read time zone file \"%s\": %m",
 								 filename);
-				return -1;
+				goto error_exit;
 			}
 			/* else we're at EOF after all */
 			break;
@@ -374,7 +374,7 @@ 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;
+			goto error_exit;
 		}
 
 		/* skip over whitespace */
@@ -397,12 +397,12 @@ ParseTzFile(const char *filename, int depth,
 			{
 				GUC_check_errmsg("@INCLUDE without file name in time zone file \"%s\", line %d",
 								 filename, lineno);
-				return -1;
+				goto error_exit;
 			}
 			n = ParseTzFile(includeFile, depth + 1,
 							base, arraysize, n);
 			if (n < 0)
-				return -1;
+				goto error_exit;
 			continue;
 		}
 
@@ -413,14 +413,19 @@ ParseTzFile(const char *filename, int depth,
 		}
 
 		if (!splitTzLine(filename, lineno, line, &tzentry))
-			return -1;
+			goto error_exit;
 		if (!validateTzEntry(&tzentry))
-			return -1;
+			goto error_exit;
 		n = addToArray(base, arraysize, n, &tzentry, override);
 		if (n < 0)
-			return -1;
+			goto error_exit;
 	}
+	goto success;
 
+error_exit:
+	n = -1;
+
+success:
 	FreeFile(tzFile);
 
 	return n;
-- 
2.31.1

Reply via email to