Skip to content
Snippets Groups Projects
Commit 9f7a664f authored by Tom Lane's avatar Tom Lane
Browse files

Avoid failure when selecting a namespace node in XMLTABLE.

It appears that libxml2 doesn't bother to set the "children" field of
an XML_NAMESPACE_DECL node to null; that field just contains garbage.
In v10 and v11, this can result in a crash in XMLTABLE().  The rewrite
done in commit 251cf2e2 fixed this, somewhat accidentally, in v12.
We're not going to back-patch 251cf2e2, however.  The case apparently
doesn't have wide use, so rather than risk introducing other problems,
just add a safety check to throw an error.

Even though no bug manifests in v12/HEAD, add the relevant test case
there too, to prevent future regressions.

Chapman Flack (per private report)
parent 2930f163
No related branches found
No related tags found
No related merge requests found
......@@ -4612,6 +4612,12 @@ XmlTableGetValue(TableFuncScanState *state, int colnum,
xmlChar *str;
xmlNodePtr node;
node = xpathobj->nodesetval->nodeTab[0];
if (node->type == XML_NAMESPACE_DECL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("XMLTABLE cannot cast a namespace node to a non-XML result type")));
/*
* Most nodes (elements and even attributes) store their data
* in children nodes. If they don't have children nodes, it
......@@ -4619,7 +4625,6 @@ XmlTableGetValue(TableFuncScanState *state, int colnum,
* CDATA sections are an exception: they don't have children
* but have content in the Text/CDATA node itself.
*/
node = xpathobj->nodesetval->nodeTab[0];
if (node->type != XML_CDATA_SECTION_NODE &&
node->type != XML_TEXT_NODE)
node = node->xmlChildrenNode;
......
......@@ -1173,6 +1173,10 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'a');
ERROR: DEFAULT namespace is not supported
SELECT * FROM XMLTABLE('.'
PASSING '<foo/>'
COLUMNS a text PATH 'foo/namespace::node()');
ERROR: XMLTABLE cannot cast a namespace node to a non-XML result type
-- used in prepare statements
PREPARE pp AS
SELECT xmltable.*
......
......@@ -1048,6 +1048,14 @@ LINE 3: PASSING '<rows xmlns="http://x.y"><row...
^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT * FROM XMLTABLE('.'
PASSING '<foo/>'
COLUMNS a text PATH 'foo/namespace::node()');
ERROR: unsupported XML feature
LINE 2: PASSING '<foo/>'
^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
-- used in prepare statements
PREPARE pp AS
SELECT xmltable.*
......
......@@ -1153,6 +1153,10 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'a');
ERROR: DEFAULT namespace is not supported
SELECT * FROM XMLTABLE('.'
PASSING '<foo/>'
COLUMNS a text PATH 'foo/namespace::node()');
ERROR: XMLTABLE cannot cast a namespace node to a non-XML result type
-- used in prepare statements
PREPARE pp AS
SELECT xmltable.*
......
......@@ -402,6 +402,10 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'a');
SELECT * FROM XMLTABLE('.'
PASSING '<foo/>'
COLUMNS a text PATH 'foo/namespace::node()');
-- used in prepare statements
PREPARE pp AS
SELECT xmltable.*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment