aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/genbki.pl13
-rw-r--r--src/bin/initdb/initdb.c63
-rw-r--r--src/include/catalog/pg_authid.dat5
-rw-r--r--src/include/catalog/pg_database.dat5
-rw-r--r--src/include/catalog/pg_proc.dat12
5 files changed, 77 insertions, 21 deletions
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index b750ec9f0ac..938686f0ca7 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -660,12 +660,19 @@ sub print_bki_insert
# since that represents a NUL char in C code.
$bki_value = '' if $bki_value eq '\0';
+ # Handle single quotes by doubling them, and double quotes by
+ # converting them to octal escapes, because that's what the
+ # bootstrap scanner requires. We do not process backslashes
+ # specially; this allows escape-string-style backslash escapes
+ # to be used in catalog data.
+ $bki_value =~ s/'/''/g;
+ $bki_value =~ s/"/\\042/g;
+
# Quote value if needed. We need not quote values that satisfy
# the "id" pattern in bootscanner.l, currently "[-A-Za-z0-9_]+".
$bki_value = sprintf(qq'"%s"', $bki_value)
- if $bki_value !~ /^"[^"]+"$/
- and ( length($bki_value) == 0
- or $bki_value =~ /[^-A-Za-z0-9_]/);
+ if length($bki_value) == 0
+ or $bki_value =~ /[^-A-Za-z0-9_]/;
push @bki_values, $bki_value;
}
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 4907a379038..b39115c346d 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -265,6 +265,7 @@ static void make_postgres(FILE *cmdfd);
static void trapsig(int signum);
static void check_ok(void);
static char *escape_quotes(const char *src);
+static char *escape_quotes_bki(const char *src);
static int locale_date_order(const char *locale);
static void check_locale_name(int category, const char *locale,
char **canonname);
@@ -324,6 +325,10 @@ do { \
output_failed = true, output_errno = errno; \
} while (0)
+/*
+ * Escape single quotes and backslashes, suitably for insertions into
+ * configuration files or SQL E'' strings.
+ */
static char *
escape_quotes(const char *src)
{
@@ -338,6 +343,52 @@ escape_quotes(const char *src)
}
/*
+ * Escape a field value to be inserted into the BKI data.
+ * Here, we first run the value through escape_quotes (which
+ * will be inverted by the backend's scanstr() function) and
+ * then overlay special processing of double quotes, which
+ * bootscanner.l will only accept as data if converted to octal
+ * representation ("\042"). We always wrap the value in double
+ * quotes, even if that isn't strictly necessary.
+ */
+static char *
+escape_quotes_bki(const char *src)
+{
+ char *result;
+ char *data = escape_quotes(src);
+ char *resultp;
+ char *datap;
+ int nquotes = 0;
+
+ /* count double quotes in data */
+ datap = data;
+ while ((datap = strchr(datap, '"')) != NULL)
+ {
+ nquotes++;
+ datap++;
+ }
+
+ result = (char *) pg_malloc(strlen(data) + 3 + nquotes * 3);
+ resultp = result;
+ *resultp++ = '"';
+ for (datap = data; *datap; datap++)
+ {
+ if (*datap == '"')
+ {
+ strcpy(resultp, "\\042");
+ resultp += 4;
+ }
+ else
+ *resultp++ = *datap;
+ }
+ *resultp++ = '"';
+ *resultp = '\0';
+
+ free(data);
+ return result;
+}
+
+/*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
*
@@ -1368,13 +1419,17 @@ bootstrap_template1(void)
bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
FLOAT8PASSBYVAL ? "true" : "false");
- bki_lines = replace_token(bki_lines, "POSTGRES", escape_quotes(username));
+ bki_lines = replace_token(bki_lines, "POSTGRES",
+ escape_quotes_bki(username));
- bki_lines = replace_token(bki_lines, "ENCODING", encodingid_to_string(encodingid));
+ bki_lines = replace_token(bki_lines, "ENCODING",
+ encodingid_to_string(encodingid));
- bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate));
+ bki_lines = replace_token(bki_lines, "LC_COLLATE",
+ escape_quotes_bki(lc_collate));
- bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype));
+ bki_lines = replace_token(bki_lines, "LC_CTYPE",
+ escape_quotes_bki(lc_ctype));
/*
* Pass correct LC_xxx environment to bootstrap.
diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat
index 52f42595600..d8421b01627 100644
--- a/src/include/catalog/pg_authid.dat
+++ b/src/include/catalog/pg_authid.dat
@@ -12,14 +12,11 @@
[
-# POSTGRES will be replaced at initdb time with a user choice that might
-# contain non-word characters, so we must double-quote it.
-
# The C code typically refers to these roles using the #define symbols,
# so make sure every entry has an oid_symbol value.
{ oid => '10', oid_symbol => 'BOOTSTRAP_SUPERUSERID',
- rolname => '"POSTGRES"', rolsuper => 't', rolinherit => 't',
+ rolname => 'POSTGRES', rolsuper => 't', rolinherit => 't',
rolcreaterole => 't', rolcreatedb => 't', rolcanlogin => 't',
rolreplication => 't', rolbypassrls => 't', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat
index 957ca8408a5..002075685cc 100644
--- a/src/include/catalog/pg_database.dat
+++ b/src/include/catalog/pg_database.dat
@@ -12,13 +12,10 @@
[
-# LC_COLLATE and LC_CTYPE will be replaced at initdb time with user choices
-# that might contain non-word characters, so we must double-quote them.
-
{ oid => '1', oid_symbol => 'TemplateDbOid',
descr => 'default template for new databases',
datname => 'template1', datdba => 'PGUID', encoding => 'ENCODING',
- datcollate => '"LC_COLLATE"', datctype => '"LC_CTYPE"', datistemplate => 't',
+ datcollate => 'LC_COLLATE', datctype => 'LC_CTYPE', datistemplate => 't',
datallowconn => 't', datconnlimit => '-1', datlastsysoid => '0',
datfrozenxid => '0', datminmxid => '1', dattablespace => '1663',
datacl => '_null_' },
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 3c56ef6abcc..9b53855236f 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -2417,7 +2417,7 @@
{ oid => '1216', descr => 'get description for table column',
proname => 'col_description', prolang => '14', procost => '100',
provolatile => 's', prorettype => 'text', proargtypes => 'oid int4',
- prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = \'\'pg_catalog.pg_class\'\'::pg_catalog.regclass and objsubid = $2' },
+ prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = \'pg_catalog.pg_class\'::pg_catalog.regclass and objsubid = $2' },
{ oid => '1993',
descr => 'get description for object id and shared catalog name',
proname => 'shobj_description', prolang => '14', procost => '100',
@@ -3483,11 +3483,11 @@
{ oid => '879', descr => 'left-pad string to length',
proname => 'lpad', prolang => '14', prorettype => 'text',
proargtypes => 'text int4',
- prosrc => 'select pg_catalog.lpad($1, $2, \'\' \'\')' },
+ prosrc => 'select pg_catalog.lpad($1, $2, \' \')' },
{ oid => '880', descr => 'right-pad string to length',
proname => 'rpad', prolang => '14', prorettype => 'text',
proargtypes => 'text int4',
- prosrc => 'select pg_catalog.rpad($1, $2, \'\' \'\')' },
+ prosrc => 'select pg_catalog.rpad($1, $2, \' \')' },
{ oid => '881', descr => 'trim spaces from left end of string',
proname => 'ltrim', prorettype => 'text', proargtypes => 'text',
prosrc => 'ltrim1' },
@@ -6930,7 +6930,7 @@
descr => 'disk space usage for the main fork of the specified table or index',
proname => 'pg_relation_size', prolang => '14', provolatile => 'v',
prorettype => 'int8', proargtypes => 'regclass',
- prosrc => 'select pg_catalog.pg_relation_size($1, \'\'main\'\')' },
+ prosrc => 'select pg_catalog.pg_relation_size($1, \'main\')' },
{ oid => '2332',
descr => 'disk space usage for the specified fork of a table or index',
proname => 'pg_relation_size', provolatile => 'v', prorettype => 'int8',
@@ -8168,7 +8168,7 @@
{ oid => '2932', descr => 'evaluate XPath expression',
proname => 'xpath', prolang => '14', prorettype => '_xml',
proargtypes => 'text xml',
- prosrc => 'select pg_catalog.xpath($1, $2, \'\'{}\'\'::pg_catalog.text[])' },
+ prosrc => 'select pg_catalog.xpath($1, $2, \'{}\'::pg_catalog.text[])' },
{ oid => '2614', descr => 'test XML value against XPath expression',
proname => 'xmlexists', prorettype => 'bool', proargtypes => 'text xml',
@@ -8181,7 +8181,7 @@
{ oid => '3050', descr => 'test XML value against XPath expression',
proname => 'xpath_exists', prolang => '14', prorettype => 'bool',
proargtypes => 'text xml',
- prosrc => 'select pg_catalog.xpath_exists($1, $2, \'\'{}\'\'::pg_catalog.text[])' },
+ prosrc => 'select pg_catalog.xpath_exists($1, $2, \'{}\'::pg_catalog.text[])' },
{ oid => '3051', descr => 'determine if a string is well formed XML',
proname => 'xml_is_well_formed', provolatile => 's', prorettype => 'bool',
proargtypes => 'text', prosrc => 'xml_is_well_formed' },