]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix handling of namespace nodes in xpath() (xml)
authorMichael Paquier <michael@paquier.xyz>
Fri, 12 Jun 2026 01:25:59 +0000 (10:25 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 12 Jun 2026 01:25:59 +0000 (10:25 +0900)
xpath() attempted to call xmlCopyNode() and xmlNodeDump() on a
XML_NAMESPACE_DECL, finishing with a confusing error:
=# SELECT xpath('//namespace::foo', '<root xmlns:foo="http://127.0.0.1"/>');
ERROR:  53200: could not copy node
CONTEXT:  SQL function "xpath" statement 1

xpath() is changed so as it goes through xmlXPathCastNodeToString()
instead, that is able to handle namespace nodes.  xml2 uses the same
solution.  This issue has been discovered while digging into
9d33a5a804db.

Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/aioT7ui_ZJ9RMlfM@paquier.xyz
Backpatch-through: 14

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 98dcc04122bd0864f5d3816537df0dd1b99f3d58..9b5e2e17b183869d17ec26ded841fbacb5a24ea1 100644 (file)
@@ -3855,7 +3855,9 @@ xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt)
 {
        xmltype    *result = NULL;
 
-       if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE)
+       if (cur->type != XML_ATTRIBUTE_NODE &&
+               cur->type != XML_TEXT_NODE &&
+               cur->type != XML_NAMESPACE_DECL)
        {
                void            (*volatile nodefree) (xmlNodePtr) = NULL;
                volatile xmlBufferPtr buf = NULL;
index f9b7ec0bab8d49cbb8c4ba6f1974c66628eb1526..5924deff665b4e1f578f4a6cf768b01dc2a2cbb4 100644 (file)
@@ -710,6 +710,12 @@ SELECT xpath('root', '<root/>');
  {<root/>}
 (1 row)
 
+SELECT xpath('//namespace::foo', '<root xmlns:foo="http://127.0.0.1"/>');
+       xpath        
+--------------------
+ {http://127.0.0.1}
+(1 row)
+
 -- Round-trip non-ASCII data through xpath().
 DO $$
 DECLARE
index fcf5d0f4aa24accaff004d447783bc2bd0b171d3..d22a6f82153b6f0f9b0b2a7d64139fe055b4e166 100644 (file)
@@ -624,6 +624,12 @@ LINE 1: SELECT xpath('root', '<root/>');
                              ^
 DETAIL:  This functionality requires the server to be built with libxml support.
 HINT:  You need to rebuild PostgreSQL using --with-libxml.
+SELECT xpath('//namespace::foo', '<root xmlns:foo="http://127.0.0.1"/>');
+ERROR:  unsupported XML feature
+LINE 1: SELECT xpath('//namespace::foo', '<root xmlns:foo="http://12...
+                                         ^
+DETAIL:  This functionality requires the server to be built with libxml support.
+HINT:  You need to rebuild PostgreSQL using --with-libxml.
 -- Round-trip non-ASCII data through xpath().
 DO $$
 DECLARE
index e908b6c39572d1fce7967fa42c0305a58c43d18d..ea2de44deb61b3cb25cbf82e57f98779abb6bf2b 100644 (file)
@@ -196,6 +196,7 @@ SELECT xpath('count(//*)=3', '<root><sub/><sub/></root>');
 SELECT xpath('name(/*)', '<root><sub/><sub/></root>');
 SELECT xpath('/nosuchtag', '<root/>');
 SELECT xpath('root', '<root/>');
+SELECT xpath('//namespace::foo', '<root xmlns:foo="http://127.0.0.1"/>');
 
 -- Round-trip non-ASCII data through xpath().
 DO $$