tinyxml2 icon indicating copy to clipboard operation
tinyxml2 copied to clipboard

Unbounded recursion in XMLNode::DeepClone results in stack overflow

Open cleeus opened this issue 5 years ago • 3 comments
trafficstars

The XMLNode::DeepClone member function does an unbounded recursion.

Even though XMLNode::ParseDeep enforces a limit on the recursion using the XMLDocument::DepthTracker:

XMLDocument::DepthTracker tracker(_document);
if (_document->Error())
	return 0;

this limit can later be exceeded by manipulation of the XML tree (e.g. inserting subtrees). If a suitably deep XML tree is then ::DeepClone()-ed a stack overflow can happen.

cleeus avatar Oct 21 '20 08:10 cleeus

There also seem to be other recursive operations that will suffer from the same problem. I found:

  • XMLNode::~XMLNode->XMLNode::DeleteChildren->XMLNode::DeleteChild->XMLNode::DeleteNode->XMLNode::~XMLNode
  • XMLElement::Accept->XMLElement::Accept

I have seen this before in XML handling code. There basically are two remediations: a) limit recursion depth and gracefully fail with an error b) implement iterative depth-first graph traversal with state tracking on a heap-allocated data structure

From my experience b) is a little bit more complicated to implement but also provides a good performance improvement (function call overhead can be eliminated in iterative functions).

cleeus avatar Oct 22 '20 04:10 cleeus

I wrote a few simple repro test cases to illustrate the problem. These tests currently all crash with a stack overflow. Can I get a comment if this is considered a defect?

https://github.com/cleeus/tinyxml2/commit/82310de580d9dfe9d4030082ead07799765a53a2

cleeus avatar Oct 23 '20 09:10 cleeus

Definitely a bug - and a good find!

leethomason avatar Dec 30 '20 18:12 leethomason