nokogiri 1.8.5 → 1.9.0.rc1

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8a0b2422e8eb44142a8f8c1c0a0443b844db2a9d73c66bba59f239d800be9da
4
- data.tar.gz: eee2e520dd02954386e3b3c83b02ff9fcb12339edcfc9aaf124835badd9b3239
3
+ metadata.gz: d658fc7d5957c3a7ebb52b4760fe6a3e1b65bacdacd70c1ed6e193aea0742d3d
4
+ data.tar.gz: 2078571efdde9bc3a78b97545f3edbe5953b6ae4b977604362fcc2d22b14469c
5
5
  SHA512:
6
- metadata.gz: c967b49cdb174560fc8519d3e7e7252e4d3bd6e7fde2d13e3b052a9c050291e6ea375cb039fbb96ab9599516bf1dba33e3d606175c08a7db07e4c1abc1f16d4a
7
- data.tar.gz: ff74b9432fddaff768ba2bda7547461c86ec65133b9c1818a178b75d4db603d1a200204a95e16c5b7fc563f39d2210446ddcf9d18a8eeb4939d597b957074b26
6
+ metadata.gz: 8683c1e51a8ede1daf265e9a33af1aba329b91489c75da8608d40f0c06d2823d833236f21f05914acd860b7722822d8f9a9f36f3120a907eb126be8fe5b984b9
7
+ data.tar.gz: 134e6617355b1bb6aac6729c7a0ca0ceeead11304eaf28dd383a8c90b1e20be83aa16246e7bb90abddaba20cf7f203baba49756f4931735814502542cb40ad3c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ # 1.9.0.rc1 / 2018-12-10
2
+
3
+ ## Security Notes
4
+
5
+ * [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 to address upstream vulnerability CVE-2012-0881 [#1831] (Thanks @grajagandev for reporting.)
6
+
7
+
8
+ ## Features
9
+
10
+ * `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800]
11
+ * Introduce `XML::Node#wrap` which does what `XML::NodeSet#wrap` has always done, but for a single node. [#1531] (Thanks, @ethirajsrinivasan!)
12
+ * [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!)
13
+ * [MRI] Node#dup supports copying a node directly to a new document. See the method documentation for details.
14
+ * [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063]
15
+ * [JRuby] NodeSet has been rewritten to improve performance! [#1795]
16
+
17
+
18
+ ## Bug fixes
19
+
20
+ * `NodeSet#each` now returns `self` instead of zero. [#1822] (Thanks, @olehif!)
21
+ * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810]
22
+ * [MRI] Address a memory leak when unparenting a DTD. [#1784] (Thanks, @stevecheckoway!)
23
+ * [MRI] Decrease large memory usage when making nested XPath queries. [#1749]
24
+ * [MRI] Use RbConfig::CONFIG instead of ::MAKEFILE_CONFIG to fix installations that use Makefile macros. [#1820] (Thanks, @nobu!)
25
+ * [JRuby] Fix failing tests on JRuby 9.2.x
26
+ * [JRuby] Fix default namespaces in nodes reparented into a different document [#1774]
27
+ * [JRuby] Fix support for Java 9. [#1759] (Thanks, @Taywee!)
28
+
29
+
30
+ ## Dependencies
31
+
32
+ * [MRI] Upgrade mini_portile2 dependency from `~> 2.3.0` to `~> 2.4.0`
33
+
34
+
1
35
  # 1.8.5 / 2018-10-04
2
36
 
3
37
  ## Security Notes
data/Gemfile CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  source "https://rubygems.org/"
6
6
 
7
- gem "mini_portile2", "~>2.3.0"
7
+ gem "mini_portile2", "~>2.4.0"
8
8
 
9
9
  gem "hoe-bundler", "~>1.2", :group => [:development, :test]
10
- gem "hoe-debugging", "~>1.4", :group => [:development, :test]
10
+ gem "hoe-debugging", "~>2.0", :group => [:development, :test]
11
11
  gem "hoe-gemspec", "~>1.0", :group => [:development, :test]
12
12
  gem "hoe-git", "~>1.6", :group => [:development, :test]
13
13
  gem "minitest", "~>5.8.4", :group => [:development, :test]
@@ -17,7 +17,7 @@ gem "rake-compiler-dock", "~>0.6.2", :group => [:development, :test]
17
17
  gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw]
18
18
  gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw]
19
19
  gem "concourse", "~>0.15", :group => [:development, :test]
20
- gem "rdoc", "~>4.0", :group => [:development, :test]
21
- gem "hoe", "~>3.16", :group => [:development, :test]
20
+ gem "rdoc", ">=4.0", "<7", :group => [:development, :test]
21
+ gem "hoe", "~>3.17", :group => [:development, :test]
22
22
 
23
23
  # vim: syntax=ruby
data/Manifest.txt CHANGED
@@ -81,6 +81,8 @@ ext/java/nokogiri/internals/XalanDTMManagerPatch.java
81
81
  ext/java/nokogiri/internals/XmlDeclHandler.java
82
82
  ext/java/nokogiri/internals/XmlDomParserContext.java
83
83
  ext/java/nokogiri/internals/XmlSaxParser.java
84
+ ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java
85
+ ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java
84
86
  ext/java/nokogiri/internals/c14n/AttrCompare.java
85
87
  ext/java/nokogiri/internals/c14n/C14nHelper.java
86
88
  ext/java/nokogiri/internals/c14n/CanonicalFilter.java
@@ -108,7 +110,6 @@ ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java
108
110
  ext/java/nokogiri/internals/c14n/NodeFilter.java
109
111
  ext/java/nokogiri/internals/c14n/UtfHelpper.java
110
112
  ext/java/nokogiri/internals/c14n/XMLUtils.java
111
- ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java
112
113
  ext/nokogiri/depend
113
114
  ext/nokogiri/extconf.rb
114
115
  ext/nokogiri/html_document.c
data/README.md CHANGED
@@ -18,7 +18,6 @@ or CSS3 selectors.
18
18
 
19
19
  [![Concourse CI](https://ci.nokogiri.org/api/v1/teams/nokogiri-core/pipelines/nokogiri/jobs/ruby-2.4-system/badge)](https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri?groups=master)
20
20
  [![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.svg)](https://codeclimate.com/github/sparklemotion/nokogiri)
21
- [![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri)
22
21
  [![Join the chat at https://gitter.im/sparklemotion/nokogiri](https://badges.gitter.im/sparklemotion/nokogiri.svg)](https://gitter.im/sparklemotion/nokogiri?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
23
22
 
24
23
 
data/Rakefile CHANGED
@@ -127,13 +127,13 @@ HOE = Hoe.spec 'nokogiri' do
127
127
 
128
128
  unless java?
129
129
  self.extra_deps += [
130
- ["mini_portile2", "~> 2.3.0"], # keep version in sync with extconf.rb
130
+ ["mini_portile2", "~> 2.4.0"], # keep version in sync with extconf.rb
131
131
  ]
132
132
  end
133
133
 
134
134
  self.extra_dev_deps += [
135
135
  ["hoe-bundler", "~> 1.2"],
136
- ["hoe-debugging", "~> 1.4"],
136
+ ["hoe-debugging", "~> 2.0"],
137
137
  ["hoe-gemspec", "~> 1.0"],
138
138
  ["hoe-git", "~> 1.6"],
139
139
  ["minitest", "~> 5.8.4"],
@@ -266,11 +266,21 @@ task 'bundler:gemfile' do
266
266
  end
267
267
 
268
268
  file GENERATED_PARSER => "lib/nokogiri/css/parser.y" do |t|
269
- sh "racc -l -o #{t.name} #{t.prerequisites.first}"
269
+ if java?
270
+ warn "WARNING: #{GENERATED_PARSER} may be out of date:"
271
+ sh "ls -lt #{t.name} #{t.prerequisites.first}"
272
+ else
273
+ sh "racc -l -o #{t.name} #{t.prerequisites.first}"
274
+ end
270
275
  end
271
276
 
272
277
  file GENERATED_TOKENIZER => "lib/nokogiri/css/tokenizer.rex" do |t|
273
- sh "rex --independent -o #{t.name} #{t.prerequisites.first}"
278
+ if java?
279
+ warn "WARNING: #{GENERATED_TOKENIZER} may be out of date:"
280
+ sh "ls -lt #{t.name} #{t.prerequisites.first}"
281
+ else
282
+ sh "rex --independent -o #{t.name} #{t.prerequisites.first}"
283
+ end
274
284
  end
275
285
 
276
286
  [:compile, :check_manifest].each do |task_name|
data/build_all CHANGED
@@ -17,6 +17,10 @@ fi
17
17
 
18
18
  set -o errexit
19
19
 
20
+ # check that we have the latest jruby
21
+ rvm use jruby
22
+ rvm use ruby
23
+
20
24
  rm -rf tmp pkg
21
25
  bundle exec rake clean clobber
22
26
 
@@ -37,7 +41,7 @@ cp -v pkg/nokogiri*.gem gems
37
41
  bundle exec rake clean clobber
38
42
  bundle exec rake generate
39
43
 
40
- rvm jruby
44
+ rvm use jruby
41
45
  gem install bundler --conservative
42
46
  bundle install --quiet --local || bundle install
43
47
  bundle exec ruby -S rake gem
@@ -400,9 +400,11 @@ if openbsd? && !using_system_libraries?
400
400
  ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /usr/local/include"
401
401
  end
402
402
 
403
- RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
403
+ if ENV['CC']
404
+ RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
405
+ end
404
406
  # use same c compiler for libxml and libxslt
405
- ENV['CC'] = RbConfig::MAKEFILE_CONFIG['CC']
407
+ ENV['CC'] = RbConfig::CONFIG['CC']
406
408
 
407
409
  $LIBS << " #{ENV["LIBS"]}"
408
410
 
@@ -432,7 +434,7 @@ if RUBY_PLATFORM =~ /mingw/i
432
434
  $CPPFLAGS << ' "-Idummypath"'
433
435
  end
434
436
 
435
- if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
437
+ if RbConfig::CONFIG['CC'] =~ /gcc/
436
438
  $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
437
439
  $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wmissing-noreturn -Winline"
438
440
  end
@@ -460,7 +462,7 @@ else
460
462
  # The gem version constraint in the Rakefile is not respected at install time.
461
463
  # Keep this version in sync with the one in the Rakefile !
462
464
  require 'rubygems'
463
- gem 'mini_portile2', '~> 2.3.0'
465
+ gem 'mini_portile2', '~> 2.4.0'
464
466
  require 'mini_portile2'
465
467
  message "Using mini_portile version #{MiniPortile::VERSION}\n"
466
468
 
@@ -560,7 +562,8 @@ EOM
560
562
  *(libiconv_recipe ? "--with-iconv=#{libiconv_recipe.path}" : iconv_configure_flags),
561
563
  "--with-c14n",
562
564
  "--with-debug",
563
- "--with-threads"
565
+ "--with-threads",
566
+ *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
564
567
  ]
565
568
  end
566
569
 
@@ -573,7 +576,8 @@ EOM
573
576
  "--without-python",
574
577
  "--without-crypto",
575
578
  "--with-debug",
576
- "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}"
579
+ "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}",
580
+ *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "")
577
581
  ]
578
582
  end
579
583
 
@@ -4,37 +4,40 @@
4
4
  * call-seq:
5
5
  * value=(content)
6
6
  *
7
- * Set the value for this Attr to +content+
7
+ * Set the value for this Attr to +content+. Use `nil` to remove the value
8
+ * (e.g., a HTML boolean attribute).
8
9
  */
9
10
  static VALUE set_value(VALUE self, VALUE content)
10
11
  {
11
12
  xmlAttrPtr attr;
12
- Data_Get_Struct(self, xmlAttr, attr);
13
+ xmlChar *value;
14
+ xmlNode *cur;
13
15
 
14
- if (attr->children) { xmlFreeNodeList(attr->children); }
16
+ Data_Get_Struct(self, xmlAttr, attr);
15
17
 
18
+ if (attr->children) {
19
+ xmlFreeNodeList(attr->children);
20
+ }
16
21
  attr->children = attr->last = NULL;
17
22
 
18
- if (content) {
19
- xmlChar *buffer;
20
- xmlNode *tmp;
21
-
22
- /* Encode our content */
23
- buffer = xmlEncodeEntitiesReentrant(attr->doc, (unsigned char *)StringValueCStr(content));
23
+ if (content == Qnil) {
24
+ return content;
25
+ }
24
26
 
25
- attr->children = xmlStringGetNodeList(attr->doc, buffer);
26
- attr->last = NULL;
27
- tmp = attr->children;
27
+ value = xmlEncodeEntitiesReentrant(attr->doc, (unsigned char *)StringValueCStr(content));
28
+ if (xmlStrlen(value) == 0) {
29
+ attr->children = xmlNewDocText(attr->doc, value);
30
+ } else {
31
+ attr->children = xmlStringGetNodeList(attr->doc, value);
32
+ }
33
+ xmlFree(value);
28
34
 
29
- /* Loop through the children */
30
- for(tmp = attr->children; tmp; tmp = tmp->next) {
31
- tmp->parent = (xmlNode *)attr;
32
- tmp->doc = attr->doc;
33
- if (tmp->next == NULL) { attr->last = tmp; }
35
+ for (cur = attr->children; cur; cur = cur->next) {
36
+ cur->parent = (xmlNode *)attr;
37
+ cur->doc = attr->doc;
38
+ if (cur->next == NULL) {
39
+ attr->last = cur;
34
40
  }
35
-
36
- /* Free up memory */
37
- xmlFree(buffer);
38
41
  }
39
42
 
40
43
  return content;
@@ -74,7 +77,9 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
74
77
  rb_node = Nokogiri_wrap_xml_node(klass, (xmlNodePtr)node);
75
78
  rb_obj_call_init(rb_node, argc, argv);
76
79
 
77
- if (rb_block_given_p()) { rb_yield(rb_node); }
80
+ if (rb_block_given_p()) {
81
+ rb_yield(rb_node);
82
+ }
78
83
 
79
84
  return rb_node;
80
85
  }
@@ -7,7 +7,10 @@ static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
7
7
  xmlFreePropList((xmlAttrPtr)node);
8
8
  break;
9
9
  case XML_NAMESPACE_DECL:
10
- xmlFree(node);
10
+ xmlFreeNs((xmlNsPtr)node);
11
+ break;
12
+ case XML_DTD_NODE:
13
+ xmlFreeDtd((xmlDtdPtr)node);
11
14
  break;
12
15
  default:
13
16
  if(node->parent == NULL) {
@@ -63,7 +63,7 @@ static int part_of_an_xpath_node_set_eh(xmlNsPtr node)
63
63
 
64
64
  VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
65
65
  {
66
- VALUE ns, document, node_cache;
66
+ VALUE ns = 0, document, node_cache;
67
67
 
68
68
  assert(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE);
69
69
 
@@ -71,8 +71,6 @@ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
71
71
 
72
72
  if (doc->type == XML_DOCUMENT_FRAG_NODE) doc = doc->doc;
73
73
 
74
- ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);
75
-
76
74
  if (DOC_RUBY_OBJECT_TEST(doc)) {
77
75
  document = DOC_RUBY_OBJECT(doc);
78
76
 
@@ -91,6 +89,8 @@ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
91
89
  }
92
90
 
93
91
  rb_iv_set(ns, "@document", document);
92
+ } else {
93
+ ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);
94
94
  }
95
95
 
96
96
  node->_private = (void *)ns;
@@ -7,8 +7,7 @@ void init_xml_namespace();
7
7
 
8
8
  extern VALUE cNokogiriXmlNamespace ;
9
9
 
10
- VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) ;
11
- VALUE Nokogiri_wrap_xml_namespace2(VALUE document, xmlNsPtr node) ;
10
+ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node);
12
11
 
13
12
  #define NOKOGIRI_NAMESPACE_EH(node) ((node)->type == XML_NAMESPACE_DECL)
14
13
 
@@ -31,13 +31,13 @@ typedef xmlNodePtr (*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr);
31
31
  static void relink_namespace(xmlNodePtr reparented)
32
32
  {
33
33
  xmlNodePtr child;
34
- xmlNsPtr ns;
35
34
 
36
35
  if (reparented->type != XML_ATTRIBUTE_NODE &&
37
36
  reparented->type != XML_ELEMENT_NODE) { return; }
38
37
 
39
38
  if (reparented->ns == NULL || reparented->ns->prefix == NULL) {
40
- xmlChar *name = 0, *prefix = 0;
39
+ xmlNsPtr ns = NULL;
40
+ xmlChar *name = NULL, *prefix = NULL;
41
41
 
42
42
  name = xmlSplitQName2(reparented->name, &prefix);
43
43
 
@@ -99,6 +99,25 @@ static void relink_namespace(xmlNodePtr reparented)
99
99
  }
100
100
  }
101
101
 
102
+ /*
103
+ * Search our parents for an existing definition of current namespace,
104
+ * because the definition it's pointing to may have just been removed nsDef.
105
+ *
106
+ * And although that would technically probably be OK, I'd feel better if we
107
+ * referred to a namespace that's still present in a node's nsDef somewhere
108
+ * in the doc.
109
+ */
110
+ if (reparented->ns) {
111
+ xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix);
112
+ if (ns
113
+ && ns != reparented->ns
114
+ && xmlStrEqual(ns->prefix, reparented->ns->prefix)
115
+ && xmlStrEqual(ns->href, reparented->ns->href)
116
+ ) {
117
+ xmlSetNs(reparented, ns);
118
+ }
119
+ }
120
+
102
121
  /* Only walk all children if there actually is a namespace we need to */
103
122
  /* reparent. */
104
123
  if (NULL == reparented->ns) { return; }
@@ -282,7 +301,11 @@ ok:
282
301
  }
283
302
 
284
303
  if (original_ns_prefix_is_default && reparentee->ns != NULL && reparentee->ns->prefix != NULL) {
285
- /* issue #391, where new node's prefix may become the string "default" */
304
+ /*
305
+ * issue #391, where new node's prefix may become the string "default"
306
+ * see libxml2 tree.c xmlNewReconciliedNs which implements this behavior.
307
+ */
308
+ xmlFree(reparentee->ns->prefix);
286
309
  reparentee->ns->prefix = NULL;
287
310
  }
288
311
  }
@@ -509,22 +532,39 @@ static VALUE internal_subset(VALUE self)
509
532
  /*
510
533
  * call-seq:
511
534
  * dup
535
+ * dup(depth)
536
+ * dup(depth, new_parent_doc)
512
537
  *
513
- * Copy this node. An optional depth may be passed in, but it defaults
514
- * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
538
+ * Copy this node.
539
+ * An optional depth may be passed in. 0 is a shallow copy, 1 (the default) is a deep copy.
540
+ * An optional new_parent_doc may also be passed in, which will be the new
541
+ * node's parent document. Defaults to the current node's document.
542
+ * current document.
515
543
  */
516
544
  static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
517
545
  {
518
- VALUE level;
546
+ VALUE r_level, r_new_parent_doc;
547
+ int level;
548
+ int n_args;
549
+ xmlDocPtr new_parent_doc;
519
550
  xmlNodePtr node, dup;
520
551
 
521
- if(rb_scan_args(argc, argv, "01", &level) == 0) {
522
- level = INT2NUM((long)1);
552
+ Data_Get_Struct(self, xmlNode, node);
553
+
554
+ n_args = rb_scan_args(argc, argv, "02", &r_level, &r_new_parent_doc);
555
+
556
+ if (n_args < 1) {
557
+ r_level = INT2NUM((long)1);
523
558
  }
559
+ level = (int)NUM2INT(r_level);
524
560
 
525
- Data_Get_Struct(self, xmlNode, node);
561
+ if (n_args < 2) {
562
+ new_parent_doc = node->doc;
563
+ } else {
564
+ Data_Get_Struct(r_new_parent_doc, xmlDoc, new_parent_doc);
565
+ }
526
566
 
527
- dup = xmlDocCopyNode(node, node->doc, (int)NUM2INT(level));
567
+ dup = xmlDocCopyNode(node, new_parent_doc, level);
528
568
  if(dup == NULL) { return Qnil; }
529
569
 
530
570
  nokogiri_root_node(dup);
@@ -1308,11 +1348,11 @@ static VALUE line(VALUE self)
1308
1348
  */
1309
1349
  static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
1310
1350
  {
1311
- xmlNodePtr node, namespacee;
1351
+ xmlNodePtr node, namespace;
1312
1352
  xmlNsPtr ns;
1313
1353
 
1314
1354
  Data_Get_Struct(self, xmlNode, node);
1315
- namespacee = node ;
1355
+ namespace = node ;
1316
1356
 
1317
1357
  ns = xmlSearchNs(
1318
1358
  node->doc,
@@ -1322,10 +1362,10 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
1322
1362
 
1323
1363
  if(!ns) {
1324
1364
  if (node->type != XML_ELEMENT_NODE) {
1325
- namespacee = node->parent;
1365
+ namespace = node->parent;
1326
1366
  }
1327
1367
  ns = xmlNewNs(
1328
- namespacee,
1368
+ namespace,
1329
1369
  (const xmlChar *)StringValueCStr(href),
1330
1370
  (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix))
1331
1371
  );
@@ -1333,7 +1373,7 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
1333
1373
 
1334
1374
  if (!ns) { return Qnil ; }
1335
1375
 
1336
- if(NIL_P(prefix) || node != namespacee) { xmlSetNs(node, ns); }
1376
+ if(NIL_P(prefix) || node != namespace) { xmlSetNs(node, ns); }
1337
1377
 
1338
1378
  return Nokogiri_wrap_xml_namespace(node->doc, ns);
1339
1379
  }
@@ -1,6 +1,6 @@
1
1
  module Nokogiri
2
2
  # The version of Nokogiri you are using
3
- VERSION = '1.8.5'
3
+ VERSION = '1.9.0.rc1'
4
4
 
5
5
  class VersionInfo # :nodoc:
6
6
  def jruby?
@@ -25,6 +25,17 @@ module Nokogiri
25
25
  children.each { |child| child.parent = self }
26
26
  end
27
27
 
28
+ if Nokogiri.uses_libxml?
29
+ def dup
30
+ new_document = document.dup
31
+ new_fragment = XML::DocumentFragment.new(new_document)
32
+ children.each do |child|
33
+ child.dup(1, new_document).parent = new_fragment
34
+ end
35
+ new_fragment
36
+ end
37
+ end
38
+
28
39
  ###
29
40
  # return the name for DocumentFragment
30
41
  def name
@@ -161,6 +161,18 @@ module Nokogiri
161
161
  end
162
162
  end
163
163
 
164
+
165
+ ###
166
+ # Add html around this node
167
+ #
168
+ # Returns self
169
+ def wrap(html)
170
+ new_parent = document.parse(html).first
171
+ add_next_sibling(new_parent)
172
+ new_parent.add_child(self)
173
+ self
174
+ end
175
+
164
176
  ###
165
177
  # Add +node_or_tags+ as a child of this Node.
166
178
  # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
@@ -203,6 +203,7 @@ module Nokogiri
203
203
  0.upto(length - 1) do |x|
204
204
  yield self[x]
205
205
  end
206
+ self
206
207
  end
207
208
 
208
209
  ###
@@ -230,14 +231,9 @@ module Nokogiri
230
231
  end
231
232
 
232
233
  ###
233
- # Wrap this NodeSet with +html+ or the results of the builder in +blk+
234
- def wrap(html, &blk)
235
- each do |j|
236
- new_parent = document.parse(html).first
237
- j.add_next_sibling(new_parent)
238
- new_parent.add_child(j)
239
- end
240
- self
234
+ # Wrap this NodeSet with +html+
235
+ def wrap html
236
+ map { |node| node.wrap html }
241
237
  end
242
238
 
243
239
  ###
data/test/helper.rb CHANGED
@@ -213,7 +213,7 @@ module Nokogiri
213
213
  .each do |name|
214
214
  define_method name do |*arguments|
215
215
  @items << [name, *arguments]
216
- super *arguments
216
+ super(*arguments)
217
217
  end
218
218
  end
219
219
 
@@ -707,6 +707,16 @@ eohtml
707
707
  assert_equal 'ISO-8859-1', html.encoding.name
708
708
  end
709
709
 
710
+ def test_leaking_dtd_nodes_after_internal_subset_removal
711
+ # see https://github.com/sparklemotion/nokogiri/issues/1784
712
+ #
713
+ # just checking that this doesn't raise a valgrind error. we
714
+ # don't otherwise have any test coverage for removing DTDs.
715
+ #
716
+ 100.times do |i|
717
+ Nokogiri::HTML::Document.new.internal_subset.remove
718
+ end
719
+ end
710
720
  end
711
721
  end
712
722
  end
@@ -13,6 +13,22 @@ class TestMemoryLeak < Nokogiri::TestCase
13
13
  EOF
14
14
  end
15
15
 
16
+ #
17
+ # this suite is turned off unless the env var NOKOGIRI_GC is non-nil
18
+ #
19
+ # to run any of these tests, do something like this on the commandline:
20
+ #
21
+ # $ NOKOGIRI_GC=t ruby -Ilib:test \
22
+ # test/test_memory_leak.rb \
23
+ # -n /test_leaking_namespace_node_strings/
24
+ #
25
+ # also see:
26
+ #
27
+ # https://github.com/sparklemotion/nokogiri/issues/1603
28
+ #
29
+ # which is an open issue to resurrect these tests and run them as
30
+ # part of the CI pipeline.
31
+ #
16
32
  if ENV['NOKOGIRI_GC'] # turning these off by default for now
17
33
  def test_dont_hurt_em_why
18
34
  content = File.open("#{File.dirname(__FILE__)}/files/dont_hurt_em_why.xml").read
@@ -126,7 +142,7 @@ EOF
126
142
  end
127
143
 
128
144
  def test_in_context_parser_leak
129
- loop do
145
+ loop do
130
146
  doc = Nokogiri::XML::Document.new
131
147
  fragment1 = Nokogiri::XML::DocumentFragment.new(doc, '<foo/>')
132
148
  node = fragment1.children[0]
@@ -144,8 +160,62 @@ EOF
144
160
  doc.xpath('name(//node())')
145
161
  end
146
162
  end
163
+
164
+ def test_leaking_namespace_node_strings
165
+ # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report
166
+ ns = {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'}
167
+ 20.times do
168
+ 10_000.times do
169
+ Nokogiri::XML::Builder.new do |xml|
170
+ xml.send 'Envelope', ns do
171
+ xml.send 'Foobar', ns
172
+ end
173
+ end
174
+ end
175
+ puts MemInfo.rss
176
+ end
177
+ end
178
+
179
+ def test_leaking_namespace_node_strings_with_prefix
180
+ # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report
181
+ ns = {'xmlns:foo' => 'http://schemas.xmlsoap.org/soap/envelope/'}
182
+ 20.times do
183
+ 10_000.times do
184
+ Nokogiri::XML::Builder.new do |xml|
185
+ xml.send 'Envelope', ns do
186
+ xml.send 'Foobar', ns
187
+ end
188
+ end
189
+ end
190
+ puts MemInfo.rss
191
+ end
192
+ end
193
+
194
+ def test_leaking_dtd_nodes_after_internal_subset_removal
195
+ # see https://github.com/sparklemotion/nokogiri/issues/1784
196
+ 100_000.times do |i|
197
+ doc = Nokogiri::HTML::Document.new
198
+ doc.internal_subset.remove
199
+ puts MemInfo.rss if (i % 1000 == 0)
200
+ end
201
+ end
147
202
  end # if NOKOGIRI_GC
148
203
 
204
+ module MemInfo
205
+ # from https://stackoverflow.com/questions/7220896/get-current-ruby-process-memory-usage
206
+ # this is only going to work on linux
207
+ PAGE_SIZE = `getconf PAGESIZE`.chomp.to_i rescue 4096
208
+ STATM_PATH = "/proc/#{Process.pid}/statm"
209
+ STATM_FOUND = File.exist?(STATM_PATH)
210
+
211
+ def self.rss
212
+ if STATM_FOUND
213
+ return (File.read(STATM_PATH).split(' ')[1].to_i * PAGE_SIZE) / 1024
214
+ end
215
+ return 0
216
+ end
217
+ end
218
+
149
219
  private
150
220
 
151
221
  def count_object_space_documents
@@ -26,12 +26,34 @@ module Nokogiri
26
26
  assert_equal "Y&ent1;", street.value
27
27
  end
28
28
 
29
- def test_value=
29
+ def test_set_value
30
30
  xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
31
31
  address = xml.xpath('//address')[3]
32
32
  street = address.attributes['street']
33
33
  street.value = "Y&ent1;"
34
34
  assert_equal "Y&ent1;", street.value
35
+ assert_includes %Q{ street="Y&amp;ent1;"}, street.to_xml
36
+ end
37
+
38
+ def test_set_value_with_entity_string_in_html_file
39
+ html = Nokogiri::HTML("<html><body><div foo='asdf'>")
40
+ foo = html.at_css("div").attributes["foo"]
41
+ foo.value = "Y&ent1;"
42
+ assert_includes %Q{ foo="Y&amp;ent1;"}, foo.to_html
43
+ end
44
+
45
+ def test_set_value_with_blank_string_in_html_file
46
+ html = Nokogiri::HTML("<html><body><div foo='asdf'>")
47
+ foo = html.at_css("div").attributes["foo"]
48
+ foo.value = ""
49
+ assert_includes %Q{ foo=""}, foo.to_html
50
+ end
51
+
52
+ def test_set_value_of_boolean_attr_with_nil_in_html_file
53
+ html = Nokogiri::HTML("<html><body><div disabled='asdf'>")
54
+ disabled = html.at_css("div").attributes["disabled"]
55
+ disabled.value = nil
56
+ assert_includes %Q{ disabled}, disabled.to_html
35
57
  end
36
58
 
37
59
  def test_unlink # aliased as :remove
@@ -331,6 +331,18 @@ module Nokogiri
331
331
  assert_nil doc.at_xpath("//*[local-name() = 'products']").namespace
332
332
  end
333
333
 
334
+ def test_builder_reuses_namespaces
335
+ # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report
336
+ builder = Nokogiri::XML::Builder.new
337
+ builder.send "envelope", {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'} do
338
+ builder.send "package", {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'}
339
+ end
340
+ envelope = builder.doc.at_css("envelope")
341
+ package = builder.doc.at_css("package")
342
+ assert_equal envelope.namespace, package.namespace
343
+ assert_equal envelope.namespace.object_id, package.namespace.object_id
344
+ end
345
+
334
346
  private
335
347
 
336
348
  def namespaces_defined_on(node)
@@ -263,6 +263,20 @@ EOS
263
263
  Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised
264
264
  end
265
265
 
266
+ def test_dup_creates_tree_with_identical_structure
267
+ original = Nokogiri::XML::DocumentFragment.parse("<div><p>hello</p></div>")
268
+ duplicate = original.dup
269
+ assert_equal original.to_html, duplicate.to_html
270
+ end
271
+
272
+ def test_dup_creates_mutable_tree
273
+ original = Nokogiri::XML::DocumentFragment.parse("<div><p>hello</p></div>")
274
+ duplicate = original.dup
275
+ duplicate.at_css("div").add_child("<b>hello there</b>")
276
+ assert_nil original.at_css("b")
277
+ assert_not_nil duplicate.at_css("b")
278
+ end
279
+
266
280
  if Nokogiri.uses_libxml?
267
281
  def test_for_libxml_in_context_fragment_parsing_bug_workaround
268
282
  10.times do
@@ -165,6 +165,44 @@ module Nokogiri
165
165
  assert_equal x.first.name, "span"
166
166
  end
167
167
 
168
+ def test_dup_is_deep_copy_by_default
169
+ doc = XML::Document.parse "<root><div><p>hello</p></div></root>"
170
+ div = doc.at_css "div"
171
+ node = div.dup
172
+ assert_equal 1, node.children.length
173
+ assert_equal "<p>hello</p>", node.children.first.to_html
174
+ end
175
+
176
+ def test_dup_deep_copy
177
+ doc = XML::Document.parse "<root><div><p>hello</p></div></root>"
178
+ div = doc.at_css "div"
179
+ node = div.dup(1)
180
+ assert_equal 1, node.children.length
181
+ assert_equal "<p>hello</p>", node.children.first.to_html
182
+ end
183
+
184
+ def test_dup_shallow_copy
185
+ doc = XML::Document.parse "<root><div><p>hello</p></div></root>"
186
+ div = doc.at_css "div"
187
+ node = div.dup(0)
188
+ assert_equal 0, node.children.length
189
+ end
190
+
191
+ if Nokogiri.uses_libxml?
192
+ def test_dup_to_another_document
193
+ doc1 = HTML::Document.parse "<root><div><p>hello</p></div></root>"
194
+ doc2 = HTML::Document.parse "<div></div>"
195
+
196
+ div = doc1.at_css "div"
197
+ duplicate_div = div.dup(1, doc2)
198
+
199
+ assert_not_nil doc1.at_css("div")
200
+ assert_equal doc2, duplicate_div.document
201
+ assert_equal 1, duplicate_div.children.length
202
+ assert_equal "<p>hello</p>", duplicate_div.children.first.to_html
203
+ end
204
+ end
205
+
168
206
  def test_subclass_dup
169
207
  subclass = Class.new(Nokogiri::XML::Node)
170
208
  node = subclass.new('foo', @xml).dup
@@ -415,12 +453,19 @@ module Nokogiri
415
453
  assert_equal ns, ns2
416
454
  end
417
455
 
418
- def test_add_default_ns
456
+ def test_add_default_namespace
419
457
  node = @xml.at('address')
420
458
  node.add_namespace(nil, 'http://tenderlovemaking.com')
421
459
  assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
422
460
  end
423
461
 
462
+ def test_add_default_namespace_twice
463
+ node = @xml.at('address')
464
+ ns = node.add_namespace(nil, 'http://tenderlovemaking.com')
465
+ ns2 = node.add_namespace(nil, 'http://tenderlovemaking.com')
466
+ assert_equal ns.object_id, ns2.object_id
467
+ end
468
+
424
469
  def test_add_multiple_namespaces
425
470
  node = @xml.at('address')
426
471
 
@@ -1320,6 +1365,15 @@ eoxml
1320
1365
  node.add_next_sibling(Nokogiri::XML::Text.new('after', node.document))
1321
1366
  end
1322
1367
  end
1368
+
1369
+ def test_wrap
1370
+ xml = '<root><thing><div class="title">important thing</div></thing></root>'
1371
+ doc = Nokogiri::XML(xml)
1372
+ thing = doc.at_css("thing")
1373
+ thing.wrap("<wrapper/>")
1374
+ assert_equal 'wrapper', thing.parent.name
1375
+ assert_equal 'thing', doc.at_css("wrapper").children.first.name
1376
+ end
1323
1377
  end
1324
1378
  end
1325
1379
  end
@@ -204,7 +204,7 @@ module Nokogiri
204
204
  node = doc1.at_xpath("//value")
205
205
  node.remove
206
206
  doc2.add_child(node)
207
- assert_match /<value>3<\/value>/, doc2.to_xml
207
+ assert_match(/<value>3<\/value>/, doc2.to_xml)
208
208
  end
209
209
  end
210
210
 
@@ -224,6 +224,59 @@ module Nokogiri
224
224
  node.add_child(child)
225
225
  assert @doc.at('//xmlns:second')
226
226
  end
227
+
228
+ describe "and a child node was added to a new doc with the a different namespace using the same prefix" do
229
+ before do
230
+ @doc = Nokogiri::XML %Q{<root xmlns:bar="http://tenderlovemaking.com/"><bar:first/></root>}
231
+ new_doc = Nokogiri::XML %Q{<newroot xmlns:bar="http://flavorjon.es/"/>}
232
+ assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
233
+ new_doc.root.add_child node
234
+ @doc = new_doc
235
+ end
236
+
237
+ it "serializes the doc with the proper default namespace" do
238
+ assert_match(/<bar:first\ xmlns:bar="http:\/\/tenderlovemaking.com\/"\/>/, @doc.to_xml)
239
+ end
240
+ end
241
+
242
+ describe "and a child node was added to a new doc with the same default namespaces" do
243
+ before do
244
+ new_doc = Nokogiri::XML %Q{<newroot xmlns="http://tenderlovemaking.com/"/>}
245
+ assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
246
+ new_doc.root.add_child node
247
+ @doc = new_doc
248
+ end
249
+
250
+ it "serializes the doc with the proper default namespace" do
251
+ assert_match(/<first>/, @doc.to_xml)
252
+ end
253
+ end
254
+
255
+ describe "and a child node was added to a new doc without any default namespaces" do
256
+ before do
257
+ new_doc = Nokogiri::XML "<newroot/>"
258
+ assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
259
+ new_doc.root.add_child node
260
+ @doc = new_doc
261
+ end
262
+
263
+ it "serializes the doc with the proper default namespace" do
264
+ assert_match(/<first xmlns=\"http:\/\/tenderlovemaking.com\/\">/, @doc.to_xml)
265
+ end
266
+ end
267
+
268
+ describe "and a child node became the root of a new doc" do
269
+ before do
270
+ new_doc = Nokogiri::XML::Document.new
271
+ assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
272
+ new_doc.root = node
273
+ @doc = new_doc
274
+ end
275
+
276
+ it "serializes the doc with the proper default namespace" do
277
+ assert_match(/<first xmlns=\"http:\/\/tenderlovemaking.com\/\">/, @doc.to_xml)
278
+ end
279
+ end
227
280
  end
228
281
 
229
282
  describe "given a parent node with a default and non-default namespace" do
@@ -249,7 +302,7 @@ module Nokogiri
249
302
  @node.add_child(@child)
250
303
  assert reparented = @doc.at('//bar:second', "bar" => "http://tenderlovemaking.com/")
251
304
  assert reparented.namespace_definitions.empty?
252
- assert_equal @ns, reparented.namespace
305
+ assert_equal @doc.root.namespace, reparented.namespace
253
306
  assert_equal(
254
307
  {
255
308
  "xmlns" => "http://tenderlovemaking.com/",
@@ -282,17 +335,20 @@ module Nokogiri
282
335
  end
283
336
 
284
337
  describe "and a child with a namespace matching the parent's non-default namespace" do
338
+ before do
339
+ @root_ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
340
+ end
341
+
285
342
  describe "set by #namespace=" do
286
343
  before do
287
- @ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
288
- @child.namespace = @ns
344
+ @child.namespace = @root_ns
289
345
  end
290
346
 
291
347
  it "inserts a node that inherits the matching parent namespace" do
292
348
  @node.add_child(@child)
293
349
  assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
294
350
  assert reparented.namespace_definitions.empty?
295
- assert_equal @ns, reparented.namespace
351
+ assert_equal @root_ns, reparented.namespace
296
352
  assert_equal(
297
353
  {
298
354
  "xmlns" => "http://tenderlovemaking.com/",
@@ -312,7 +368,7 @@ module Nokogiri
312
368
  @node.add_child(@child)
313
369
  assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
314
370
  assert reparented.namespace_definitions.empty?
315
- assert_equal @ns, reparented.namespace
371
+ assert_equal @root_ns, reparented.namespace
316
372
  assert_equal(
317
373
  {
318
374
  "xmlns" => "http://tenderlovemaking.com/",
@@ -550,6 +606,19 @@ module Nokogiri
550
606
  end
551
607
  end
552
608
 
609
+ describe "reparenting and preserving a reference to the original ns" do
610
+ it "should not cause illegal memory access" do
611
+ # this test will only cause a failure in valgrind. it
612
+ # drives out the reason why we can't call xmlFreeNs in
613
+ # relink_namespace and instead have to root the nsdef.
614
+ doc = Nokogiri::XML '<root xmlns="http://flavorjon.es/"><envelope /></root>'
615
+ elem = doc.create_element "package", {"xmlns" => "http://flavorjon.es/"}
616
+ ns = elem.namespace_definitions
617
+ doc.at_css("envelope").add_child elem
618
+ ns.inspect
619
+ end
620
+ end
621
+
553
622
  describe "reparenting into another document" do
554
623
  it "correctly sets default namespace of a reparented node" do
555
624
  # issue described in #391
@@ -511,6 +511,19 @@ module Nokogiri
511
511
  assert_equal 'employee', @xml.search("//wrapper").first.children[0].name
512
512
  end
513
513
 
514
+ def test_wrap_various_node_types
515
+ xml = '<root><foo>contents</foo></root>'
516
+ doc = Nokogiri::XML xml
517
+ nodes = doc.at_css("root").xpath(".//* | .//*/text()") # foo and "contents"
518
+ nodes.wrap("<wrapper/>")
519
+ wrappers = doc.css("wrapper")
520
+ assert_equal "root", wrappers.first.parent.name
521
+ assert_equal "foo", wrappers.first.children.first.name
522
+ assert_equal "foo", wrappers.last.parent.name
523
+ assert wrappers.last.children.first.text?
524
+ assert_equal "contents", wrappers.last.children.first.text
525
+ end
526
+
514
527
  def test_wrap_a_fragment
515
528
  frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML
516
529
  <employees>
@@ -804,6 +817,12 @@ module Nokogiri
804
817
  assert_equal node_set.document, new_set.document
805
818
  assert new_set.respond_to?(:awesome!)
806
819
  end
820
+
821
+ def test_each_should_return_self
822
+ node_set1 = @xml.css("address")
823
+ node_set2 = node_set1.each {}
824
+ assert_equal node_set1, node_set2
825
+ end
807
826
  end
808
827
  end
809
828
  end
@@ -55,6 +55,15 @@ module Nokogiri
55
55
  node << Text.new('bar', Document.new)
56
56
  }
57
57
  end
58
+
59
+ def test_wrap
60
+ xml = '<root><thing><div class="title">important thing</div></thing></root>'
61
+ doc = Nokogiri::XML(xml)
62
+ text = doc.at_css("div").children.first
63
+ text.wrap("<wrapper/>")
64
+ assert_equal 'wrapper', text.parent.name
65
+ assert_equal 'wrapper', doc.at_css("div").children.first.name
66
+ end
58
67
  end
59
68
  end
60
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nokogiri
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.5
4
+ version: 1.9.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2018-10-05 00:00:00.000000000 Z
17
+ date: 2018-12-10 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: mini_portile2
@@ -22,14 +22,14 @@ dependencies:
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 2.3.0
25
+ version: 2.4.0
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 2.3.0
32
+ version: 2.4.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: hoe-bundler
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '1.4'
53
+ version: '2.0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '1.4'
60
+ version: '2.0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: hoe-gemspec
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -188,30 +188,36 @@ dependencies:
188
188
  name: rdoc
189
189
  requirement: !ruby/object:Gem::Requirement
190
190
  requirements:
191
- - - "~>"
191
+ - - ">="
192
192
  - !ruby/object:Gem::Version
193
193
  version: '4.0'
194
+ - - "<"
195
+ - !ruby/object:Gem::Version
196
+ version: '7'
194
197
  type: :development
195
198
  prerelease: false
196
199
  version_requirements: !ruby/object:Gem::Requirement
197
200
  requirements:
198
- - - "~>"
201
+ - - ">="
199
202
  - !ruby/object:Gem::Version
200
203
  version: '4.0'
204
+ - - "<"
205
+ - !ruby/object:Gem::Version
206
+ version: '7'
201
207
  - !ruby/object:Gem::Dependency
202
208
  name: hoe
203
209
  requirement: !ruby/object:Gem::Requirement
204
210
  requirements:
205
211
  - - "~>"
206
212
  - !ruby/object:Gem::Version
207
- version: '3.16'
213
+ version: '3.17'
208
214
  type: :development
209
215
  prerelease: false
210
216
  version_requirements: !ruby/object:Gem::Requirement
211
217
  requirements:
212
218
  - - "~>"
213
219
  - !ruby/object:Gem::Version
214
- version: '3.16'
220
+ version: '3.17'
215
221
  description: |-
216
222
  Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser. Among
217
223
  Nokogiri's many features is the ability to search documents via XPath
@@ -569,12 +575,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
569
575
  version: 2.1.0
570
576
  required_rubygems_version: !ruby/object:Gem::Requirement
571
577
  requirements:
572
- - - ">="
578
+ - - ">"
573
579
  - !ruby/object:Gem::Version
574
- version: '0'
580
+ version: 1.3.1
575
581
  requirements: []
576
582
  rubyforge_project:
577
- rubygems_version: 2.7.7
583
+ rubygems_version: 2.7.8
578
584
  signing_key:
579
585
  specification_version: 4
580
586
  summary: Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser