Skip to content

Commit

Permalink
Fix attribute nodes namespace when using XML::Reader
Browse files Browse the repository at this point in the history
Fixes assertion failure. xml reader is choking while trying to access
namespace information tied to the attribute nodes. The assertion was:

Assertion failed: (doc->_private), function Nokogiri_wrap_xml_namespace,
file xml_namespace.c, line 41
  • Loading branch information
2potatocakes authored and jvshahid committed Dec 9, 2015
1 parent 7b32758 commit 24fc533
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
16 changes: 10 additions & 6 deletions ext/nokogiri/xml_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,24 @@ static VALUE href(VALUE self)
VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
{
VALUE ns, document, node_cache;
nokogiriTuplePtr node_has_a_document;

assert(doc->_private);
if (doc->type == XML_DOCUMENT_FRAG_NODE) doc = doc->doc;
node_has_a_document = DOC_RUBY_OBJECT_TEST(doc);

if(node->_private)
if(node->_private && node_has_a_document)
return (VALUE)node->_private;

ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);

document = DOC_RUBY_OBJECT(doc);
if (doc->_private) {
document = DOC_RUBY_OBJECT(doc);

node_cache = rb_iv_get(document, "@node_cache");
rb_ary_push(node_cache, ns);
node_cache = rb_iv_get(document, "@node_cache");
rb_ary_push(node_cache, ns);

rb_iv_set(ns, "@document", DOC_RUBY_OBJECT(doc));
rb_iv_set(ns, "@document", DOC_RUBY_OBJECT(doc));
}

node->_private = (void *)ns;

Expand Down
19 changes: 19 additions & 0 deletions test/test_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,25 @@ def test_ns_uri
reader.map { |n| n.namespace_uri })
end

def test_namespaced_attributes
reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
<x xmlns:edi='http://ecommerce.example.org/schema' xmlns:commons="http://rets.org/xsd/RETSCommons">
<edi:foo commons:street-number="43">hello</edi:foo>
<y edi:name="francis" bacon="87"/>
</x>
eoxml
attr_ns = []
while reader.read
if reader.node_type == Nokogiri::XML::Node::ELEMENT_NODE
reader.attribute_nodes.each {|attr| attr_ns << (attr.namespace.nil? ? nil : attr.namespace.prefix) }
end
end
assert_equal(['commons',
'edi',
nil],
attr_ns)
end

def test_local_name
reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
<x xmlns:edi='http://ecommerce.example.org/schema'>
Expand Down

0 comments on commit 24fc533

Please sign in to comment.