]> granicus.if.org Git - postgresql/commitdiff
Allow XML processing instructions starting with "xml" while prohibiting
authorPeter Eisentraut <peter_e@gmx.net>
Fri, 9 Nov 2007 15:52:51 +0000 (15:52 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Fri, 9 Nov 2007 15:52:51 +0000 (15:52 +0000)
those being exactly "xml".  Bug #3735 from Ben Leslie

src/backend/utils/adt/xml.c
src/test/regress/expected/xml.out
src/test/regress/expected/xml_1.out
src/test/regress/sql/xml.sql

index a1a619dd7a2912cf436aeba8bba78370045023db..1747d9e4bdefad298a051c91b98891b0ea20c426 100644 (file)
@@ -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 */
index 8ffde1dc6af7c9b912a659b1064b300f51551866..45d82c7dda8ae8c1e9e93051725c4fe3171dc983 100644 (file)
@@ -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    
 -------------
index ae85f71acc32fa92b636b999836f0c04fb0954fc..76455919fc0567a804914678e747b5179d1ba8c5 100644 (file)
@@ -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.
index 2c9db299fda33d1df0917e6b199f2fc008b13524..cae45dd28cb4dba8b7b6abde1a4cbb8bbcd9145e 100644 (file)
@@ -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');