Skip to content

Commit a53df25

Browse files
committed
change: CData.new no longer accepts nil as the content argument
An upcoming libxml2 change will force us to make a behavioral change of some kind, so I'm choosing to bring CData in line with the other character data classes (Comment and Text). The alternative would have been to continue accepting nil; but then the constructed node would contain a blank string (currently in this case Node#content returns nil). I think it's preferable to force callers to be explicit here. See upstream commit GNOME/libxml2@9991fae4
1 parent f5bf157 commit a53df25

File tree

6 files changed

+18
-25
lines changed

6 files changed

+18
-25
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA
1818
* `Node#clone`, `NodeSet#clone`, and `*::Document#clone` all properly copy the metaclass of the original as expected. Previously, `#clone` had been aliased to `#dup` for these classes (since v1.3.0 in 2009). [#316, #3117] @flavorjones
1919

2020

21+
### Changed
22+
23+
* [CRuby] `Nokogiri::XML::CData.new` no longer accepts `nil` as the content argument, making `CData` behave like other character data classes (like `Comment` and `Text`). This change was necessitated by behavioral changes in the upcoming libxml 2.13.0 release. If you wish to create an empty CDATA node, pass an empty string. [#3156] @flavorjones
24+
25+
2126
## v1.16.3 / 2024-03-15
2227

2328
### Dependencies

ext/java/nokogiri/XmlCdata.java

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public class XmlCdata extends XmlText
4646
IRubyObject rbDocument = args[0];
4747
content = args[1];
4848

49+
if (content.isNil()) {
50+
throw context.runtime.newTypeError("expected second parameter to be a String, received NilClass");
51+
}
4952
if (!(rbDocument instanceof XmlNode)) {
5053
String msg = "expected first parameter to be a Nokogiri::XML::Document, received " + rbDocument.getMetaClass();
5154
throw context.runtime.newTypeError(msg);

ext/nokogiri/xml_cdata.c

+2-10
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ rb_xml_cdata_s_new(int argc, VALUE *argv, VALUE klass)
2020
VALUE rb_content;
2121
VALUE rb_rest;
2222
VALUE rb_node;
23-
xmlChar *c_content = NULL;
24-
int c_content_len = 0;
2523

2624
rb_scan_args(argc, argv, "2*", &rb_document, &rb_content, &rb_rest);
2725

26+
Check_Type(rb_content, T_STRING);
2827
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
2928
rb_raise(rb_eTypeError,
3029
"expected first parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
@@ -40,15 +39,8 @@ rb_xml_cdata_s_new(int argc, VALUE *argv, VALUE klass)
4039
c_document = noko_xml_document_unwrap(rb_document);
4140
}
4241

43-
if (!NIL_P(rb_content)) {
44-
c_content = (xmlChar *)StringValuePtr(rb_content);
45-
c_content_len = RSTRING_LENINT(rb_content);
46-
}
47-
48-
c_node = xmlNewCDataBlock(c_document, c_content, c_content_len);
49-
42+
c_node = xmlNewCDataBlock(c_document, (xmlChar *)StringValueCStr(rb_content), RSTRING_LENINT(rb_content));
5043
noko_xml_document_pin_node(c_node);
51-
5244
rb_node = noko_xml_node_wrap(klass, c_node);
5345
rb_obj_call_init(rb_node, argc, argv);
5446

ext/nokogiri/xml_comment.c

+3-8
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,20 @@ new (int argc, VALUE *argv, VALUE klass)
2323

2424
rb_scan_args(argc, argv, "2*", &document, &content, &rest);
2525

26+
Check_Type(content, T_STRING);
2627
if (rb_obj_is_kind_of(document, cNokogiriXmlNode)) {
2728
document = rb_funcall(document, document_id, 0);
2829
} else if (!rb_obj_is_kind_of(document, cNokogiriXmlDocument)
2930
&& !rb_obj_is_kind_of(document, cNokogiriXmlDocumentFragment)) {
3031
rb_raise(rb_eArgError, "first argument must be a XML::Document or XML::Node");
3132
}
32-
3333
xml_doc = noko_xml_document_unwrap(document);
3434

35-
node = xmlNewDocComment(
36-
xml_doc,
37-
(const xmlChar *)StringValueCStr(content)
38-
);
39-
35+
node = xmlNewDocComment(xml_doc, (const xmlChar *)StringValueCStr(content));
36+
noko_xml_document_pin_node(node);
4037
rb_node = noko_xml_node_wrap(klass, node);
4138
rb_obj_call_init(rb_node, argc, argv);
4239

43-
noko_xml_document_pin_node(node);
44-
4540
if (rb_block_given_p()) { rb_yield(rb_node); }
4641

4742
return rb_node;

ext/nokogiri/xml_text.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass)
2020

2121
rb_scan_args(argc, argv, "2*", &rb_string, &rb_document, &rb_rest);
2222

23+
Check_Type(rb_string, T_STRING);
2324
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
2425
rb_raise(rb_eTypeError,
2526
"expected second parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
@@ -36,9 +37,7 @@ rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass)
3637
}
3738

3839
c_node = xmlNewDocText(c_document, (xmlChar *)StringValueCStr(rb_string));
39-
4040
noko_xml_document_pin_node(c_node);
41-
4241
rb_node = noko_xml_node_wrap(klass, c_node) ;
4342
rb_obj_call_init(rb_node, argc, argv);
4443

test/xml/test_cdata.rb

+4-5
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@
2828
assert_same(doc, node.document)
2929
end
3030

31-
it "has nil content when passed nil" do
32-
node = Nokogiri::XML::CDATA.new(Nokogiri::XML::Document.new, nil)
33-
34-
assert_instance_of(Nokogiri::XML::CDATA, node)
35-
assert_nil(node.content)
31+
it "when passed nil raises TypeError" do
32+
assert_raises(TypeError) do
33+
Nokogiri::XML::CDATA.new(Nokogiri::XML::Document.new, nil)
34+
end
3635
end
3736

3837
it "does not accept anything but a string" do

0 commit comments

Comments
 (0)