Skip to content

Commit 8b4ced4

Browse files
committed
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.
1 parent feae7c3 commit 8b4ced4

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/bin/pg_dump/pg_dumpall.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
5050
static void dumpDatabases(PGconn *conn);
5151
static void dumpTimestamp(char *msg);
5252
static void doShellQuoting(PQExpBuffer buf, const char *str);
53+
static void doConnStrQuoting(PQExpBuffer buf, const char *str);
5354

5455
static int runPgDump(const char *dbname);
5556
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
@@ -1560,6 +1561,7 @@ dumpDatabases(PGconn *conn)
15601561
static int
15611562
runPgDump(const char *dbname)
15621563
{
1564+
PQExpBuffer connstr = createPQExpBuffer();
15631565
PQExpBuffer cmd = createPQExpBuffer();
15641566
int ret;
15651567

@@ -1575,7 +1577,17 @@ runPgDump(const char *dbname)
15751577
else
15761578
appendPQExpBuffer(cmd, " -Fp ");
15771579

1578-
doShellQuoting(cmd, dbname);
1580+
/*
1581+
* Construct a connection string from the database name, like
1582+
* dbname='<database name>'. pg_dump would usually also accept the
1583+
* database name as is, but if it contains any = characters, it would
1584+
* incorrectly treat it as a connection string.
1585+
*/
1586+
appendPQExpBuffer(connstr, "dbname='");
1587+
doConnStrQuoting(connstr, dbname);
1588+
appendPQExpBuffer(connstr, "'");
1589+
1590+
doShellQuoting(cmd, connstr->data);
15791591

15801592
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
15811593

@@ -1588,6 +1600,7 @@ runPgDump(const char *dbname)
15881600
ret = system(cmd->data);
15891601

15901602
destroyPQExpBuffer(cmd);
1603+
destroyPQExpBuffer(connstr);
15911604

15921605
return ret;
15931606
}
@@ -1811,6 +1824,25 @@ dumpTimestamp(char *msg)
18111824
}
18121825

18131826

1827+
/*
1828+
* Append the given string to the buffer, with suitable quoting for passing
1829+
* the string as a value, in a keyword/pair value in a libpq connection
1830+
* string
1831+
*/
1832+
static void
1833+
doConnStrQuoting(PQExpBuffer buf, const char *str)
1834+
{
1835+
while (*str)
1836+
{
1837+
/* ' and \ must be escaped by to \' and \\ */
1838+
if (*str == '\'' || *str == '\\')
1839+
appendPQExpBufferChar(buf, '\\');
1840+
1841+
appendPQExpBufferChar(buf, *str);
1842+
str++;
1843+
}
1844+
}
1845+
18141846
/*
18151847
* Append the given string to the shell command being built in the buffer,
18161848
* with suitable shell-style quoting.

0 commit comments

Comments
 (0)