From 9fe0761c47c0d4270d1a5220cfd25de080350d50 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 6 Dec 2022 01:51:37 -0500 Subject: [PATCH] fix(cruby): XML::Reader#attribute_hash returns nil on error Note that on JRuby, the namespaces are still returned because the parse error would raised on the subsequent node expansion. This restores the behavior from v1.13.7 --- CHANGELOG.md | 7 +++++++ ext/nokogiri/xml_reader.c | 4 ++++ test/xml/test_reader.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 481f837e64..ef5c718c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA --- +## next / unreleased + +### Improvements + +* [CRuby] `XML::Reader#attribute_hash` now returns `nil` on parse errors. This restores the behavior of `#attributes` from v1.13.7 and earlier. [[#2715](https://github.com/sparklemotion/nokogiri/issues/2715)] + + ## 1.13.9 / 2022-10-18 ### Security diff --git a/ext/nokogiri/xml_reader.c b/ext/nokogiri/xml_reader.c index 022f8ff531..0895ea6a72 100644 --- a/ext/nokogiri/xml_reader.c +++ b/ext/nokogiri/xml_reader.c @@ -212,6 +212,10 @@ rb_xml_reader_attribute_hash(VALUE rb_reader) } c_node = xmlTextReaderExpand(c_reader); + if (c_node == NULL) { + return Qnil; + } + c_property = c_node->properties; while (c_property != NULL) { VALUE rb_name = NOKOGIRI_STR_NEW2(c_property->name); diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb index ab119656c7..f77dbe148c 100644 --- a/test/xml/test_reader.rb +++ b/test/xml/test_reader.rb @@ -681,6 +681,38 @@ def test_nonexistent_attribute reader.read # el assert_nil(reader.attribute("other")) end + + def test_broken_markup_attribute_hash + xml = <<~XML + + XML + reader = Nokogiri::XML::Reader(xml) + reader.read # root + reader.read # foo + + assert_equal("foo", reader.name) + if Nokogiri.jruby? + assert_equal({ "bar" => "asdf" }, reader.attribute_hash) + else + assert_nil(reader.attribute_hash) + end + end + + def test_broken_markup_namespaces + xml = <<~XML + + XML + reader = Nokogiri::XML::Reader(xml) + reader.read # root + reader.read # foo + + assert_equal("foo", reader.name) + if Nokogiri.jruby? + assert_equal({ "xmlns:quux" => "qwer" }, reader.namespaces) + else + assert_nil(reader.namespaces) + end + end end end end