aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-20 17:08:54 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-20 17:12:30 +0200
commit79f21b31074f3790320cb05e1e913360aba1053f (patch)
treee81249990ca2d1562f272c9b7ea6bab736be9fb3 /src
parent5c97528df0053a4f92d020474636bde398f697ec (diff)
downloadpostgresql-79f21b31074f3790320cb05e1e913360aba1053f.tar.gz
postgresql-79f21b31074f3790320cb05e1e913360aba1053f.zip
Fix pg_dumpall with database names containing =
If a database name contained a '=' character, pg_dumpall failed. The problem was in the way pg_dumpall passes the database name to pg_dump on the command line. If it contained a '=' character, pg_dump would interpret it as a libpq connection string instead of a plain database name. To fix, pass the database name to pg_dump as a connection string, "dbname=foo", with the database name escaped if necessary. Back-patch to all supported branches.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dumpall.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 10ce2223df4..5ed8ca1339c 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -49,6 +49,7 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
static void dumpDatabases(PGconn *conn);
static void dumpTimestamp(char *msg);
static void doShellQuoting(PQExpBuffer buf, const char *str);
+static void doConnStrQuoting(PQExpBuffer buf, const char *str);
static int runPgDump(const char *dbname);
static void buildShSecLabels(PGconn *conn, const char *catalog_name,
@@ -1619,6 +1620,7 @@ dumpDatabases(PGconn *conn)
static int
runPgDump(const char *dbname)
{
+ PQExpBuffer connstr = createPQExpBuffer();
PQExpBuffer cmd = createPQExpBuffer();
int ret;
@@ -1634,7 +1636,17 @@ runPgDump(const char *dbname)
else
appendPQExpBuffer(cmd, " -Fp ");
- doShellQuoting(cmd, dbname);
+ /*
+ * Construct a connection string from the database name, like
+ * dbname='<database name>'. pg_dump would usually also accept the
+ * database name as is, but if it contains any = characters, it would
+ * incorrectly treat it as a connection string.
+ */
+ appendPQExpBuffer(connstr, "dbname='");
+ doConnStrQuoting(connstr, dbname);
+ appendPQExpBuffer(connstr, "'");
+
+ doShellQuoting(cmd, connstr->data);
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
@@ -1647,6 +1659,7 @@ runPgDump(const char *dbname)
ret = system(cmd->data);
destroyPQExpBuffer(cmd);
+ destroyPQExpBuffer(connstr);
return ret;
}
@@ -1887,6 +1900,25 @@ dumpTimestamp(char *msg)
/*
+ * Append the given string to the buffer, with suitable quoting for passing
+ * the string as a value, in a keyword/pair value in a libpq connection
+ * string
+ */
+static void
+doConnStrQuoting(PQExpBuffer buf, const char *str)
+{
+ while (*str)
+ {
+ /* ' and \ must be escaped by to \' and \\ */
+ if (*str == '\'' || *str == '\\')
+ appendPQExpBufferChar(buf, '\\');
+
+ appendPQExpBufferChar(buf, *str);
+ str++;
+ }
+}
+
+/*
* Append the given string to the shell command being built in the buffer,
* with suitable shell-style quoting.
*/