From 1abf2967f955858764a6de5d7b7fe247cb637853 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 6 Aug 2020 17:51:57 +0200 Subject: [PATCH 109/139] Fix exponential runtime and memory in xi:fallback processing When creating XML_XINCLUDE_START nodes, the children of the original xi:include node must be freed, otherwise fallback content is copied twice, doubling runtime and memory consumption for each nested xi:fallback/xi:include pair. Found with libFuzzer. --- result/XInclude/fallback5.xml | 51 +++++++++++++++++ result/XInclude/fallback5.xml.rdr | 116 ++++++++++++++++++++++++++++++++++++++ test/XInclude/docs/fallback5.xml | 83 +++++++++++++++++++++++++++ xinclude.c | 8 +++ 4 files changed, 258 insertions(+) create mode 100644 result/XInclude/fallback5.xml create mode 100644 result/XInclude/fallback5.xml.rdr create mode 100644 test/XInclude/docs/fallback5.xml diff --git a/result/XInclude/fallback5.xml b/result/XInclude/fallback5.xml new file mode 100644 index 0000000..0ba503d --- /dev/null +++ b/result/XInclude/fallback5.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/result/XInclude/fallback5.xml.rdr b/result/XInclude/fallback5.xml.rdr new file mode 100644 index 0000000..0e1dab7 --- /dev/null +++ b/result/XInclude/fallback5.xml.rdr @@ -0,0 +1,116 @@ +0 1 a 0 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 1 elem 1 0 +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +1 14 #text 0 1 + +0 15 a 0 0 diff --git a/test/XInclude/docs/fallback5.xml b/test/XInclude/docs/fallback5.xml new file mode 100644 index 0000000..d3ad424 --- /dev/null +++ b/test/XInclude/docs/fallback5.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xinclude.c b/xinclude.c index 2917d45..5ea87ad 100644 --- a/xinclude.c +++ b/xinclude.c @@ -2260,11 +2260,19 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { xmlUnlinkNode(cur); xmlFreeNode(cur); } else { + xmlNodePtr child, next; + /* * Change the current node as an XInclude start one, and add an * XInclude end one */ cur->type = XML_XINCLUDE_START; + /* Remove fallback children */ + for (child = cur->children; child != NULL; child = next) { + next = child->next; + xmlUnlinkNode(child); + xmlFreeNode(child); + } end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL); if (end == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, -- 1.8.3.1