diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 48bf5a4feb8e914bc7f331b8e09aab03d32178a9..cf929f0b72e86004c803ec9f9406c2466ae4be15 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.131 2009/04/27 16:27:36 momjian Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.132 2009/05/05 18:32:17 petere Exp $ --> <chapter id="sql-syntax"> <title>SQL Syntax</title> @@ -499,6 +499,17 @@ U&'d!0061t!+000061' UESCAPE '!' specified. </para> + <para> + Also, the Unicode escape syntax for string constants only works + when the configuration + parameter <xref linkend="guc-standard-conforming-strings"> is + turned on. This is because otherwise this syntax could confuse + clients that parse the SQL statements to the point that it could + lead to SQL injections and similar security issues. If the + parameter is set to off, this syntax will be rejected with an + error message. + </para> + <para> To include the escape character in the string literally, write it twice. diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 8551cd27538eed6a8b1b2fa75560ec251c104a14..eb0fc10c8f3df747ac2d955805304fda72836d8b 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -24,7 +24,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.151 2009/04/19 21:08:54 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.152 2009/05/05 18:32:17 petere Exp $ * *------------------------------------------------------------------------- */ @@ -469,6 +469,11 @@ other . startlit(); } {xusstart} { + if (!standard_conforming_strings) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("unsafe use of string constant with Unicode escapes"), + errdetail("String constants with Unicode escapes cannot be used when standard_conforming_strings is off."))); SET_YYLLOC(); BEGIN(xus); startlit(); diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index 6b9dc5df9f46983a2d2e07eecd087e5ab6cbe2c2..831fb9e2037cd82b95a5e1fb0582963344029671 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -22,6 +22,7 @@ ERROR: syntax error at or near "' - third line'" LINE 3: ' - third line' ^ -- Unicode escapes +SET standard_conforming_strings TO on; SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; data ------ @@ -34,6 +35,18 @@ SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; dat\+000061 (1 row) +SELECT U&' \' UESCAPE '!' AS "tricky"; + tricky +-------- + \ +(1 row) + +SELECT 'tricky' AS U&"\" UESCAPE '!'; + \ +-------- + tricky +(1 row) + SELECT U&'wrong: \061'; ERROR: invalid Unicode escape value at or near "\061'" LINE 1: SELECT U&'wrong: \061'; @@ -46,6 +59,32 @@ SELECT U&'wrong: +0061' UESCAPE '+'; ERROR: invalid Unicode escape character at or near "+'" LINE 1: SELECT U&'wrong: +0061' UESCAPE '+'; ^ +SET standard_conforming_strings TO off; +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +SELECT U&' \' UESCAPE '!' AS "tricky"; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +SELECT 'tricky' AS U&"\" UESCAPE '!'; + \ +-------- + tricky +(1 row) + +SELECT U&'wrong: \061'; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +SELECT U&'wrong: \+0061'; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +SELECT U&'wrong: +0061' UESCAPE '+'; +ERROR: unsafe use of string constant with Unicode escapes +DETAIL: String constants with Unicode escapes cannot be used when standard_conforming_strings is off. +RESET standard_conforming_strings; -- -- test conversions between various string types -- E021-10 implicit casting among the character data types diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 0da88c7b29e6f09effba211cb4f51903bd9156af..a28c75ac0449ec9c70738bea08c91790c4c5e610 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -17,13 +17,32 @@ SELECT 'first line' AS "Illegal comment within continuation"; -- Unicode escapes +SET standard_conforming_strings TO on; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; + +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT U&'wrong: \061'; +SELECT U&'wrong: \+0061'; +SELECT U&'wrong: +0061' UESCAPE '+'; + +SET standard_conforming_strings TO off; + SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; +SELECT U&' \' UESCAPE '!' AS "tricky"; +SELECT 'tricky' AS U&"\" UESCAPE '!'; + SELECT U&'wrong: \061'; SELECT U&'wrong: \+0061'; SELECT U&'wrong: +0061' UESCAPE '+'; +RESET standard_conforming_strings; + -- -- test conversions between various string types -- E021-10 implicit casting among the character data types