diff --git a/CHANGELOG.md b/CHANGELOG.md index f013c98b02..2644710555 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.9.1 / 2018-12-17 + +## Bug fixes + +* Fix a bug introduced in v1.9.0 where `XML::DocumentFragment#dup` no longer returned an instance of the callee's class, instead always returning an `XML::DocumentFragment`. This notably broke any subclass of `XML::DocumentFragment` including `HTML::DocumentFragment` as well as the Loofah gem's `Loofah::HTML::DocumentFragment`. [#1846] + + # 1.9.0 / 2018-12-17 ## Security Notes diff --git a/lib/nokogiri/xml/document_fragment.rb b/lib/nokogiri/xml/document_fragment.rb index cfa826b421..e56886b0d6 100644 --- a/lib/nokogiri/xml/document_fragment.rb +++ b/lib/nokogiri/xml/document_fragment.rb @@ -28,7 +28,7 @@ def initialize document, tags = nil, ctx = nil if Nokogiri.uses_libxml? def dup new_document = document.dup - new_fragment = XML::DocumentFragment.new(new_document) + new_fragment = self.class.new(new_document) children.each do |child| child.dup(1, new_document).parent = new_fragment end diff --git a/test/html/test_document_fragment.rb b/test/html/test_document_fragment.rb index 3a85740b42..1b497b0c6d 100644 --- a/test/html/test_document_fragment.rb +++ b/test/html/test_document_fragment.rb @@ -305,6 +305,13 @@ def test_capturing_nonparse_errors_during_node_copy_between_fragments assert_equal original_errors1, frag1.errors assert_equal original_errors2, frag2.errors end + + def test_dup_should_create_an_html_document_fragment + # https://github.com/sparklemotion/nokogiri/issues/1846 + original = Nokogiri::HTML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_instance_of Nokogiri::HTML::DocumentFragment, duplicate + end end end end diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index 3ff801e847..242bd9e4f1 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -263,6 +263,20 @@ def test_issue_1077_parsing_of_frozen_strings Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised end + def test_dup_should_exist_in_a_new_document + # https://github.com/sparklemotion/nokogiri/issues/1063 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_not_equal original.document, duplicate.document + end + + def test_dup_should_create_an_xml_document_fragment + # https://github.com/sparklemotion/nokogiri/issues/1846 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_instance_of Nokogiri::XML::DocumentFragment, duplicate + end + def test_dup_creates_tree_with_identical_structure original = Nokogiri::XML::DocumentFragment.parse("

hello

") duplicate = original.dup