From 8db43db01efb6c6dd13c1e1101af269a2f3e32f5 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Fri, 9 Nov 2007 15:52:51 +0000 Subject: [PATCH] Allow XML processing instructions starting with "xml" while prohibiting those being exactly "xml". Bug #3735 from Ben Leslie --- src/backend/utils/adt/xml.c | 19 ++++++++++++++++--- src/test/regress/expected/xml.out | 26 ++++++++++++++++++++++---- src/test/regress/expected/xml_1.out | 12 ++++++++++++ src/test/regress/sql/xml.sql | 3 +++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index a1a619dd7a2..1747d9e4bde 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.53 2007/11/08 15:16:45 petere Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.54 2007/11/09 15:52:51 petere Exp $ * *------------------------------------------------------------------------- */ @@ -676,11 +676,11 @@ xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null) xmltype *result; StringInfoData buf; - if (pg_strncasecmp(target, "xml", 3) == 0) + if (pg_strcasecmp(target, "xml") == 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), /* really */ errmsg("invalid XML processing instruction"), - errdetail("XML processing instruction target name cannot start with \"xml\"."))); + errdetail("XML processing instruction target name cannot be \"%s\".", target))); /* * Following the SQL standard, the null check comes after the @@ -997,6 +997,14 @@ xml_init(void) #define SKIP_XML_SPACE(p) \ while (xmlIsBlank_ch(*(p))) (p)++ +/* Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender */ +#define pg_xmlIsNameChar(c) \ + (xmlIsBaseChar_ch(c) || xmlIsIdeographicQ(c) \ + || xmlIsDigit_ch(c) \ + || c == '.' || c == '-' || c == '_' || c == ':' \ + || xmlIsCombiningQ(c) \ + || xmlIsExtender_ch(c)) + static int parse_xml_decl(const xmlChar *str,size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone) @@ -1004,6 +1012,7 @@ parse_xml_decl(const xmlChar *str,size_t *lenp, const xmlChar *p; const xmlChar *save_p; size_t len; + int utf8len; xml_init(); @@ -1019,6 +1028,10 @@ parse_xml_decl(const xmlChar *str,size_t *lenp, if (xmlStrncmp(p, (xmlChar *)"<?xml", 5) != 0) goto finished; + /* This means it's a PI like <?xml-stylesheet ...?>. */ + if (pg_xmlIsNameChar(xmlGetUTF8Char(&p[5], &utf8len))) + goto finished; + p += 5; /* version */ diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 8ffde1dc6af..45d82c7dda8 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -180,9 +180,15 @@ SELECT xmlpi(name foo); <?foo?> (1 row) -SELECT xmlpi(name xmlstuff); +SELECT xmlpi(name xml); ERROR: invalid XML processing instruction -DETAIL: XML processing instruction target name cannot start with "xml". +DETAIL: XML processing instruction target name cannot be "xml". +SELECT xmlpi(name xmlstuff); + xmlpi +-------------- + <?xmlstuff?> +(1 row) + SELECT xmlpi(name foo, 'bar'); xmlpi ------------- @@ -198,9 +204,21 @@ SELECT xmlpi(name foo, null); (1 row) -SELECT xmlpi(name xmlstuff, null); +SELECT xmlpi(name xml, null); ERROR: invalid XML processing instruction -DETAIL: XML processing instruction target name cannot start with "xml". +DETAIL: XML processing instruction target name cannot be "xml". +SELECT xmlpi(name xmlstuff, null); + xmlpi +------- + +(1 row) + +SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"'); + xmlpi +------------------------------------------------------- + <?xml-stylesheet href="mystyle.css" type="text/css"?> +(1 row) + SELECT xmlpi(name foo, ' bar'); xmlpi ------------- diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index ae85f71acc3..76455919fc0 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -140,6 +140,10 @@ SELECT xmlpi(name foo); 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 xmlpi(name xml); +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 xmlpi(name xmlstuff); ERROR: unsupported XML feature DETAIL: This functionality requires the server to be built with libxml support. @@ -156,10 +160,18 @@ SELECT xmlpi(name foo, null); 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 xmlpi(name xml, null); +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 xmlpi(name xmlstuff, null); 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 xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"'); +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 xmlpi(name foo, ' bar'); ERROR: unsupported XML feature DETAIL: This functionality requires the server to be built with libxml support. diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index 2c9db299fda..cae45dd28cb 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -61,11 +61,14 @@ SELECT xmlparse(document '<abc>x</abc>'); SELECT xmlpi(name foo); +SELECT xmlpi(name xml); SELECT xmlpi(name xmlstuff); SELECT xmlpi(name foo, 'bar'); SELECT xmlpi(name foo, 'in?>valid'); SELECT xmlpi(name foo, null); +SELECT xmlpi(name xml, null); SELECT xmlpi(name xmlstuff, null); +SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"'); SELECT xmlpi(name foo, ' bar'); -- GitLab