Browse files

ensure _private is NULL for merged text nodes

this normally isn't an issue, but if libxml-ruby is loaded, then the
global deregister handler will see merged text nodes with non-null
_private and start mucking around in our heap.

closes #1426
  • Loading branch information...
flavorjones committed Feb 17, 2016
1 parent 33b7427 commit af2cfc2e280c0bf8ce039c13b0831ebe8d5309ca
Showing with 28 additions and 0 deletions.
  1. +17 −0 ext/nokogiri/xml_node.c
  2. +11 −0 test/xml/test_node.rb
@@ -233,6 +233,23 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep
* uninteresting libxml2 implementation detail). as a result, we cannot
* reparent the actual reparentee, so we reparent a duplicate.
if (reparentee->type == XML_TEXT_NODE && reparentee->_private) {
* additionally, since we know this C struct isn't going to be related to
* a Ruby object anymore, let's break the relationship on this end as
* well.
* this is not absolutely necessary unless libxml-ruby is also in effect,
* in which case its global callback `rxml_node_deregisterNode` will try
* to do things to our data.
* for more details on this particular (and particularly nasty) edge
* case, see:
reparentee->_private = NULL ;
if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) {
rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
@@ -1228,6 +1228,17 @@ def test_set_node_lang
subject.lang = "fr"
assert_equal "fr", subject.lang
def test_text_node_robustness_gh1426
# notably, the original bug report was about libxml-ruby interactions
# this test should blow up under valgrind if we regress on libxml-ruby workarounds
message = "<h2>BOOM!</h2>"
10_000.times do
node = Nokogiri::HTML::DocumentFragment.parse(message)
node.add_previous_sibling('before', node.document))
node.add_next_sibling('after', node.document))

0 comments on commit af2cfc2

Please sign in to comment.