summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/runtime.sgml31
-rw-r--r--src/backend/parser/scan.l18
-rw-r--r--src/backend/utils/misc/guc.c37
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample3
-rw-r--r--src/bin/psql/tab-complete.c3
-rw-r--r--src/include/parser/gramparse.h13
6 files changed, 99 insertions, 6 deletions
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index f77ee8e035a..718e90d8f85 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.147.2.7 2003/04/04 00:32:57 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.147.2.8 2006/05/21 20:12:20 tgl Exp $
-->
<Chapter Id="runtime">
@@ -1318,6 +1318,35 @@ env PGOPTIONS='-c geqo=off' psql
</listitem>
</varlistentry>
+ <varlistentry id="guc-backslash-quote" xreflabel="backslash_quote">
+ <term><varname>BACKSLASH_QUOTE</varname> (<type>string</type>)</term>
+ <indexterm><primary>strings</><secondary>backslash quotes</></>
+ <indexterm>
+ <primary><varname>backslash_quote</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ This controls whether a quote mark can be represented by
+ <literal>\'</> in a string literal. The preferred, SQL-standard way
+ to represent a quote mark is by doubling it (<literal>''</>) but
+ <productname>PostgreSQL</> has historically also accepted
+ <literal>\'</>. However, use of <literal>\'</> creates security risks
+ because in some client character set encodings, there are multibyte
+ characters in which the last byte is numerically equivalent to ASCII
+ <literal>\</>. If client-side code does escaping incorrectly then a
+ SQL-injection attack is possible. This risk can be prevented by
+ making the server reject queries in which a quote mark appears to be
+ escaped by a backslash.
+ The allowed values of <varname>backslash_quote</> are
+ <literal>on</> (allow <literal>\'</> always),
+ <literal>off</> (reject always), and
+ <literal>safe_encoding</> (allow only if client encoding does not
+ allow ASCII <literal>\</> within a multibyte character).
+ <literal>safe_encoding</> is the default setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>CLIENT_ENCODING</varname> (<type>string</type>)</term>
<indexterm><primary>character set encoding</></>
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index a902e2828d8..d8fda9a2ca5 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.102.2.2 2005/08/16 00:48:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.102.2.3 2006/05/21 20:12:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,6 +40,15 @@ extern YYSTYPE yylval;
static int xcdepth = 0; /* depth of nesting in slash-star comments */
/*
+ * GUC variables. This is a DIRECT violation of the warning given at the
+ * head of gram.y, ie flex/bison code must not depend on any GUC variables;
+ * as such, changing their values can induce very unintuitive behavior.
+ * But we shall have to live with it as a short-term thing until the switch
+ * to SQL-standard string syntax is complete.
+ */
+BackslashQuoteType backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING;
+
+/*
* literalbuf is used to accumulate literal values when multiple rules
* are needed to parse a single literal. Call startlit to reset buffer
* to empty, addlit to add text. Note that the buffer is palloc'd and
@@ -376,6 +385,13 @@ other .
addlit(yytext, yyleng);
}
<xq>{xqescape} {
+ if (yytext[1] == '\'')
+ {
+ if (backslash_quote == BACKSLASH_QUOTE_OFF ||
+ (backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&
+ PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))
+ elog(ERROR, "unsafe use of \\' in a string literal");
+ }
addlitchar(unescape_single_char(yytext[1]));
}
<xq>{xqoctesc} {
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index af64f0ad34f..4f723c42dbb 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5,7 +5,7 @@
* command, configuration file, and command line options.
* See src/backend/utils/misc/README for more information.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.99.2.6 2006/02/12 22:33:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.99.2.7 2006/05/21 20:12:20 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -38,6 +38,7 @@
#include "optimizer/geqo.h"
#include "optimizer/paths.h"
#include "optimizer/planmain.h"
+#include "parser/gramparse.h"
#include "parser/parse_expr.h"
#include "storage/fd.h"
#include "storage/freespace.h"
@@ -72,6 +73,8 @@ static const char *assign_facility(const char *facility,
static const char *assign_msglvl(int *var, const char *newval,
bool doit, bool interactive);
+static const char *assign_backslash_quote(const char *newval, bool doit,
+ bool interactive);
/*
* Debugging options
@@ -124,6 +127,7 @@ const char client_min_messages_str_default[] = "notice";
* and is kept in sync by assign_hooks.
*/
static double phony_random_seed;
+static char *backslash_quote_string;
static char *client_encoding_string;
static char *datestyle_string;
static char *default_iso_level_string;
@@ -737,6 +741,11 @@ static struct config_string
ConfigureNamesString[] =
{
{
+ {"backslash_quote", PGC_USERSET}, &backslash_quote_string,
+ "safe_encoding", assign_backslash_quote, NULL
+ },
+
+ {
{"client_encoding", PGC_USERSET, GUC_IS_NAME}, &client_encoding_string,
"SQL_ASCII", assign_client_encoding, NULL
},
@@ -3060,4 +3069,30 @@ assign_msglvl(int *var, const char *newval, bool doit, bool interactive)
return newval; /* OK */
}
+static const char *
+assign_backslash_quote(const char *newval, bool doit, bool interactive)
+{
+ BackslashQuoteType bq;
+ bool bqbool;
+
+ /*
+ * Although only "on", "off", and "safe_encoding" are documented,
+ * we use parse_bool so we can accept all the likely variants of
+ * "on" and "off".
+ */
+ if (strcasecmp(newval, "safe_encoding") == 0)
+ bq = BACKSLASH_QUOTE_SAFE_ENCODING;
+ else if (parse_bool(newval, &bqbool))
+ {
+ bq = bqbool ? BACKSLASH_QUOTE_ON : BACKSLASH_QUOTE_OFF;
+ }
+ else
+ return NULL; /* reject */
+
+ if (doit)
+ backslash_quote = bq;
+
+ return newval;
+}
+
#include "guc-file.c"
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index d34a22939e6..e974a811167 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -206,4 +206,5 @@
#transform_null_equals = false
#statement_timeout = 0 # 0 is disabled, in milliseconds
#db_user_namespace = false
-
+#backslash_quote = safe_encoding # on, off, or safe_encoding
+
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index ce4a2b5a809..b7f3c33a00a 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.64 2002/09/04 20:31:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.64.2.1 2006/05/21 20:12:20 tgl Exp $
*/
/*----------------------------------------------------------------------
@@ -269,6 +269,7 @@ psql_completion(char *text, int start, int end)
"cpu_operator_cost",
"geqo_selection_bias",
+ "backslash_quote",
"default_transaction_isolation",
"search_path",
"statement_timeout",
diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h
index 97a91093e23..dd08e95c404 100644
--- a/src/include/parser/gramparse.h
+++ b/src/include/parser/gramparse.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: gramparse.h,v 1.25 2002/09/04 20:31:45 momjian Exp $
+ * $Id: gramparse.h,v 1.25.2.1 2006/05/21 20:12:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,6 +18,17 @@
#include "lib/stringinfo.h"
#include "nodes/parsenodes.h"
+typedef enum
+{
+ BACKSLASH_QUOTE_OFF,
+ BACKSLASH_QUOTE_ON,
+ BACKSLASH_QUOTE_SAFE_ENCODING
+} BackslashQuoteType;
+
+/* GUC variables in scan.l (every one of these is a bad idea :-() */
+extern BackslashQuoteType backslash_quote;
+
+
/* from parser.c */
extern void parser_param_set(Oid *typev, int nargs);
extern Oid param_type(int t);