diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-20 17:08:54 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-20 17:12:27 +0200 |
commit | 957bafb2091136161cb7f1a8a56439310c6bd1b2 (patch) | |
tree | b054be897628d49e2a8258178224e2f4a88a8832 /src | |
parent | 23ef96327f9ea2a0213d05831175a3ac1b472f29 (diff) |
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.c | 34 |
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 b3ad2eac29b..d50561f88b2 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -50,6 +50,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 PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport, @@ -1583,6 +1584,7 @@ dumpDatabases(PGconn *conn) static int runPgDump(const char *dbname) { + PQExpBuffer connstr = createPQExpBuffer(); PQExpBuffer cmd = createPQExpBuffer(); int ret; @@ -1598,7 +1600,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); @@ -1611,6 +1623,7 @@ runPgDump(const char *dbname) ret = system(cmd->data); destroyPQExpBuffer(cmd); + destroyPQExpBuffer(connstr); return ret; } @@ -1835,6 +1848,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. */ |