Skip to content

Commit c77a129

Browse files
authored
Don't use recursion when transferring a DOM internal document pointer (#16180)
Recursion is typically slower than iteration, and furthermore, this can cause problems in theory with deep trees.
1 parent 8b8a673 commit c77a129

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

ext/dom/document.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ PHP_METHOD(DOMDocument, getElementById)
10741074
}
10751075
/* }}} end dom_document_get_element_by_id */
10761076

1077-
static zend_always_inline void php_dom_transfer_document_ref_single_node(xmlNodePtr node, php_libxml_ref_obj *new_document)
1077+
static void php_dom_transfer_document_ref_single_node(xmlNodePtr node, php_libxml_ref_obj *new_document)
10781078
{
10791079
php_libxml_node_ptr *iteration_object_ptr = node->_private;
10801080
if (iteration_object_ptr) {
@@ -1087,21 +1087,25 @@ static zend_always_inline void php_dom_transfer_document_ref_single_node(xmlNode
10871087
}
10881088
}
10891089

1090-
static void php_dom_transfer_document_ref(xmlNodePtr node, php_libxml_ref_obj *new_document)
1090+
static void php_dom_transfer_document_ref_single_aux(xmlNodePtr node, php_libxml_ref_obj *new_document)
10911091
{
1092-
if (node->children) {
1093-
php_dom_transfer_document_ref(node->children, new_document);
1092+
php_dom_transfer_document_ref_single_node(node, new_document);
1093+
if (node->type == XML_ELEMENT_NODE) {
1094+
for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
1095+
php_dom_transfer_document_ref_single_node((xmlNodePtr) attr, new_document);
1096+
}
10941097
}
1098+
}
10951099

1096-
while (node) {
1097-
if (node->type == XML_ELEMENT_NODE) {
1098-
for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
1099-
php_dom_transfer_document_ref_single_node((xmlNodePtr) attr, new_document);
1100-
}
1101-
}
1100+
static void php_dom_transfer_document_ref(xmlNodePtr node, php_libxml_ref_obj *new_document)
1101+
{
1102+
xmlNodePtr base = node;
1103+
php_dom_transfer_document_ref_single_aux(base, new_document);
11021104

1103-
php_dom_transfer_document_ref_single_node(node, new_document);
1104-
node = node->next;
1105+
node = node->children;
1106+
while (node != NULL) {
1107+
php_dom_transfer_document_ref_single_aux(node, new_document);
1108+
node = php_dom_next_in_tree_order(node, base);
11051109
}
11061110
}
11071111

0 commit comments

Comments
 (0)