summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Misch2016-08-08 14:07:53 +0000
committerNoah Misch2016-08-08 14:07:53 +0000
commita19edcd2407d7dc8677513d1770e41b11a851163 (patch)
tree36685b2e5c7f794409d3069cdcca28875457ddcf
parent4837155292f67f10576f3d7204ffd5379bbe3a7b (diff)
Back-patch "Only quote libpq connection string values that need quoting."
Back-patch commit 2953cd6d17210935098c803c52c6df5b12a725b9 and certain runPgDump() bits of 3dee636e0404885d07885d41c0d70e50c784f324 to 9.2 and 9.1. This synchronizes their doConnStrQuoting() implementations with later releases. Subsequent security patches will modify that function. Security: CVE-2016-5424
-rw-r--r--src/bin/pg_dump/pg_dumpall.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 47fb7008462..2c46b5ee90b 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1656,7 +1656,7 @@ dumpDatabases(PGconn *conn)
static int
runPgDump(const char *dbname)
{
- PQExpBuffer connstr = createPQExpBuffer();
+ PQExpBuffer connstrbuf = createPQExpBuffer();
PQExpBuffer cmd = createPQExpBuffer();
int ret;
@@ -1678,11 +1678,10 @@ runPgDump(const char *dbname)
* 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, "'");
+ appendPQExpBufferStr(connstrbuf, "dbname=");
+ doConnStrQuoting(connstrbuf, dbname);
- doShellQuoting(cmd, connstr->data);
+ doShellQuoting(cmd, connstrbuf->data);
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
@@ -1695,7 +1694,7 @@ runPgDump(const char *dbname)
ret = system(cmd->data);
destroyPQExpBuffer(cmd);
- destroyPQExpBuffer(connstr);
+ destroyPQExpBuffer(connstrbuf);
return ret;
}
@@ -1943,15 +1942,40 @@ dumpTimestamp(char *msg)
static void
doConnStrQuoting(PQExpBuffer buf, const char *str)
{
- while (*str)
+ const char *s;
+ bool needquotes;
+
+ /*
+ * If the string consists entirely of plain ASCII characters, no need to
+ * quote it. This is quite conservative, but better safe than sorry.
+ */
+ needquotes = false;
+ for (s = str; *s; s++)
+ {
+ if (!((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
+ (*s >= '0' && *s <= '9') || *s == '_' || *s == '.'))
+ {
+ needquotes = true;
+ break;
+ }
+ }
+
+ if (needquotes)
{
- /* ' and \ must be escaped by to \' and \\ */
- if (*str == '\'' || *str == '\\')
- appendPQExpBufferChar(buf, '\\');
+ appendPQExpBufferChar(buf, '\'');
+ while (*str)
+ {
+ /* ' and \ must be escaped by to \' and \\ */
+ if (*str == '\'' || *str == '\\')
+ appendPQExpBufferChar(buf, '\\');
- appendPQExpBufferChar(buf, *str);
- str++;
+ appendPQExpBufferChar(buf, *str);
+ str++;
+ }
+ appendPQExpBufferChar(buf, '\'');
}
+ else
+ appendPQExpBufferStr(buf, str);
}
/*