diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 46f8987fd76..b2a9d50587a 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -3286,19 +3286,34 @@ xml_xmlnodetoxmltype(xmlNodePtr cur) if (cur->type == XML_ELEMENT_NODE) { xmlBufferPtr buf; + xmlNodePtr cur_copy; buf = xmlBufferCreate(); + + /* + * The result of xmlNodeDump() won't contain namespace definitions + * from parent nodes, but xmlCopyNode() duplicates a node along with + * its required namespace definitions. + */ + cur_copy = xmlCopyNode(cur, 1); + + if (cur_copy == NULL) + xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + PG_TRY(); { - xmlNodeDump(buf, NULL, cur, 0, 1); + xmlNodeDump(buf, NULL, cur_copy, 0, 1); result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { + xmlFreeNode(cur_copy); xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY(); + xmlFreeNode(cur_copy); xmlBufferFree(buf); } else diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 7db5f917bed..1f165a6cd8e 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -496,6 +496,21 @@ SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + xpath +------------------------------------------------------------------------------------------------------------------------------------------------ + {"number one",""} +(1 row) + +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + xpath +-------------------------------------------------------------------------------------- + {"+ + number one + + + + ",""} +(1 row) + SELECT xpath('//b', 'one two three etc'); xpath ------------------------- diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index d654056b08b..15f93e687d3 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -450,6 +450,18 @@ LINE 1: SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); +ERROR: unsupported XML feature +LINE 1: SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); +ERROR: unsupported XML feature +LINE 1: SELECT xpath('//loc:piece', 'number one'); SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); SELECT xpath('//b', 'one two three etc'); -- External entity references should not leak filesystem information.