Skip to content

Commit

Permalink
fix(jruby): Node#attribute correctly matches against localName
Browse files Browse the repository at this point in the history
Previously, it was matching against the full name.

Also, make sure that we create new attributes with
setAttributeNS (even if the URI is null) so that we can retrieve with
`localName`. Note that we need additional logic to handle unknown
namespaces.
  • Loading branch information
flavorjones committed Jun 24, 2024
1 parent d20cd17 commit c142785
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA
* [CRuby] libgumbo (the HTML5 parser) treats reaching max-depth as EOF. This addresses a class of issues when the parser is interrupted in this way. [#3121] @stevecheckoway
* [CRuby] Update node GC lifecycle to avoid a potential memory leak with fragments in libxml 2.13.0 caused by changes in `xmlAddChild`. [#3156] @flavorjones
* [CRuby] libgumbo correctly prints nonstandard element names in error messages. [#3219] @stevecheckoway
* [JRuby] Fixed some bugs in how `Node#attributes` handles attributes with namespaces. [#2677, #2679] @flavorjones


### Changed
Expand Down
27 changes: 19 additions & 8 deletions ext/java/nokogiri/XmlNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -643,12 +643,22 @@ public class XmlNode extends RubyObject

@JRubyMethod(name = {"attribute", "attr"})
public IRubyObject
attribute(ThreadContext context, IRubyObject name)
attribute(ThreadContext context, IRubyObject rbName)
{
NamedNodeMap attrs = this.node.getAttributes();
Node attr = attrs.getNamedItem(rubyStringToString(name));
if (attr == null) { return context.nil; }
return getCachedNodeOrCreate(context.runtime, attr);
NamedNodeMap attributes = this.node.getAttributes();
String name = rubyStringToString(rbName);

for (int j = 0 ; j < attributes.getLength() ; j++) {
Node attribute = attributes.item(j);
String localName = attribute.getLocalName();
if (localName == null) {
continue;
}
if (localName.equals(name)) {
return getCachedNodeOrCreate(context.runtime, attribute);
}
}
return context.nil;
}

@JRubyMethod
Expand Down Expand Up @@ -1415,11 +1425,12 @@ public class XmlNode extends RubyObject
}
}

if (uri != null) {
element.setAttributeNS(uri, key, val);
} else {
if (colonIndex > 0 && uri == null) {
element.setAttribute(key, val);
} else {
element.setAttributeNS(uri, key, val);
}

clearXpathContext(node);
}

Expand Down

0 comments on commit c142785

Please sign in to comment.