File tree Expand file tree Collapse file tree 3 files changed +68
-1
lines changed Expand file tree Collapse file tree 3 files changed +68
-1
lines changed Original file line number Diff line number Diff line change @@ -104,7 +104,11 @@ recursively_remove_namespaces_from_node(xmlNodePtr node)
104104 (node -> type == XML_XINCLUDE_START ) ||
105105 (node -> type == XML_XINCLUDE_END )) &&
106106 node -> nsDef ) {
107- xmlFreeNsList (node -> nsDef );
107+ xmlNsPtr curr = node -> nsDef ;
108+ while (curr ) {
109+ noko_xml_document_pin_namespace (curr , node -> doc );
110+ curr = curr -> next ;
111+ }
108112 node -> nsDef = NULL ;
109113 }
110114
Original file line number Diff line number Diff line change 3939
4040 doc . at_xpath ( "//root:first" , "root" => "http://example.com/root" ) . namespace_scopes . inspect
4141 end
42+
43+ it "remove_namespaces!" do
44+ skip unless GC . respond_to? ( :verify_compaction_references )
45+
46+ doc = Nokogiri ::XML ( <<~XML )
47+ <root xmlns:a="http://a.flavorjon.es/" xmlns:b="http://b.flavorjon.es/">
48+ <a:foo>hello from a</a:foo>
49+ <b:foo>hello from b</b:foo>
50+ <container xmlns:c="http://c.flavorjon.es/">
51+ <c:foo c:attr='attr-value'>hello from c</c:foo>
52+ </container>
53+ </root>
54+ XML
55+
56+ namespaces = doc . root . namespaces
57+ namespaces . each ( &:inspect )
58+ doc . remove_namespaces!
59+
60+ GC . verify_compaction_references ( double_heap : true , toward : :empty )
61+
62+ namespaces . each ( &:inspect )
63+ end
4264 end
4365end
Original file line number Diff line number Diff line change @@ -191,6 +191,47 @@ def test_leaking_namespace_node_strings_with_prefix
191191 end
192192 end
193193
194+ def test_document_remove_namespaces_with_ruby_objects
195+ xml = <<~XML
196+ <root xmlns:a="http://a.flavorjon.es/" xmlns:b="http://b.flavorjon.es/">
197+ <a:foo>hello from a</a:foo>
198+ <b:foo>hello from b</b:foo>
199+ <container xmlns:c="http://c.flavorjon.es/">
200+ <c:foo c:attr='attr-value'>hello from c</c:foo>
201+ </container>
202+ </root>
203+ XML
204+
205+ 20 . times do
206+ 10_000 . times do
207+ doc = Nokogiri ::XML ::Document . parse ( xml )
208+ doc . namespaces . each ( &:inspect )
209+ doc . remove_namespaces!
210+ end
211+ puts MemInfo . rss
212+ end
213+ end
214+
215+ def test_document_remove_namespaces_without_ruby_objects
216+ xml = <<~XML
217+ <root xmlns:a="http://a.flavorjon.es/" xmlns:b="http://b.flavorjon.es/">
218+ <a:foo>hello from a</a:foo>
219+ <b:foo>hello from b</b:foo>
220+ <container xmlns:c="http://c.flavorjon.es/">
221+ <c:foo c:attr='attr-value'>hello from c</c:foo>
222+ </container>
223+ </root>
224+ XML
225+
226+ 20 . times do
227+ 20_000 . times do
228+ doc = Nokogiri ::XML ::Document . parse ( xml )
229+ doc . remove_namespaces!
230+ end
231+ puts MemInfo . rss
232+ end
233+ end
234+
194235 def test_leaking_dtd_nodes_after_internal_subset_removal
195236 # see https://github.com/sparklemotion/nokogiri/issues/1784
196237 100_000 . times do |i |
You can’t perform that action at this time.
0 commit comments