Skip to content

Commit 957bafb

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 23ef963 commit 957bafb

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,
@@ -1583,6 +1584,7 @@ dumpDatabases(PGconn *conn)
15831584
static int
15841585
runPgDump(const char *dbname)
15851586
{
1587+
PQExpBuffer connstr = createPQExpBuffer();
15861588
PQExpBuffer cmd = createPQExpBuffer();
15871589
int ret;
15881590

@@ -1598,7 +1600,17 @@ runPgDump(const char *dbname)
15981600
else
15991601
appendPQExpBuffer(cmd, " -Fp ");
16001602

1601-
doShellQuoting(cmd, dbname);
1603+
/*
1604+
* Construct a connection string from the database name, like
1605+
* dbname='<database name>'. pg_dump would usually also accept the
1606+
* database name as is, but if it contains any = characters, it would
1607+
* incorrectly treat it as a connection string.
1608+
*/
1609+
appendPQExpBuffer(connstr, "dbname='");
1610+
doConnStrQuoting(connstr, dbname);
1611+
appendPQExpBuffer(connstr, "'");
1612+
1613+
doShellQuoting(cmd, connstr->data);
16021614

16031615
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
16041616

@@ -1611,6 +1623,7 @@ runPgDump(const char *dbname)
16111623
ret = system(cmd->data);
16121624

16131625
destroyPQExpBuffer(cmd);
1626+
destroyPQExpBuffer(connstr);
16141627

16151628
return ret;
16161629
}
@@ -1834,6 +1847,25 @@ dumpTimestamp(char *msg)
18341847
}
18351848

18361849

1850+
/*
1851+
* Append the given string to the buffer, with suitable quoting for passing
1852+
* the string as a value, in a keyword/pair value in a libpq connection
1853+
* string
1854+
*/
1855+
static void
1856+
doConnStrQuoting(PQExpBuffer buf, const char *str)
1857+
{
1858+
while (*str)
1859+
{
1860+
/* ' and \ must be escaped by to \' and \\ */
1861+
if (*str == '\'' || *str == '\\')
1862+
appendPQExpBufferChar(buf, '\\');
1863+
1864+
appendPQExpBufferChar(buf, *str);
1865+
str++;
1866+
}
1867+
}
1868+
18371869
/*
18381870
* Append the given string to the shell command being built in the buffer,
18391871
* with suitable shell-style quoting.

0 commit comments

Comments
 (0)