From 640b6b63ddc1c79b1013ba7f4956f8a0d62c40ae Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Date: Thu, 8 Jul 2021 17:10:19 +0900
Subject: [PATCH v3 2/3] Make complain for invalid numeirc values in
 environemnt variables

Postgresql commands that read environment variables for integer values
are tolerant of trailing garbages like '5432xyz'. Ignore such values
and make warning on it.
---
 src/bin/pg_ctl/pg_ctl.c     | 12 +++++++++++-
 src/bin/pg_upgrade/option.c | 32 ++++++++++++++++++++++++++++++--
 src/bin/psql/startup.c      | 17 ++++++++++++++++-
 3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 0f72ef016b..0c5dba5ecf 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -2319,7 +2319,17 @@ main(int argc, char **argv)
 
 	env_wait = getenv("PGCTLTIMEOUT");
 	if (env_wait != NULL)
-		wait_seconds = atoi(env_wait);
+	{
+		char *endptr;
+		int tmp_wait;
+
+		errno = 0;
+		tmp_wait = strtoint(env_wait, &endptr, 10);
+		if (*endptr || errno == ERANGE || tmp_wait < 0)
+			write_stderr(_("%s: ignored invalid setting of environment variable PGCTLTIMEOUT: %s\n"), progname, env_wait);
+		else
+			wait_seconds = tmp_wait;
+	}
 
 	/*
 	 * 'Action' can be before or after args so loop over both. Some
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
index c014bbca0d..0acb6b7cdc 100644
--- a/src/bin/pg_upgrade/option.c
+++ b/src/bin/pg_upgrade/option.c
@@ -71,8 +71,36 @@ parseCommandLine(int argc, char *argv[])
 	os_info.progname = get_progname(argv[0]);
 
 	/* Process libpq env. variables; load values here for usage() output */
-	old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT;
-	new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT;
+	old_cluster.port = new_cluster.port = DEF_PGUPORT;
+	if (getenv("PGPORTOLD"))
+	{
+		char	   *endptr;
+		int			port;
+
+		errno = 0;
+		port = strtoint(getenv("PGPORTOLD"), &endptr, 10);
+		if (*endptr || errno == ERANGE || port < 1)
+			pg_log(PG_WARNING,
+				   "%s: ignored invalid setting of environment variable PGPORTOLD: %s\n",
+					 os_info.progname, getenv("PGPORTOLD"));
+		else
+			old_cluster.port = port;
+	}
+
+	if (getenv("PGPORTNEW"))
+	{
+		char	   *endptr;
+		int			port;
+
+		errno = 0;
+		port = strtoint(getenv("PGPORTNEW"), &endptr, 10);
+		if (*endptr || errno == ERANGE || port < 1)
+			pg_log(PG_WARNING,
+				   "%s: ignored invalid setting of environment variable PGPORTNEW: %s\n",
+					 os_info.progname, getenv("PGPORTNEW"));
+		else
+			new_cluster.port = port;
+	}
 
 	os_user_effective_id = get_user_info(&os_info.user);
 	/* we override just the database user name;  we got the OS id above */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5f36f0d1c6..35ccabce77 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -181,7 +181,22 @@ main(int argc, char *argv[])
 	refresh_utf8format(&(pset.popt.topt));
 
 	/* We must get COLUMNS here before readline() sets it */
-	pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
+	pset.popt.topt.env_columns = 0;
+	if (getenv("COLUMNS"))
+	{
+		char   *endptr;
+		int		cols;
+
+		errno = 0;
+		cols = strtoint(getenv("COLUMNS"), &endptr, 10);
+		if (*endptr || errno == ERANGE || cols < 0)
+		{
+			pg_log_warning("ignored invalid setting of environemt variable COLUMNS: %s",
+						 getenv("COLUMNS"));
+		}
+
+		pset.popt.topt.env_columns = cols;
+	}
 
 	pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout)));
 
-- 
2.27.0

