]> git.sesse.net Git - xml-template/commitdiff
Fix a possible use-after-free in the C++11 version; substitution could remove an...
authorsgunderson@bigfoot.com <>
Thu, 22 Sep 2011 21:50:48 +0000 (23:50 +0200)
committersgunderson@bigfoot.com <>
Thu, 22 Sep 2011 21:50:48 +0000 (23:50 +0200)
c++11/xml-template.cpp

index 317a561779fab53a7177d8376e1bbd37de585909..2e8fb9429fa3ab4508f33dcd4cd106ac75c39f52 100644 (file)
@@ -168,8 +168,8 @@ void Substitute::process(xmlNode *node, bool clean)
 {
        xmlNode *next_child;
        for (xmlNode *child = node->children; child != NULL; child = next_child) {
-               next_child = child->next;       
-               bool processed = false;
+               next_child = child->next;
+               Directive *next_processor = this;
 
                if (child->type == XML_ELEMENT_NODE) {
                        // Find the ID, if any.
@@ -208,22 +208,16 @@ void Substitute::process(xmlNode *node, bool clean)
                                        xmlSetProp(child, attr_key, attr_value);
                                }
 
-                               if (processed) {
-                                       continue;
-                               }
-
-                               // Regular substitution.
+                               // Regular substitution. (Don't call process() immediately, because
+                               // that might delete the element, which would cause problems.)
                                if (it.first == tag ||
                                    (!id.empty() && it.first == ("#" + id))) {
-                                       it.second->process(child, clean);
-                                       processed = true;
+                                       next_processor = it.second;
                                }
                        }
                }
 
-               if (!processed) {
-                       process(child, clean);
-               }
+               next_processor->process(child, clean);
        }
        if (clean) {
                clean_node(node);