nokogiri 1.11.2 → 1.11.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +1 -1
  4. data/dependencies.yml +12 -12
  5. data/ext/nokogiri/nokogiri.c +19 -0
  6. data/ext/nokogiri/xml_document.c +36 -35
  7. data/ext/nokogiri/xml_node.c +53 -46
  8. data/lib/nokogiri/version/constant.rb +1 -1
  9. data/lib/nokogiri/version/info.rb +1 -0
  10. data/lib/nokogiri/xml/document.rb +43 -17
  11. data/lib/nokogiri/xml/node.rb +1 -0
  12. data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
  13. data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
  14. data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
  15. data/patches/libxml2/{0008-use-glibc-strlen.patch → 0004-use-glibc-strlen.patch} +0 -0
  16. data/patches/libxml2/{0009-avoid-isnan-isinf.patch → 0005-avoid-isnan-isinf.patch} +4 -4
  17. data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
  18. data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
  19. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
  20. data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
  21. data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
  22. metadata +13 -14
  23. data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
  24. data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
  25. data/patches/libxml2/0006-htmlParseComment-treat-as-if-it-closed-the-comment.patch +0 -73
  26. data/patches/libxml2/0007-use-new-htmlParseLookupCommentEnd-to-find-comment-en.patch +0 -103
  27. data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +0 -70
  28. data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 452bb1cd5efd099165d1c7e0e6239fdafc0b2e3620f715ceda57b23f620cc1d0
4
- data.tar.gz: 7776d8ab7ed9b0b528d48f0cd7882e5672cfab18671f146c5f67708ec9abf99c
3
+ metadata.gz: a73d0d0bba6227291bb1780b081dd2620881949ec0621e51d83457da13a98717
4
+ data.tar.gz: 2b6a3899b2368fa153d5de232e0dd7e04bd1a925ddebbfb0fb248956a9de8247
5
5
  SHA512:
6
- metadata.gz: ca1b3d69c4653d4b5cbf0f46d1241897981196f0515c11b871e6502562da7241856dc567de19fac0f1e71a854aefcc6ec9bd8beac5a764368c53fc636677c7f4
7
- data.tar.gz: b524df68b46b37ad5e5e09451ed808f6e0f68ca06e4a7e3e7b483c97d6e595cfe668de5a539c776e0ceb7c49eaa45d5cc6bcda9c835548c6e5633f0f410330fa
6
+ metadata.gz: f798c33192a0b25e1d57aa62b6eefbf3ccab6e0563f86357688e0cc75a7a714e83d48b0fc1cceb22f3c740005a61800c908e8e62cf6147663450950976941ca3
7
+ data.tar.gz: 0cbb1ab65d2299c10e39ff19b2df63fb7c50daf94ffc4062031239caa5455d1f81c6ac32ea4c3a5ca71a41e49184271fcccc28b8f8b226f64507de98775c71e0
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright 2008 -- 2020 by Mike Dalessio, Aaron Patterson, Yoko Harada, Akinori MUSHA, John Shahid, Karol Bucek, Lars Kanis, Sergio Arbeo, Timothy Elliott, Nobuyoshi Nakada, Charles Nutter, Patrick Mahoney.
3
+ Copyright 2008 -- 2021 by Mike Dalessio, Aaron Patterson, Yoko Harada, Akinori MUSHA, John Shahid, Karol Bucek, Lars Kanis, Sergio Arbeo, Timothy Elliott, Nobuyoshi Nakada, Charles Nutter, Patrick Mahoney.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
data/README.md CHANGED
@@ -57,7 +57,7 @@ Your first stops for learning more about Nokogiri should be:
57
57
 
58
58
  There are a few ways to ask exploratory questions:
59
59
 
60
- - The Discord chat channel is `#nokogiri-💎` at https://discord.gg/UyQnKrT
60
+ - The Ruby Discord chat server is active at https://discord.gg/UyQnKrT
61
61
  - The Nokogiri mailing list is active at https://groups.google.com/group/nokogiri-talk
62
62
  - Open an issue using the "Help Request" template at https://github.com/sparklemotion/nokogiri/issues
