[libxml2] Make xmlFreeNodeList non-recursive
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml2] Make xmlFreeNodeList non-recursive
- Date: Wed, 25 Sep 2019 13:50:54 +0000 (UTC)
commit 0762c9b69ba01628f72eada1c64ff3d361fb5716
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Mon Sep 23 17:07:40 2019 +0200
Make xmlFreeNodeList non-recursive
Avoid call stack overflow when freeing deeply nested documents.
tree.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
---
diff --git a/tree.c b/tree.c
index bba06140..47813267 100644
--- a/tree.c
+++ b/tree.c
@@ -3664,7 +3664,9 @@ xmlNextElementSibling(xmlNodePtr node) {
void
xmlFreeNodeList(xmlNodePtr cur) {
xmlNodePtr next;
+ xmlNodePtr parent;
xmlDictPtr dict = NULL;
+ size_t depth = 0;
if (cur == NULL) return;
if (cur->type == XML_NAMESPACE_DECL) {
@@ -3680,16 +3682,21 @@ xmlFreeNodeList(xmlNodePtr cur) {
return;
}
if (cur->doc != NULL) dict = cur->doc->dict;
- while (cur != NULL) {
+ while (1) {
+ while ((cur->children != NULL) &&
+ (cur->type != XML_DTD_NODE) &&
+ (cur->type != XML_ENTITY_REF_NODE)) {
+ cur = cur->children;
+ depth += 1;
+ }
+
next = cur->next;
+ parent = cur->parent;
if (cur->type != XML_DTD_NODE) {
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
xmlDeregisterNodeDefaultValue(cur);
- if ((cur->children != NULL) &&
- (cur->type != XML_ENTITY_REF_NODE))
- xmlFreeNodeList(cur->children);
if (((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_XINCLUDE_START) ||
(cur->type == XML_XINCLUDE_END)) &&
@@ -3720,7 +3727,16 @@ xmlFreeNodeList(xmlNodePtr cur) {
DICT_FREE(cur->name)
xmlFree(cur);
}
- cur = next;
+
+ if (next != NULL) {
+ cur = next;
+ } else {
+ if ((depth == 0) || (parent == NULL))
+ break;
+ depth -= 1;
+ cur = parent;
+ cur->children = NULL;
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]