Class | Nokogiri::XML::NodeSet |
In: |
lib/nokogiri/xml/node_set.rb
ext/nokogiri/xml_document_fragment.c |
Parent: | Object |
xmlXPathFreeNodeSet() contains an implicit assumption that it is being called before any of its pointed-to nodes have been free()d. this assumption lies in the operation where it dereferences nodeTab pointers while searching for namespace nodes to free.
however, since Ruby‘s GC mechanism cannot guarantee the strict order in which ruby objects will be GC‘d, nodes may be garbage collected before a nodeset containing pointers to those nodes. (this is true regardless of how we declare dependencies between objects with rb_gc_mark().)
as a result, xmlXPathFreeNodeSet() will perform unsafe memory operations, and calling it would be evil.
on the bright side, though, Nokogiri‘s API currently does not cause namespace nodes to be included in node sets, ever.
armed with that fact, we examined xmlXPathFreeNodeSet() and related libxml code and determined that, within the Nokogiri abstraction, we will not leak memory if we simply free the node set‘s memory directly. that‘s only quasi-evil!
there‘s probably a lesson in here somewhere about intermingling, within a single array, structs with different memory-ownership semantics. or more generally, a lesson about building an API in C/C++ that does not contain assumptions about the strict order in which memory will be released. hey, that sounds like a great idea for a blog post! get to it!
"In Valgrind We Trust." seriously.