63
63
 
data/dependencies.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  libxml2:
2
- version: "2.9.10"
3
- sha256: "aafee193ffb8fe0c82d4afef6ef91972cbaf5feea100edc2f262750611b4be1f"
2
+ version: "2.9.12"
3
+ sha256: "c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92"
4
4
  # manually verified checksum:
5
5
  #
6
- # $ gpg --verify libxml2-2.9.10.tar.gz.asc ports/archives/libxml2-2.9.10.tar.gz
7
- # gpg: Signature made Wed 30 Oct 2019 03:15:42 PM EDT
6
+ # $ gpg --verify libxml2-2.9.12.tar.gz.asc ports/archives/libxml2-2.9.12.tar.gz
7
+ # gpg: Signature made Thu 13 May 2021 02:59:16 PM EDT
8
8
  # gpg: using RSA key DB46681BB91ADCEA170FA2D415588B26596BEA5D
9
9
  # gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard@redhat.com>" [unknown]
10
10
  # gpg: aka "Daniel Veillard <Daniel.Veillard@w3.org>" [unknown]
@@ -17,14 +17,14 @@ libxml2:
17
17
  #
18
18
  # -----BEGIN PGP SIGNATURE-----
19
19
  #
20
- # iQEzBAABCAAdFiEE20ZoG7ka3OoXD6LUFViLJllr6l0FAl254V4ACgkQFViLJllr
21
- # 6l0ldAf6Azt4/oKDfMKRd+xaykUrb+34dr2ZRsjRDS1cnelAtL9TCWhE5lOkLI3c
22
- # 3FyNRaLhOEOOluZmKTJYyzS42JSSHDhxGj14gIeyafOjvRhHG3h1m5GvMmvgKWkd
23
- # qzxFrVFSG26iWJxMvxIA88t7M+QHb7ff7xR29ETJscewEmAd3LmZITglK02lWeGz
24
- # LfxfLuakM6RnCUu0dzacJKO0nMOKju+RL/N9bciI/UOhNYEkWqPnzC0GzbvFLqDu
25
- # rM+OvCSewSTziiejpdrUwYXkY5Ui2+cxUbacLauEr8iRLg7xXKqv27NORE4yeQcS
26
- # LgIhxG/qSNfihMS6E1ZO5bK2DbGCZQ==
27
- # =ZNuc
20
+ # iQEzBAABCAAdFiEE20ZoG7ka3OoXD6LUFViLJllr6l0FAmCddwQACgkQFViLJllr
21
+ # 6l11LQgAioRTdfmcC+uK/7+6HPtF/3c5zkX6j8VGYuvFBwZ0jayqMRBAl++fcpjE
22
+ # JUU/JKebSZ/KCYjzyeOWK/i3Gq77iqm3UbZFB85rqu4a5P3gmj/4STWVyAx0KU3z
23
+ # G3jKqDhJOt7c0acXb5lh2DngfDa1dn/VGcQcIXsqplNxNr4ET7MnSJjZ3nlxYfW2
24
+ # E5vWBdPCMUeXDBl6MjYvw9XnGGBLUAaEJWoFToG6jKmVf4GAd9nza20jj5dtbcJq
25
+ # QEOaSDKDr+f9h2NS8haOhJ9vOpy52PdeGzaFlbRkXarGXuAr8kITgATVs8FAqcgv
26
+ # MoVhmrO5r2hJf0dCM9fZoYqzpMfmNA==
27
+ # =KfJ9
28
28
  # -----END PGP SIGNATURE-----
29
29
  #
30
30
 
@@ -191,7 +191,26 @@ Init_nokogiri()
191
191
  rb_const_set(mNokogiri, rb_intern("OTHER_LIBRARY_VERSIONS"), NOKOGIRI_STR_NEW2(NOKOGIRI_OTHER_LIBRARY_VERSIONS));
192
192
  #endif
193
193
 
194
+ #if defined(_WIN32) && !defined(NOKOGIRI_PACKAGED_LIBRARIES)
195
+ /*
196
+ * We choose *not* to do use Ruby's memory management functions with windows DLLs because of this
197
+ * issue in libxml 2.9.12:
198
+ *
199
+ * https://github.com/sparklemotion/nokogiri/issues/2241
200
+ *
201
+ * If the atexit() issue gets fixed in a future version of libxml2, then we may be able to skip
202
+ * this config only for the specific libxml2 versions 2.9.12.
203
+ *
204
+ * Alternatively, now that Ruby has a generational GC, it might be OK to let libxml2 use its
205
+ * default memory management functions (recall that this config was introduced to reduce memory
206
+ * bloat and allow Ruby to GC more often); but we should *really* test with production workloads
207
+ * before making that kind of a potentially-invasive change.
208
+ */
209
+ rb_const_set(mNokogiri, rb_intern("LIBXML_MEMORY_MANAGEMENT"), NOKOGIRI_STR_NEW2("default"));
210
+ #else
211
+ rb_const_set(mNokogiri, rb_intern("LIBXML_MEMORY_MANAGEMENT"), NOKOGIRI_STR_NEW2("ruby"));
194
212
  xmlMemSetup((xmlFreeFunc)ruby_xfree, (xmlMallocFunc)ruby_xmalloc, (xmlReallocFunc)ruby_xrealloc, ruby_strdup);
213
+ #endif
195
214
 
196
215
  xmlInitParser();
197
216
 
@@ -141,42 +141,41 @@ url(VALUE self)
141
141
  * Set the root element on this document
142
142
  */
143
143
  static VALUE
144
- set_root(VALUE self, VALUE root)
144
+ rb_xml_document_root_set(VALUE self, VALUE rb_new_root)
145
145
  {
146
- xmlDocPtr doc;
147
- xmlNodePtr new_root;
148
- xmlNodePtr old_root;
149
-
150
- Data_Get_Struct(self, xmlDoc, doc);
146
+ xmlDocPtr c_document;
147
+ xmlNodePtr c_new_root = NULL, c_current_root;
151
148
 
152
- old_root = NULL;
153
-
154
- if (NIL_P(root)) {
155
- old_root = xmlDocGetRootElement(doc);
156
-
157
- if (old_root) {
158
- xmlUnlinkNode(old_root);
159
- noko_xml_document_pin_node(old_root);
160
- }
149
+ Data_Get_Struct(self, xmlDoc, c_document);
161
150
 
162
- return root;
151
+ c_current_root = xmlDocGetRootElement(c_document);
152
+ if (c_current_root) {
153
+ xmlUnlinkNode(c_current_root);
154
+ noko_xml_document_pin_node(c_current_root);
163
155
  }
164
156
 
165
- Data_Get_Struct(root, xmlNode, new_root);
157
+ if (!NIL_P(rb_new_root)) {
158
+ if (!rb_obj_is_kind_of(rb_new_root, cNokogiriXmlNode)) {
159
+ rb_raise(rb_eArgError,
160
+ "expected Nokogiri::XML::Node but received %"PRIsVALUE,
161
+ rb_obj_class(rb_new_root));
162
+ }
166
163
 
164
+ Data_Get_Struct(rb_new_root, xmlNode, c_new_root);
167
165
 
168
- /* If the new root's document is not the same as the current document,
169
- * then we need to dup the node in to this document. */
170
- if (new_root->doc != doc) {
171
- old_root = xmlDocGetRootElement(doc);
172
- if (!(new_root = xmlDocCopyNode(new_root, doc, 1))) {
173
- rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
166
+ /* If the new root's document is not the same as the current document,
167
+ * then we need to dup the node in to this document. */
168
+ if (c_new_root->doc != c_document) {
169
+ c_new_root = xmlDocCopyNode(c_new_root, c_document, 1);
170
+ if (!c_new_root) {
171
+ rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
172
+ }
174
173
  }
175
174
  }
176
175
 
177
- xmlDocSetRootElement(doc, new_root);
178
- if (old_root) { noko_xml_document_pin_node(old_root); }
179
- return root;
176
+ xmlDocSetRootElement(c_document, c_new_root);
177
+
178
+ return rb_new_root;
180
179
  }
181
180
 
182
181
  /*
@@ -186,17 +185,19 @@ set_root(VALUE self, VALUE root)
186
185
  * Get the root node for this document.
187
186
  */
188
187
  static VALUE
189
- root(VALUE self)
188
+ rb_xml_document_root(VALUE self)
190
189
  {
191
- xmlDocPtr doc;
192
- xmlNodePtr root;
190
+ xmlDocPtr c_document;
191
+ xmlNodePtr c_root;
193
192
 
194
- Data_Get_Struct(self, xmlDoc, doc);
193
+ Data_Get_Struct(self, xmlDoc, c_document);
195
194
 
196
- root = xmlDocGetRootElement(doc);
195
+ c_root = xmlDocGetRootElement(c_document);
196
+ if (!c_root) {
197
+ return Qnil;
198
+ }
197
199
 
198
- if (!root) { return Qnil; }
199
- return noko_xml_node_wrap(Qnil, root) ;
200
+ return noko_xml_node_wrap(Qnil, c_root) ;
200
201
  }
201
202
 
202
203
  /*
@@ -666,8 +667,8 @@ noko_init_xml_document()
666
667
  rb_define_singleton_method(cNokogiriXmlDocument, "read_io", read_io, 4);
667
668
  rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1);
668
669
 
669
- rb_define_method(cNokogiriXmlDocument, "root", root, 0);
670
- rb_define_method(cNokogiriXmlDocument, "root=", set_root, 1);
670
+ rb_define_method(cNokogiriXmlDocument, "root", rb_xml_document_root, 0);
671
+ rb_define_method(cNokogiriXmlDocument, "root=", rb_xml_document_root_set, 1);
671
672
  rb_define_method(cNokogiriXmlDocument, "encoding", encoding, 0);
672
673
  rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1);
673
674
  rb_define_method(cNokogiriXmlDocument, "version", version, 0);
@@ -2,7 +2,7 @@
2
2
 
3
3
  VALUE cNokogiriXmlNode ;
4
4
 
5
- static ID decorate, decorate_bang;
5
+ static ID id_decorate, id_decorate_bang;
6
6
 
7
7
  #ifdef DEBUG
8
8
  static void
@@ -357,7 +357,7 @@ ok:
357
357
 
358
358
  reparented_obj = noko_xml_node_wrap(Qnil, reparented);
359
359
 
360
- rb_funcall(reparented_obj, decorate_bang, 0);
360
+ rb_funcall(reparented_obj, id_decorate_bang, 0);
361
361
 
362
362
  return reparented_obj ;
363
363
  }
@@ -1292,17 +1292,25 @@ get_name(VALUE self)
1292
1292
  * Returns the path associated with this Node
1293
1293
  */
1294
1294
  static VALUE
1295
- path(VALUE self)
1295
+ noko_xml_node_path(VALUE rb_node)
1296
1296
  {
1297
- xmlNodePtr node;
1298
- xmlChar *path ;
1297
+ xmlNodePtr c_node;
1298
+ xmlChar *c_path ;
1299
1299
  VALUE rval;
1300
1300
 
1301
- Data_Get_Struct(self, xmlNode, node);
1301
+ Data_Get_Struct(rb_node, xmlNode, c_node);
1302
+
1303
+ c_path = xmlGetNodePath(c_node);
1304
+ if (c_path == NULL) {
1305
+ // see https://github.com/sparklemotion/nokogiri/issues/2250
1306
+ // this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we
1307
+ // do this for now to preserve the behavior across libxml2 versions.
1308
+ rval = NOKOGIRI_STR_NEW2("?");
1309
+ } else {
1310
+ rval = NOKOGIRI_STR_NEW2(c_path);
1311
+ xmlFree(c_path);
1312
+ }
1302
1313
 
1303
- path = xmlGetNodePath(node);
1304
- rval = NOKOGIRI_STR_NEW2(path);
1305
- xmlFree(path);
1306
1314
  return rval ;
1307
1315
  }
1308
1316
 
@@ -1443,6 +1451,7 @@ add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href)
1443
1451
  * Create a new node with +name+ sharing GC lifecycle with +document+.
1444
1452
  * @param name [String]
1445
1453
  * @param document [Nokogiri::XML::Document]
1454
+ * @yieldparam node [Nokogiri::XML::Node]
1446
1455
  * @return [Nokogiri::XML::Node]
1447
1456
  * @see Nokogiri::XML::Node#initialize
1448
1457
  */
@@ -1655,85 +1664,83 @@ in_context(VALUE self, VALUE _str, VALUE _options)
1655
1664
 
1656
1665
 
1657
1666
  VALUE
1658
- noko_xml_node_wrap(VALUE klass, xmlNodePtr node)
1667
+ noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node)
1659
1668
  {
1660
- VALUE document = Qnil ;
1661
- VALUE node_cache = Qnil ;
1662
- VALUE rb_node = Qnil ;
1669
+ VALUE rb_document, rb_node_cache, rb_node;
1663
1670
  nokogiriTuplePtr node_has_a_document;
1664
- xmlDocPtr doc;
1671
+ xmlDocPtr c_doc;
1665
1672
  void (*mark_method)(xmlNodePtr) = NULL ;
1666
1673
 
1667
- assert(node);
1674
+ assert(c_node);
1668
1675
 
1669
- if (node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE) {
1670
- return DOC_RUBY_OBJECT(node->doc);
1676
+ if (c_node->type == XML_DOCUMENT_NODE || c_node->type == XML_HTML_DOCUMENT_NODE) {
1677
+ return DOC_RUBY_OBJECT(c_node->doc);
1671
1678
  }
1672
1679
 
1673
1680
  /* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
1674
1681
  /* see https://github.com/sparklemotion/nokogiri/issues/95 */
1675
1682
  /* and https://github.com/sparklemotion/nokogiri/issues/439 */
1676
- doc = node->doc;
1677
- if (doc->type == XML_DOCUMENT_FRAG_NODE) { doc = doc->doc; }
1678
- node_has_a_document = DOC_RUBY_OBJECT_TEST(doc);
1683
+ c_doc = c_node->doc;
1684
+ if (c_doc->type == XML_DOCUMENT_FRAG_NODE) { c_doc = c_doc->doc; }
1685
+ node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc);
1679
1686
 
1680
- if (node->_private && node_has_a_document) {
1681
- return (VALUE)node->_private;
1687
+ if (c_node->_private && node_has_a_document) {
1688
+ return (VALUE)c_node->_private;
1682
1689
  }
1683
1690
 
1684
- if (!RTEST(klass)) {
1685
- switch (node->type) {
1691
+ if (!RTEST(rb_class)) {
1692
+ switch (c_node->type) {
1686
1693
  case XML_ELEMENT_NODE:
1687
- klass = cNokogiriXmlElement;
1694
+ rb_class = cNokogiriXmlElement;
1688
1695
  break;
1689
1696
  case XML_TEXT_NODE:
1690
- klass = cNokogiriXmlText;
1697
+ rb_class = cNokogiriXmlText;
1691
1698
  break;
1692
1699
  case XML_ATTRIBUTE_NODE:
1693
- klass = cNokogiriXmlAttr;
1700
+ rb_class = cNokogiriXmlAttr;
1694
1701
  break;
1695
1702
  case XML_ENTITY_REF_NODE:
1696
- klass = cNokogiriXmlEntityReference;
1703
+ rb_class = cNokogiriXmlEntityReference;
1697
1704
  break;
1698
1705
  case XML_COMMENT_NODE:
1699
- klass = cNokogiriXmlComment;
1706
+ rb_class = cNokogiriXmlComment;
1700
1707
  break;
1701
1708
  case XML_DOCUMENT_FRAG_NODE:
1702
- klass = cNokogiriXmlDocumentFragment;
1709
+ rb_class = cNokogiriXmlDocumentFragment;
1703
1710
  break;
1704
1711
  case XML_PI_NODE:
1705
- klass = cNokogiriXmlProcessingInstruction;
1712
+ rb_class = cNokogiriXmlProcessingInstruction;
1706
1713
  break;
1707
1714
  case XML_ENTITY_DECL:
1708
- klass = cNokogiriXmlEntityDecl;
1715
+ rb_class = cNokogiriXmlEntityDecl;
1709
1716
  break;
1710
1717
  case XML_CDATA_SECTION_NODE:
1711
- klass = cNokogiriXmlCData;
1718
+ rb_class = cNokogiriXmlCData;
1712
1719
  break;
1713
1720
  case XML_DTD_NODE:
1714
- klass = cNokogiriXmlDtd;
1721
+ rb_class = cNokogiriXmlDtd;
1715
1722
  break;
1716
1723
  case XML_ATTRIBUTE_DECL:
1717
- klass = cNokogiriXmlAttributeDecl;
1724
+ rb_class = cNokogiriXmlAttributeDecl;
1718
1725
  break;
1719
1726
  case XML_ELEMENT_DECL:
1720
- klass = cNokogiriXmlElementDecl;
1727
+ rb_class = cNokogiriXmlElementDecl;
1721
1728
  break;
1722
1729
  default:
1723
- klass = cNokogiriXmlNode;
1730
+ rb_class = cNokogiriXmlNode;
1724
1731
  }
1725
1732
  }
1726
1733
 
1727
1734
  mark_method = node_has_a_document ? mark : NULL ;
1728
1735
 
1729
- rb_node = Data_Wrap_Struct(klass, mark_method, debug_node_dealloc, node) ;
1730
- node->_private = (void *)rb_node;
1736
+ rb_node = Data_Wrap_Struct(rb_class, mark_method, debug_node_dealloc, c_node) ;
1737
+ c_node->_private = (void *)rb_node;
1731
1738
 
1732
1739
  if (node_has_a_document) {
1733
- document = DOC_RUBY_OBJECT(doc);
1734
- node_cache = DOC_NODE_CACHE(doc);
1735
- rb_ary_push(node_cache, rb_node);
1736
- rb_funcall(document, decorate, 1, rb_node);
1740
+ rb_document = DOC_RUBY_OBJECT(c_doc);
1741
+ rb_node_cache = DOC_NODE_CACHE(c_doc);
1742
+ rb_ary_push(rb_node_cache, rb_node);
1743
+ rb_funcall(rb_document, id_decorate, 1, rb_node);
1737
1744
  }
1738
1745
 
1739
1746
  return rb_node ;
@@ -1780,7 +1787,7 @@ noko_init_xml_node()
1780
1787
  rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0);
1781
1788
  rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0);
1782
1789
  rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0);
1783
- rb_define_method(cNokogiriXmlNode, "path", path, 0);
1790
+ rb_define_method(cNokogiriXmlNode, "path", noko_xml_node_path, 0);
1784
1791
  rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1);
1785
1792
  rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2);
1786
1793
  rb_define_method(cNokogiriXmlNode, "blank?", blank_eh, 0);
@@ -1818,8 +1825,8 @@ noko_init_xml_node()
1818
1825
  rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1);
1819
1826
  rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1);
1820
1827
 
1821
- decorate = rb_intern("decorate");
1822
- decorate_bang = rb_intern("decorate!");
1828
+ id_decorate = rb_intern("decorate");
1829
+ id_decorate_bang = rb_intern("decorate!");
1823
1830
  }
1824
1831
 
1825
1832
  /* vim: set noet sw=4 sws=4 */
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Nokogiri
3
3
  # The version of Nokogiri you are using
4
- VERSION = "1.11.2"
4
+ VERSION = "1.11.7"
5
5
  end
@@ -137,6 +137,7 @@ module Nokogiri
137
137
  else
138
138
  libxml["source"] = "system"
139
139
  end
140
+ libxml["memory_management"] = Nokogiri::LIBXML_MEMORY_MANAGEMENT
140
141
  libxml["iconv_enabled"] = libxml2_has_iconv?
141
142
  libxml["compiled"] = compiled_libxml_version.to_s
142
143
  libxml["loaded"] = loaded_libxml_version.to_s
@@ -14,11 +14,12 @@ module Nokogiri
14
14
  # Nokogiri::XML::Searchable#xpath
15
15
  #
16
16
  class Document < Nokogiri::XML::Node
17
- # I'm ignoring unicode characters here.
18
- # See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details.
17
+ # See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details. Note that we're not
18
+ # attempting to handle unicode characters partly because libxml2 doesn't handle unicode
19
+ # characters in NCNAMEs.
19
20
  NCNAME_START_CHAR = "A-Za-z_"
20
- NCNAME_CHAR = NCNAME_START_CHAR + "\\-.0-9"
21
- NCNAME_RE = /^xmlns(:[#{NCNAME_START_CHAR}][#{NCNAME_CHAR}]*)?$/
21
+ NCNAME_CHAR = NCNAME_START_CHAR + "\\-\\.0-9"
22
+ NCNAME_RE = /^xmlns(?::([#{NCNAME_START_CHAR}][#{NCNAME_CHAR}]*))?$/
22
23
 
23
24
  ##
24
25
  # Parse an XML file.
@@ -118,33 +119,58 @@ module Nokogiri
118
119
  end
119
120
 
120
121
  ##
121
- # Create an element with +name+, and optionally setting the content and attributes.
122
+ # Create a new +Element+ with +name+ sharing GC lifecycle with the document, optionally
123
+ # setting contents or attributes.
122
124
  #
123
- # doc.create_element "div" # <div></div>
124
- # doc.create_element "div", :class => "container" # <div class='container'></div>
125
- # doc.create_element "div", "contents" # <div>contents</div>
126
- # doc.create_element "div", "contents", :class => "container" # <div class='container'>contents</div>
127
- # doc.create_element "div" { |node| node['class'] = "container" } # <div class='container'></div>
125
+ # Arguments may be passed to initialize the element:
126
+ # - a +Hash+ argument will be used to set attributes
127
+ # - a non-Hash object that responds to +#to_s+ will be used to set the new node's contents
128
128
  #
129
- def create_element name, *args, &block
129
+ # A block may be passed to mutate the node.
130
+ #
131
+ # @param name [String]
132
+ # @param contents_or_attrs [#to_s,Hash]
133
+ # @yieldparam node [Nokogiri::XML::Element]
134
+ # @return [Nokogiri::XML::Element]
135
+ #
136
+ # @example An empty element without attributes
137
+ # doc.create_element("div")
138
+ # # => <div></div>
139
+ #
140
+ # @example An element with contents
141
+ # doc.create_element("div", "contents")
142
+ # # => <div>contents</div>
143
+ #
144
+ # @example An element with attributes
145
+ # doc.create_element("div", {"class" => "container"})
146
+ # # => <div class='container'></div>
147
+ #
148
+ # @example An element with contents and attributes
149
+ # doc.create_element("div", "contents", {"class" => "container"})
150
+ # # => <div class='container'>contents</div>
151
+ #
152
+ # @example Passing a block to mutate the element
153
+ # doc.create_element("div") { |node| node["class"] = "blue" if before_noon? }
154
+ #
155
+ def create_element(name, *contents_or_attrs, &block)
130
156
  elm = Nokogiri::XML::Element.new(name, self, &block)
131
- args.each do |arg|
157
+ contents_or_attrs.each do |arg|
132
158
  case arg
133
159
  when Hash
134
- arg.each { |k,v|
160
+ arg.each do |k, v|
135
161
  key = k.to_s
136
162
  if key =~ NCNAME_RE
137
- ns_name = key.split(":", 2)[1]
138
- elm.add_namespace_definition ns_name, v
163
+ ns_name = Regexp.last_match(1)
164
+ elm.add_namespace_definition(ns_name, v)
139
165
  else
140
166
  elm[k.to_s] = v.to_s
141
167
  end
142
- }
168
+ end
143
169
  else
144
170
  elm.content = arg
145
171
  end
146
172
  end
147
- if ns = elm.namespace_definitions.find { |n| n.prefix.nil? or n.prefix == '' }
173
+ if ns = elm.namespace_definitions.find { |n| n.prefix.nil? || (n.prefix == '') }
148
174
  elm.namespace = ns
149
175
  end
150
176
  elm