Skip to content

Removing nodes does not nullify _nodePtr of all freed nodes #137

@afn

Description

@afn

The (xmlFreeNode())[https://gnome.pages.gitlab.gnome.org/libxml2/html/tree_8h.html#ad330960328f909614fd956bd491d5d9c] function frees all children of the specified node, but the (remove() method of XmlNode)[https://github.com/jameslan/libxml2-wasm/blob/01fc960fa0af28dc8c6499f530ed37d71da23dc3/src/nodes.mts#L155-L162] only nullifies its own _nodePtr, not that of its descendants. This can cause issues when calling remove() on a node that has already been removed, e.g.:

let doc, xpath;

try {
  doc = XmlDocument.fromString('<root><a id="1"><a id="2"/></a></root>');
  xpath = XmlXPath.compile('//a');
  for(const node of doc.eval(xpath) as XmlNode[]) {
    node.remove(); // Throws an error when it tries to remove <a id="2">
  }
}
finally {
  xpath?.dispose();
  doc?.dispose();
}

One possible sketch of a solution:

  1. Track all XmlNode instances in a weak map (either using Disposable, or if there's a reason not to do this, then a similar implementation)
  2. In remove(), walk the subtree rooted at the current node, and for each instance of each descendant node, nullify its _nodePtr.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions