summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/scan.l37
-rw-r--r--src/backend/utils/misc/guc.c40
-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
5 files changed, 87 insertions, 9 deletions
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 433e42bf6a0..f0a424a8d02 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.119.4.1 2005/08/16 00:48:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.119.4.2 2006/05/21 20:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,6 +36,15 @@ static int xcdepth = 0; /* depth of nesting in slash-star comments */
static char *dolqstart; /* current $foo$ quote start string */
/*
+ * 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
@@ -49,6 +58,7 @@ static int literalalloc; /* current allocated buffer size */
static void addlit(char *ytext, int yleng);
static void addlitchar(unsigned char ychar);
static char *litbufdup(void);
+static int pg_err_position(void);
/*
* When we parse a token that requires multiple lexer rules to process,
@@ -391,6 +401,17 @@ 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())))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
+ errmsg("unsafe use of \\' in a string literal"),
+ errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),
+ errposition(pg_err_position())));
+ }
addlitchar(unescape_single_char(yytext[1]));
}
<xq>{xqoctesc} {
@@ -613,14 +634,20 @@ other .
%%
-void
-yyerror(const char *message)
+static int
+pg_err_position(void)
{
const char *loc = token_start ? token_start : yytext;
- int cursorpos;
/* in multibyte encodings, return index in characters not bytes */
- cursorpos = pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;
+ return pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;
+}
+
+void
+yyerror(const char *message)
+{
+ const char *loc = token_start ? token_start : yytext;
+ int cursorpos = pg_err_position();
if (*loc == YY_END_OF_BUFFER_CHAR)
{
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index c1fa6fc5686..05b7b1a68df 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <[email protected]>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.252.4.3 2006/02/12 22:33:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.252.4.4 2006/05/21 20:11:25 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -42,6 +42,7 @@
#include "optimizer/geqo.h"
#include "optimizer/paths.h"
#include "optimizer/prep.h"
+#include "parser/gramparse.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "parser/scansup.h"
@@ -113,6 +114,7 @@ static bool assign_stage_log_stats(bool newval, bool doit, GucSource source);
static bool assign_log_stats(bool newval, bool doit, GucSource source);
static bool assign_transaction_read_only(bool newval, bool doit, GucSource source);
static const char *assign_canonical_path(const char *newval, bool doit, GucSource source);
+static const char *assign_backslash_quote(const char *newval, bool doit, GucSource source);
/*
@@ -169,6 +171,7 @@ static char *log_destination_string;
static bool phony_autocommit;
static bool session_auth_is_superuser;
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;
@@ -1424,6 +1427,15 @@ static struct config_string ConfigureNamesString[] =
},
{
+ {"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
+ gettext_noop("Sets whether \"\\'\" is allowed in string literals."),
+ gettext_noop("Valid values are ON, OFF, and SAFE_ENCODING.")
+ },
+ &backslash_quote_string,
+ "safe_encoding", assign_backslash_quote, NULL
+ },
+
+ {
{"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE,
gettext_noop("Sets the client's character set encoding."),
NULL,
@@ -5613,6 +5625,32 @@ assign_log_stats(bool newval, bool doit, GucSource source)
return true;
}
+static const char *
+assign_backslash_quote(const char *newval, bool doit, GucSource source)
+{
+ 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 (pg_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;
+}
+
static bool
assign_transaction_read_only(bool newval, bool doit, GucSource source)
{
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 021b732096d..61d0bfebf3f 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -311,9 +311,10 @@
# - Previous Postgres Versions -
#add_missing_from = true
+#backslash_quote = safe_encoding # on, off, or safe_encoding
+#default_with_oids = true
#regex_flavor = advanced # advanced, extended, or basic
#sql_inheritance = true
-#default_with_oids = true
# - Other Platforms & Clients -
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 0b9e369185d..5f40705d8a4 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.120.4.1 2005/05/04 14:25:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.120.4.2 2006/05/21 20:11:25 tgl Exp $
*/
/*----------------------------------------------------------------------
@@ -512,6 +512,7 @@ psql_completion(char *text, int start, int end)
*/
"add_missing_from",
"australian_timezones",
+ "backslash_quote",
"client_encoding",
"client_min_messages",
"commit_delay",
diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h
index 8095ef2300a..8e577980a2d 100644
--- a/src/include/parser/gramparse.h
+++ b/src/include/parser/gramparse.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.31 2004/12/31 22:03:38 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.31.4.1 2006/05/21 20:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,6 +18,17 @@
#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 int yylex(void);