From a973296598f2d1eec48138a2ce4f3e63410d9ed0 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Wed, 15 Aug 2012 11:23:04 -0400
Subject: [PATCH] Properly escape usernames in initdb, so names with
 single-quotes are supported.  Also add assert to catch future breakage.

Also, improve documentation that "double"-quotes must be used in
pg_hba.conf (not single quotes).
---
 doc/src/sgml/client-auth.sgml | 2 +-
 src/backend/parser/scansup.c  | 2 ++
 src/bin/initdb/initdb.c       | 7 +++----
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 679c40a64ec..97713948df6 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -80,7 +80,7 @@
    Records cannot be continued across lines.
    A record is made
    up of a number of fields which are separated by spaces and/or tabs.
-   Fields can contain white space if the field value is quoted.
+   Fields can contain white space if the field value is double-quoted.
    Quoting one of the keywords in a database, user, or address field (e.g.,
    <literal>all</> or <literal>replication</>) makes the word lose its special
    character, and just match a database, user, or host with that name.
diff --git a/src/backend/parser/scansup.c b/src/backend/parser/scansup.c
index 6101457a109..b8e2f71d656 100644
--- a/src/backend/parser/scansup.c
+++ b/src/backend/parser/scansup.c
@@ -56,6 +56,8 @@ scanstr(const char *s)
 			 * appear in pairs, so there should be another character.
 			 */
 			i++;
+			/* The bootstrap parser is not as smart, so check here. */
+			Assert(s[i] == '\'');
 			newStr[j] = s[i];
 		}
 		else if (s[i] == '\\')
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 132ad0fa4cd..a53760af85c 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1395,7 +1395,7 @@ bootstrap_template1(void)
 	bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
 							  FLOAT8PASSBYVAL ? "true" : "false");
 
-	bki_lines = replace_token(bki_lines, "POSTGRES", username);
+	bki_lines = replace_token(bki_lines, "POSTGRES", escape_quotes(username));
 
 	bki_lines = replace_token(bki_lines, "ENCODING", encodingid);
 
@@ -2043,8 +2043,8 @@ setup_privileges(void)
 
 	PG_CMD_OPEN;
 
-	priv_lines = replace_token(privileges_setup,
-							   "$POSTGRES_SUPERUSERNAME", username);
+	priv_lines = replace_token(privileges_setup, "$POSTGRES_SUPERUSERNAME",
+							   escape_quotes(username));
 	for (line = priv_lines; *line != NULL; line++)
 		PG_CMD_PUTS(*line);
 
@@ -3056,7 +3056,6 @@ main(int argc, char *argv[])
 	canonicalize_path(pg_data);
 
 #ifdef WIN32
-
 	/*
 	 * Before we execute another program, make sure that we are running with a
 	 * restricted token. If not, re-execute ourselves with one.
-- 
GitLab