Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f2743a7

Browse files
committed
Revert "Add support for parsing of large XML data (>= 10MB)"
This reverts commit 2197d06, following a discussion over a Coverity report where issues like the "Billion laugh attack" could cause the backend to waste CPU and memory even if a client applied checks on the size of the data given in input, and libxml2 does not offer guarantees that input limits are respected under XML_PARSE_HUGE. Discussion: https://postgr.es/m/ZbHlgrPLtBZyr_QW@paquier.xyz
1 parent 376c216 commit f2743a7

File tree

3 files changed

+13
-33
lines changed

3 files changed

+13
-33
lines changed

contrib/xml2/xpath.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
381381
{
382382
workspace->doctree = xmlReadMemory((char *) VARDATA_ANY(document),
383383
docsize, NULL, NULL,
384-
XML_PARSE_HUGE | XML_PARSE_NOENT);
384+
XML_PARSE_NOENT);
385385
if (workspace->doctree != NULL)
386386
{
387387
workspace->ctxt = xmlXPathNewContext(workspace->doctree);
@@ -626,7 +626,7 @@ xpath_table(PG_FUNCTION_ARGS)
626626
if (xmldoc)
627627
doctree = xmlReadMemory(xmldoc, strlen(xmldoc),
628628
NULL, NULL,
629-
XML_PARSE_HUGE | XML_PARSE_NOENT);
629+
XML_PARSE_NOENT);
630630
else /* treat NULL as not well-formed */
631631
doctree = NULL;
632632

contrib/xml2/xslt_proc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ xslt_process(PG_FUNCTION_ARGS)
8787
/* Parse document */
8888
doctree = xmlReadMemory((char *) VARDATA_ANY(doct),
8989
VARSIZE_ANY_EXHDR(doct), NULL, NULL,
90-
XML_PARSE_HUGE | XML_PARSE_NOENT);
90+
XML_PARSE_NOENT);
9191

9292
if (doctree == NULL)
9393
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
@@ -96,7 +96,7 @@ xslt_process(PG_FUNCTION_ARGS)
9696
/* Same for stylesheet */
9797
ssdoc = xmlReadMemory((char *) VARDATA_ANY(ssheet),
9898
VARSIZE_ANY_EXHDR(ssheet), NULL, NULL,
99-
XML_PARSE_HUGE | XML_PARSE_NOENT);
99+
XML_PARSE_NOENT);
100100

101101
if (ssdoc == NULL)
102102
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,

src/backend/utils/adt/xml.c

+9-29
Original file line numberDiff line numberDiff line change
@@ -1688,8 +1688,8 @@ xml_doctype_in_content(const xmlChar *str)
16881688
* xmloption_arg, but a DOCTYPE node in the input can force DOCUMENT mode).
16891689
*
16901690
* If parsed_nodes isn't NULL and the input is not an XML document, the list
1691-
* of parsed nodes from the xmlParseInNodeContext call will be returned to
1692-
* *parsed_nodes.
1691+
* of parsed nodes from the xmlParseBalancedChunkMemory call will be returned
1692+
* to *parsed_nodes.
16931693
*
16941694
* Errors normally result in ereport(ERROR), but if escontext is an
16951695
* ErrorSaveContext, then "safe" errors are reported there instead, and the
@@ -1795,7 +1795,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
17951795
doc = xmlCtxtReadDoc(ctxt, utf8string,
17961796
NULL,
17971797
"UTF-8",
1798-
XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_HUGE
1798+
XML_PARSE_NOENT | XML_PARSE_DTDATTR
17991799
| (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS));
18001800
if (doc == NULL || xmlerrcxt->err_occurred)
18011801
{
@@ -1828,30 +1828,10 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18281828
/* allow empty content */
18291829
if (*(utf8string + count))
18301830
{
1831-
const char *data;
1832-
xmlNodePtr root;
1833-
xmlNodePtr lst;
1834-
xmlParserErrors xml_error;
1835-
1836-
data = (const char *) (utf8string + count);
1837-
1838-
/*
1839-
* Create a fake root node. The xmlNewDoc() function creates
1840-
* an XML document without any nodes, and this is required for
1841-
* xmlParseInNodeContext() that is able to handle
1842-
* XML_PARSE_HUGE.
1843-
*/
1844-
root = xmlNewNode(NULL, (const xmlChar *) "content-root");
1845-
if (root == NULL || xmlerrcxt->err_occurred)
1846-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
1847-
"could not allocate xml node");
1848-
xmlDocSetRootElement(doc, root);
1849-
1850-
/* Try to parse string with using root node context. */
1851-
xml_error = xmlParseInNodeContext(root, data, strlen(data),
1852-
XML_PARSE_HUGE,
1853-
parsed_nodes ? parsed_nodes : &lst);
1854-
if (xml_error != XML_ERR_OK || xmlerrcxt->err_occurred)
1831+
res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0,
1832+
utf8string + count,
1833+
parsed_nodes);
1834+
if (res_code != 0 || xmlerrcxt->err_occurred)
18551835
{
18561836
xml_errsave(escontext, xmlerrcxt,
18571837
ERRCODE_INVALID_XML_CONTENT,
@@ -4364,7 +4344,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
43644344
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
43654345
"could not allocate parser context");
43664346
doc = xmlCtxtReadMemory(ctxt, (char *) string + xmldecl_len,
4367-
len - xmldecl_len, NULL, NULL, XML_PARSE_HUGE);
4347+
len - xmldecl_len, NULL, NULL, 0);
43684348
if (doc == NULL || xmlerrcxt->err_occurred)
43694349
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
43704350
"could not parse XML document");
@@ -4695,7 +4675,7 @@ XmlTableSetDocument(TableFuncScanState *state, Datum value)
46954675

46964676
PG_TRY();
46974677
{
4698-
doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, XML_PARSE_HUGE);
4678+
doc = xmlCtxtReadMemory(xtCxt->ctxt, (char *) xstr, length, NULL, NULL, 0);
46994679
if (doc == NULL || xtCxt->xmlerrcxt->err_occurred)
47004680
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
47014681
"could not parse XML document");

0 commit comments

Comments
 (0)