From d367d41d662c859011724745fec592baf94b70fe Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 8 Mar 2011 21:35:42 -0500
Subject: [PATCH] Fix file descriptor leaks in pg_upgrade in failure code
 paths.

---
 contrib/pg_upgrade/check.c           |  8 ++++++--
 contrib/pg_upgrade/file.c            |  6 ++++++
 contrib/pg_upgrade/server.c          |  6 ++----
 contrib/pg_upgrade/version.c         |  5 +++--
 contrib/pg_upgrade/version_old_8_3.c | 26 +++++++++++++++++---------
 5 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 9ef63ec2c9d..1c4847abea1 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -515,9 +515,11 @@ check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
 		PQfinish(conn);
 	}
 
+	if (script)
+			fclose(script);
+
 	if (found)
 	{
-		fclose(script);
 		pg_log(PG_REPORT, "fatal\n");
 		pg_log(PG_FATAL,
 			   "| Your installation contains \"/contrib/isn\" functions\n"
@@ -616,9 +618,11 @@ check_for_reg_data_type_usage(ClusterInfo *cluster)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		fclose(script);
 		pg_log(PG_REPORT, "fatal\n");
 		pg_log(PG_FATAL,
 			   "| Your installation contains one of the reg* data types in\n"
diff --git a/contrib/pg_upgrade/file.c b/contrib/pg_upgrade/file.c
index deaca4698b7..803e0a0f70f 100644
--- a/contrib/pg_upgrade/file.c
+++ b/contrib/pg_upgrade/file.c
@@ -302,7 +302,10 @@ pg_scandir_internal(const char *dirname,
 						(size_t) ((name_num + 1) * sizeof(struct dirent *)));
 
 			if (*namelist == NULL)
+			{
+				closedir(dirdesc);
 				return -1;
+			}
 
 			entrysize = sizeof(struct dirent) - sizeof(direntry->d_name) +
 				strlen(direntry->d_name) + 1;
@@ -310,7 +313,10 @@ pg_scandir_internal(const char *dirname,
 			(*namelist)[name_num] = (struct dirent *) malloc(entrysize);
 
 			if ((*namelist)[name_num] == NULL)
+			{
+				closedir(dirdesc);
 				return -1;
+			}
 
 			memcpy((*namelist)[name_num], direntry, entrysize);
 
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
index c7684f87e5e..84bd03ed8ed 100644
--- a/contrib/pg_upgrade/server.c
+++ b/contrib/pg_upgrade/server.c
@@ -144,11 +144,9 @@ get_major_server_version(ClusterInfo *cluster)
 	if (fscanf(version_fd, "%63s", cluster->major_version_str) == 0 ||
 		sscanf(cluster->major_version_str, "%d.%d", &integer_version,
 			   &fractional_version) != 2)
-	{
 		pg_log(PG_FATAL, "could not get version from %s\n", datadir);
-		fclose(version_fd);
-		return 0;
-	}
+
+	fclose(version_fd);
 
 	return (100 * integer_version + fractional_version) * 100;
 }
diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c
index e32153818af..8ba7e98d922 100644
--- a/contrib/pg_upgrade/version.c
+++ b/contrib/pg_upgrade/version.c
@@ -62,10 +62,11 @@ new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		if (!check_mode)
-			fclose(script);
 		report_status(PG_WARNING, "warning");
 		if (check_mode)
 			pg_log(PG_WARNING, "\n"
diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c
index 5b226b218df..3ec4b59a05e 100644
--- a/contrib/pg_upgrade/version_old_8_3.c
+++ b/contrib/pg_upgrade/version_old_8_3.c
@@ -87,9 +87,11 @@ old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		fclose(script);
 		pg_log(PG_REPORT, "fatal\n");
 		pg_log(PG_FATAL,
 			   "| Your installation contains the \"name\" data type in\n"
@@ -175,9 +177,11 @@ old_8_3_check_for_tsquery_usage(ClusterInfo *cluster)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		fclose(script);
 		pg_log(PG_REPORT, "fatal\n");
 		pg_log(PG_FATAL,
 			   "| Your installation contains the \"tsquery\" data type.\n"
@@ -314,10 +318,11 @@ old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		if (!check_mode)
-			fclose(script);
 		report_status(PG_WARNING, "warning");
 		if (check_mode)
 			pg_log(PG_WARNING, "\n"
@@ -424,10 +429,11 @@ old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode)
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		if (!check_mode)
-			fclose(script);
 		report_status(PG_WARNING, "warning");
 		if (check_mode)
 			pg_log(PG_WARNING, "\n"
@@ -553,10 +559,11 @@ old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster,
 		PQfinish(conn);
 	}
 
+	if (script)
+		fclose(script);
+
 	if (found)
 	{
-		if (!check_mode)
-			fclose(script);
 		report_status(PG_WARNING, "warning");
 		if (check_mode)
 			pg_log(PG_WARNING, "\n"
@@ -672,7 +679,8 @@ old_8_3_create_sequence_script(ClusterInfo *cluster)
 
 		PQfinish(conn);
 	}
-	if (found)
+
+	if (script)
 		fclose(script);
 
 	check_ok();
-- 
GitLab