xml-more-robust-handling-2.patch
text/x-patch
Filename: xml-more-robust-handling-2.patch
Type: text/x-patch
Part: 0
Message:
Re: PostgreSQL vs SQL/XML Standards
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/xml.c | 41 | 18 |
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 28b3eaaa20..41145e697a 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -3720,35 +3720,58 @@ xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt)
if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE)
{
- xmlBufferPtr buf;
- xmlNodePtr cur_copy;
+ volatile xmlBufferPtr buf = NULL;
+ volatile xmlNodePtr cur_copy = NULL;
- buf = xmlBufferCreate();
+ PG_TRY();
+ {
+ int bytes;
- /*
- * 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);
+ buf = xmlBufferCreate();
- if (cur_copy == NULL)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
- "could not copy node");
+ if (buf == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xmlBuffer");
+
+ /*
+ * The result of xmlNodeDump() won't contain namespace definitions
+ * from parent nodes, but xmlCopyNode() duplicates a node along with
+ * its required namespace definitions.
+ *
+ * Some older libxml2 like 2.7.6 produces partialy broken
+ * XML_DOCUMENT_NODE nodes (unset content field). The copy of this node
+ * is ok, but xmlFreeNode fails. Fortunately, XML_DOCUMENT_NODE should
+ * not to have parent nodes, and we don't need to use xmlCopyNode.
+ */
+ if (cur->type != XML_DOCUMENT_NODE)
+ {
+ cur_copy = xmlCopyNode(cur, 1);
+ if (cur == NULL || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not copy node");
+ }
+ else
+ cur_copy = cur;
+
+ bytes = xmlNodeDump(buf, NULL, cur_copy, 0, 1);
+ if (bytes == -1 || xmlerrcxt->err_occurred)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not dump node");
- PG_TRY();
- {
- xmlNodeDump(buf, NULL, cur_copy, 0, 1);
result = xmlBuffer_to_xmltype(buf);
}
PG_CATCH();
{
- xmlFreeNode(cur_copy);
- xmlBufferFree(buf);
+ if (cur_copy && cur_copy != cur)
+ xmlFreeNode(cur_copy);
+ if (buf)
+ xmlBufferFree(buf);
PG_RE_THROW();
}
PG_END_TRY();
- xmlFreeNode(cur_copy);
+
+ if (cur_copy != cur)
+ xmlFreeNode(cur_copy);
xmlBufferFree(buf);
}
else