-
-
Notifications
You must be signed in to change notification settings - Fork 896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removing internal_subset
leaks memory
#1784
Comments
Thanks for reporting, will take a look. |
I believe the underlying issue is that |
I'm just back from vacation and it will take a few days to catch up on everything. Thanks for your patience. |
I believe I figured out the issue but I just realized I don't have time to write and test a fix right this moment but I want to write down what I think is going on so I don't have to redo this investigation later. Short version: static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
{
switch(node->type) {
case XML_ATTRIBUTE_NODE:
xmlFreePropList((xmlAttrPtr)node);
break;
case XML_NAMESPACE_DECL:
xmlFree(node);
break;
default:
if(node->parent == NULL) {
xmlAddChild((xmlNodePtr)doc, node);
}
}
return ST_CONTINUE;
} to something like static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
{
switch(node->type) {
case XML_ATTRIBUTE_NODE:
xmlFreePropList((xmlAttrPtr)node);
break;
case XML_NAMESPACE_DECL:
xmlFree(node);
break;
case XML_DTD_NODE:
xmlFreeDtd(node);
break;
default:
if(node->parent == NULL) {
xmlAddChild((xmlNodePtr)doc, node);
}
}
return ST_CONTINUE;
} That is, the DTD nodes need to be explicitly freed. (Honestly, I'm not sure I understand why Long version: Once all of the unlinked nodes are added back to the document, the document is freed with extSubset = cur->extSubset;
intSubset = cur->intSubset;
if (intSubset == extSubset)
extSubset = NULL;
if (extSubset != NULL) {
xmlUnlinkNode((xmlNodePtr) cur->extSubset);
cur->extSubset = NULL;
xmlFreeDtd(extSubset);
}
if (intSubset != NULL) {
xmlUnlinkNode((xmlNodePtr) cur->intSubset);
cur->intSubset = NULL;
xmlFreeDtd(intSubset);
}
if (cur->children != NULL) xmlFreeNodeList(cur->children); Note that the internal and external subsets are explicitly freed, if they exist. By adding the DTD node to the document, it has merely placed it in the children list which should be freed by One final point, I'm not sure why |
DTD nodes added to a document are not freed when the document is freed. Fixes #1784
@stevecheckoway You're probably right that we could just call |
Removing an HTML document's
internal_subset
leaks memory.What's the output from
nokogiri -v
?Can you provide a self-contained script that reproduces what you're seeing?
Here're the two leaks.
This is causing problems for users of Nokogumbo (see rubys/nokogumbo#20).
The text was updated successfully, but these errors were encountered: