Skip to content

Commit 682a293

Browse files
committed
fix: SAX::ParserContext keeps a reference to the input
to prevent it from being GCed before we parse it. (cherry picked from commit f2a9275)
1 parent fdfb6df commit 682a293

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

ext/nokogiri/xml_sax_parser_context.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ noko_xml_sax_parser_context_s_native_io(VALUE rb_class, VALUE rb_io, VALUE rb_en
102102
c_context->sax = NULL;
103103
}
104104

105-
return noko_xml_sax_parser_context_wrap(rb_class, c_context);
105+
VALUE rb_context = noko_xml_sax_parser_context_wrap(rb_class, c_context);
106+
rb_iv_set(rb_context, "@input", rb_io);
107+
108+
return rb_context;
106109
}
107110

108111
/* :nodoc: */
@@ -154,7 +157,10 @@ noko_xml_sax_parser_context_s_native_memory(VALUE rb_class, VALUE rb_input, VALU
154157
c_context->sax = NULL;
155158
}
156159

157-
return noko_xml_sax_parser_context_wrap(rb_class, c_context);
160+
VALUE rb_context = noko_xml_sax_parser_context_wrap(rb_class, c_context);
161+
rb_iv_set(rb_context, "@input", rb_input);
162+
163+
return rb_context;
158164
}
159165

160166
/*

test/test_memory_usage.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,29 @@ def start_element(name, attrs = [])
313313
# Expected error. This comment makes rubocop happy.
314314
end
315315
end
316+
317+
it "XML::SAX::ParserContext.io holds a reference to IO input" do
318+
content = File.read(XML_ATOM_FILE)
319+
320+
memwatch(__method__) do
321+
pc = Nokogiri::XML::SAX::ParserContext.io(StringIO.new(content), "ISO-8859-1")
322+
parser = Nokogiri::XML::SAX::Parser.new(Nokogiri::SAX::TestCase::Doc.new)
323+
GC.stress
324+
pc.parse_with(parser)
325+
326+
assert_equal(472, parser.document.data.length)
327+
end
328+
end
329+
330+
it "XML::SAX::ParserContext.memory holds a reference to string input" do
331+
memwatch(__method__) do
332+
pc = Nokogiri::XML::SAX::ParserContext.memory(File.read(XML_ATOM_FILE), "ISO-8859-1")
333+
parser = Nokogiri::XML::SAX::Parser.new(Nokogiri::SAX::TestCase::Doc.new)
334+
GC.stress
335+
pc.parse_with(parser)
336+
337+
assert_equal(472, parser.document.data.length)
338+
end
339+
end
316340
end if ENV["NOKOGIRI_MEMORY_SUITE"] && Nokogiri.uses_libxml?
317341
end

0 commit comments

Comments
 (0)