Commit 9b7304bc authored by Peter Eisentraut's avatar Peter Eisentraut

Fix xmlattribute escaping XML special characters twice (bug #4822).

Author: Itagaki Takahiro <itagaki.takahiro@oss.ntt.co.jp>
parent e343eaaf
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.247 2009/06/04 18:33:07 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.248 2009/06/09 22:00:57 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3243,7 +3243,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext, ...@@ -3243,7 +3243,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
{ {
appendStringInfo(&buf, "<%s>%s</%s>", appendStringInfo(&buf, "<%s>%s</%s>",
argname, argname,
map_sql_value_to_xml_value(value, exprType((Node *) e->expr)), map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true),
argname); argname);
*isNull = false; *isNull = false;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.89 2009/06/08 21:32:33 petere Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.90 2009/06/09 22:00:57 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -569,7 +569,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext) ...@@ -569,7 +569,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
if (isnull) if (isnull)
str = NULL; str = NULL;
else else
str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr)); str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr), false);
named_arg_strings = lappend(named_arg_strings, str); named_arg_strings = lappend(named_arg_strings, str);
i++; i++;
} }
...@@ -587,7 +587,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext) ...@@ -587,7 +587,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
if (!isnull) if (!isnull)
{ {
str = map_sql_value_to_xml_value(value, str = map_sql_value_to_xml_value(value,
exprType((Node *) e->expr)); exprType((Node *) e->expr), true);
arg_strings = lappend(arg_strings, str); arg_strings = lappend(arg_strings, str);
} }
} }
...@@ -1580,9 +1580,18 @@ map_xml_name_to_sql_identifier(char *name) ...@@ -1580,9 +1580,18 @@ map_xml_name_to_sql_identifier(char *name)
/* /*
* Map SQL value to XML value; see SQL/XML:2003 section 9.16. * Map SQL value to XML value; see SQL/XML:2003 section 9.16.
*
* When xml_escape_strings is true, then certain characters in string
* values are replaced by entity references (&lt; etc.), as specified
* in SQL/XML:2003 section 9.16 GR 8) ii). This is normally what is
* wanted. The false case is mainly useful when the resulting value
* is used with xmlTextWriterWriteAttribute() to write out an
* attribute, because that function does the escaping itself. The SQL
* standard of 2003 is somewhat buggy in this regard, so we do our
* best to make sense.
*/ */
char * char *
map_sql_value_to_xml_value(Datum value, Oid type) map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
{ {
StringInfoData buf; StringInfoData buf;
...@@ -1616,7 +1625,7 @@ map_sql_value_to_xml_value(Datum value, Oid type) ...@@ -1616,7 +1625,7 @@ map_sql_value_to_xml_value(Datum value, Oid type)
appendStringInfoString(&buf, "<element>"); appendStringInfoString(&buf, "<element>");
appendStringInfoString(&buf, appendStringInfoString(&buf,
map_sql_value_to_xml_value(elem_values[i], map_sql_value_to_xml_value(elem_values[i],
elmtype)); elmtype, true));
appendStringInfoString(&buf, "</element>"); appendStringInfoString(&buf, "</element>");
} }
...@@ -1774,8 +1783,8 @@ map_sql_value_to_xml_value(Datum value, Oid type) ...@@ -1774,8 +1783,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
getTypeOutputInfo(type, &typeOut, &isvarlena); getTypeOutputInfo(type, &typeOut, &isvarlena);
str = OidOutputFunctionCall(typeOut, value); str = OidOutputFunctionCall(typeOut, value);
/* ... exactly as-is for XML */ /* ... exactly as-is for XML, and when escaping is not wanted */
if (type == XMLOID) if (type == XMLOID || !xml_escape_strings)
return str; return str;
/* otherwise, translate special characters as needed */ /* otherwise, translate special characters as needed */
...@@ -3183,7 +3192,7 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename, ...@@ -3183,7 +3192,7 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename,
appendStringInfo(result, " <%s>%s</%s>\n", appendStringInfo(result, " <%s>%s</%s>\n",
colname, colname,
map_sql_value_to_xml_value(colval, map_sql_value_to_xml_value(colval,
SPI_gettypeid(SPI_tuptable->tupdesc, i)), SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
colname); colname);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.26 2009/05/13 20:27:17 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.27 2009/06/09 22:00:57 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -73,7 +73,7 @@ extern text *xmltotext_with_xmloption(xmltype *data, XmlOptionType xmloption_arg ...@@ -73,7 +73,7 @@ extern text *xmltotext_with_xmloption(xmltype *data, XmlOptionType xmloption_arg
extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period); extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period);
extern char *map_xml_name_to_sql_identifier(char *name); extern char *map_xml_name_to_sql_identifier(char *name);
extern char *map_sql_value_to_xml_value(Datum value, Oid type); extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings);
typedef enum typedef enum
{ {
......
...@@ -188,6 +188,12 @@ SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as ba ...@@ -188,6 +188,12 @@ SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as ba
SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)); SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
ERROR: timestamp out of range ERROR: timestamp out of range
DETAIL: XML does not support infinite timestamp values. DETAIL: XML does not support infinite timestamp values.
SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
xmlelement
------------------------------------------------------------
<foo funny="&lt;&gt;&amp;&quot;'" funnier="b&lt;a/&gt;r"/>
(1 row)
SELECT xmlparse(content 'abc'); SELECT xmlparse(content 'abc');
xmlparse xmlparse
---------- ----------
......
...@@ -160,6 +160,10 @@ SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)); ...@@ -160,6 +160,10 @@ SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
ERROR: unsupported XML feature ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support. DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml. HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlparse(content 'abc'); SELECT xmlparse(content 'abc');
ERROR: unsupported XML feature ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support. DETAIL: This functionality requires the server to be built with libxml support.
......
...@@ -57,6 +57,7 @@ SELECT xmlelement(name foo, bytea 'bar'); ...@@ -57,6 +57,7 @@ SELECT xmlelement(name foo, bytea 'bar');
SELECT xmlelement(name foo, xmlattributes(true as bar)); SELECT xmlelement(name foo, xmlattributes(true as bar));
SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar)); SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar));
SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)); SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
SELECT xmlparse(content 'abc'); SELECT xmlparse(content 'abc');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment