From eaca1175e98e937d6b2a9204a53a464fa00d1d56 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 31 May 2006 11:02:42 +0000 Subject: [PATCH] Escape processing patch: o turns off escape_string_warning in pg_dumpall.c o optionally use E'' for \password (undocumented option?) o honor standard_conforming-strings for \copy (but not support literal E'' strings) o optionally use E'' for \d commands o turn off escape_string_warning for createdb, createuser, droplang --- src/bin/pg_dump/pg_dumpall.c | 4 ++- src/bin/psql/command.c | 7 +++--- src/bin/psql/common.h | 8 +++++- src/bin/psql/copy.c | 48 ++++++++++++++++++++---------------- src/bin/psql/describe.c | 6 ++++- src/bin/scripts/createdb.c | 4 ++- src/bin/scripts/createuser.c | 4 ++- src/bin/scripts/droplang.c | 5 ++-- 8 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 74c2e88271..e57f9c5050 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.77 2006/05/28 21:13:54 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.78 2006/05/31 11:02:42 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -338,6 +338,8 @@ main(int argc, char *argv[]) printf("SET client_encoding = '%s';\n", pg_encoding_to_char(encoding)); printf("SET standard_conforming_strings = %s;\n", std_strings); + if (strcmp(std_strings, "off") == 0) + printf("SET escape_string_warning = 'off';\n"); printf("\n"); /* Dump roles (users) */ diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 7dd0cb232e..a060e00abc 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.166 2006/04/02 20:08:22 neilc Exp $ + * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.167 2006/05/31 11:02:42 momjian Exp $ */ #include "postgres_fe.h" #include "command.h" @@ -681,8 +681,9 @@ exec_command(const char *cmd, PGresult *res; initPQExpBuffer(&buf); - printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD '%s';", - fmtId(user), encrypted_password); + printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD %c'%s';", + fmtId(user), NEED_E_STR(encrypted_password), + encrypted_password); res = PSQLexec(buf.data, false); termPQExpBuffer(&buf); if (!res) diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index b12ccdec57..0d0f7ad5ed 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.47 2006/03/06 19:49:20 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/common.h,v 1.48 2006/05/31 11:02:42 momjian Exp $ */ #ifndef COMMON_H #define COMMON_H @@ -22,6 +22,12 @@ #define atooid(x) ((Oid) strtoul((x), NULL, 10)) +/* + * We use this to prefix strings with E'' that we know are already safe, + * so we don't get an escape_string_warning. + */ +#define NEED_E_STR(str) ((strchr(str, '\\') && !standard_strings()) ? ESCAPE_STRING_SYNTAX : ' ') + /* * Safer versions of some standard C library functions. If an * out-of-memory condition occurs, these functions will bail out diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 1c3d812abd..15a3883cdd 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.61 2006/05/26 19:51:29 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.62 2006/05/31 11:02:42 momjian Exp $ */ #include "postgres_fe.h" #include "copy.h" @@ -216,7 +216,7 @@ parse_slash_copy(const char *args) goto error; token = strtokx(NULL, whitespace, NULL, "'", - '\\', true, pset.encoding); + standard_strings() ? 0 : '\\', true, pset.encoding); if (!token) goto error; @@ -255,7 +255,7 @@ parse_slash_copy(const char *args) if (token && pg_strcasecmp(token, "delimiters") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (!token) goto error; result->delim = pg_strdup(token); @@ -290,10 +290,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "delimiter") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token) result->delim = pg_strdup(token); else @@ -302,10 +302,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "null") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token) result->null = pg_strdup(token); else @@ -314,10 +314,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "quote") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token) result->quote = pg_strdup(token); else @@ -326,10 +326,10 @@ parse_slash_copy(const char *args) else if (pg_strcasecmp(token, "escape") == 0) { token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token && pg_strcasecmp(token, "as") == 0) token = strtokx(NULL, whitespace, NULL, "'", - '\\', false, pset.encoding); + standard_strings() ? 0 : '\\', false, pset.encoding); if (token) result->escape = pg_strdup(token); else @@ -462,20 +462,22 @@ do_copy(const char *args) if (options->delim) { if (options->delim[0] == '\'') - appendPQExpBuffer(&query, " USING DELIMITERS %s", - options->delim); + appendPQExpBuffer(&query, " USING DELIMITERS %c%s", + NEED_E_STR(options->delim), options->delim); else - appendPQExpBuffer(&query, " USING DELIMITERS '%s'", - options->delim); + appendPQExpBuffer(&query, " USING DELIMITERS %c'%s'", + NEED_E_STR(options->delim), options->delim); } /* There is no backward-compatible CSV syntax */ if (options->null) { if (options->null[0] == '\'') - appendPQExpBuffer(&query, " WITH NULL AS %s", options->null); + appendPQExpBuffer(&query, " WITH NULL AS %c%s", + NEED_E_STR(options->null), options->null); else - appendPQExpBuffer(&query, " WITH NULL AS '%s'", options->null); + appendPQExpBuffer(&query, " WITH NULL AS %c'%s'", + NEED_E_STR(options->null), options->null); } if (options->csv_mode) @@ -487,17 +489,21 @@ do_copy(const char *args) if (options->quote) { if (options->quote[0] == '\'') - appendPQExpBuffer(&query, " QUOTE AS %s", options->quote); + appendPQExpBuffer(&query, " QUOTE AS %c%s", + NEED_E_STR(options->quote), options->quote); else - appendPQExpBuffer(&query, " QUOTE AS '%s'", options->quote); + appendPQExpBuffer(&query, " QUOTE AS %c'%s'", + NEED_E_STR(options->quote), options->quote); } if (options->escape) { if (options->escape[0] == '\'') - appendPQExpBuffer(&query, " ESCAPE AS %s", options->escape); + appendPQExpBuffer(&query, " ESCAPE AS %c%s", + NEED_E_STR(options->escape), options->escape); else - appendPQExpBuffer(&query, " ESCAPE AS '%s'", options->escape); + appendPQExpBuffer(&query, " ESCAPE AS %c'%s'", + NEED_E_STR(options->escape), options->escape); } if (options->force_quote_list) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 2159c5c715..b6a462c3c9 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.137 2006/05/28 21:13:54 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.138 2006/05/31 11:02:42 momjian Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -1907,14 +1907,17 @@ processNamePattern(PQExpBuffer buf, const char *pattern, if (altnamevar) { appendPQExpBuffer(buf, "(%s ~ ", namevar); + appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBuffer(buf, "\n OR %s ~ ", altnamevar); + appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBuffer(buf, ")\n"); } else { appendPQExpBuffer(buf, "%s ~ ", namevar); + appendPQExpBufferChar(buf, NEED_E_STR(namebuf.data)); appendStringLiteralConn(buf, namebuf.data, pset.db); appendPQExpBufferChar(buf, '\n'); } @@ -1938,6 +1941,7 @@ processNamePattern(PQExpBuffer buf, const char *pattern, { WHEREAND(); appendPQExpBuffer(buf, "%s ~ ", schemavar); + appendPQExpBufferChar(buf, NEED_E_STR(schemabuf.data)); appendStringLiteralConn(buf, schemabuf.data, pset.db); appendPQExpBufferChar(buf, '\n'); } diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c index f68da36498..c023a12bd9 100644 --- a/src/bin/scripts/createdb.c +++ b/src/bin/scripts/createdb.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.19 2006/05/29 19:52:46 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/scripts/createdb.c,v 1.20 2006/05/31 11:02:42 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -185,6 +185,8 @@ main(int argc, char *argv[]) { conn = connectDatabase(dbname, host, port, username, password, progname); + executeCommand(conn, "SET escape_string_warning TO 'off'", progname, false); + printfPQExpBuffer(&sql, "COMMENT ON DATABASE %s IS ", fmtId(dbname)); appendStringLiteralConn(&sql, comment, conn); appendPQExpBuffer(&sql, ";\n"); diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index bf618eea18..17b3407a3a 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.30 2006/05/29 19:52:46 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.31 2006/05/31 11:02:42 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -243,6 +243,8 @@ main(int argc, char *argv[]) printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser)); if (newpassword) { + executeCommand(conn, "SET escape_string_warning TO 'off'", progname, false); + if (encrypted == TRI_YES) appendPQExpBuffer(&sql, " ENCRYPTED"); if (encrypted == TRI_NO) diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c index 1465e504f6..c110147929 100644 --- a/src/bin/scripts/droplang.c +++ b/src/bin/scripts/droplang.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.20 2006/05/29 19:52:46 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.21 2006/05/31 11:02:42 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -176,8 +176,7 @@ main(int argc, char *argv[]) * Force schema search path to be just pg_catalog, so that we don't have * to be paranoid about search paths below. */ - executeCommand(conn, "SET search_path = pg_catalog;", - progname, echo); + executeCommand(conn, "SET search_path = pg_catalog;", progname, echo); /* * Make sure the language is installed and find the OIDs of the handler