From 076a7414e799ac3d2bacd0c78c6ca6f7a8a6265e Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Wed, 20 Sep 2017 11:30:18 +0200 Subject: [PATCH 001/176] Use UTF-8 as default encoding for Node#serialize Node#serialize used to return UTF-8 if no encoding was given. However this got broken in commit 53f9b66ee6. Since UTF-8 is the default in XML and HTML5 specs, it makes sense to use UTF-8 in serialize as well and enforce this in the tests. Fixes #1659 --- lib/nokogiri/xml/node.rb | 4 +--- test/html/test_node_encoding.rb | 6 ++++++ test/xml/test_node_encoding.rb | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/nokogiri/xml/node.rb b/lib/nokogiri/xml/node.rb index 7a8d1caafd..efb0285170 100644 --- a/lib/nokogiri/xml/node.rb +++ b/lib/nokogiri/xml/node.rb @@ -624,9 +624,7 @@ def serialize *args, &block options[:encoding] = encoding outstring = String.new - if encoding && outstring.respond_to?(:force_encoding) - outstring.force_encoding(Encoding.find(encoding)) - end + outstring.force_encoding(Encoding.find(encoding || 'utf-8')) io = StringIO.new(outstring) write_to io, options, &block io.string diff --git a/test/html/test_node_encoding.rb b/test/html/test_node_encoding.rb index 890747e82b..7490a29174 100644 --- a/test/html/test_node_encoding.rb +++ b/test/html/test_node_encoding.rb @@ -26,6 +26,12 @@ def test_serialize_encoding_html assert_equal @html.serialize, @doc.serialize end + def test_default_encoding + doc = Nokogiri::HTML(nil) + assert_nil doc.encoding + assert_equal 'UTF-8', doc.serialize.encoding.name + end + def test_encode_special_chars foo = @html.css('a').first.encode_special_chars('foo') assert_equal 'UTF-8', foo.encoding.name diff --git a/test/xml/test_node_encoding.rb b/test/xml/test_node_encoding.rb index 3a85d5587c..03a5d2e859 100644 --- a/test/xml/test_node_encoding.rb +++ b/test/xml/test_node_encoding.rb @@ -13,6 +13,12 @@ def test_serialize_encoding_xml assert_equal @xml.serialize, @doc.serialize end + def test_default_encoding + doc = Nokogiri::XML(VEHICLE_XML) + assert_nil doc.encoding + assert_equal 'UTF-8', doc.serialize.encoding.name + end + def test_encoding_GH_1113 utf8 = 'shahid ὡ 𐄣 𢂁' hex = 'shahid ὡ 𐄣 𢂁' From 6bbc9d7e51eac5f5c0429cf740629300c547d832 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 24 Sep 2017 23:29:06 -0400 Subject: [PATCH 002/176] concourse: libxmlruby jobs repositioned ... until after the system job runs for that ruby --- concourse/nokogiri.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index b56af28ea0..4713d14d44 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -131,6 +131,7 @@ jobs: - get: ci - get: nokogiri trigger: true + passed: ["ruby-<%= ruby_version %>-system"] - task: rake-test config: platform: linux @@ -152,7 +153,7 @@ jobs: - get: ci - get: nokogiri trigger: true - passed: [ruby-libxmlruby-system] + passed: ["ruby-<%= ruby_version %>-system"] - task: rake-test config: platform: linux From 7afdf124a8ed27bc94a19dabc896f15b8a62b853 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 24 Sep 2017 23:33:09 -0400 Subject: [PATCH 003/176] concourse: windows 2.4 build using concourse-gem's windows ruby awareness [skip ci] --- Gemfile | 2 +- Rakefile | 2 +- concourse/nokogiri.yml | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index fa3c4f753e..11c67e7bb6 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ gem "rake-compiler", "~>1.0.3", :group => [:development, :test] gem "rake-compiler-dock", "~>0.6.0", :group => [:development, :test] gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] -gem "concourse", "~>0.11", :group => [:development, :test] +gem "concourse", "~>0.15", :group => [:development, :test] gem "rdoc", "~>4.0", :group => [:development, :test] gem "hoe", "~>3.16", :group => [:development, :test] diff --git a/Rakefile b/Rakefile index fcb8a1addf..60a6dc3b6a 100644 --- a/Rakefile +++ b/Rakefile @@ -140,7 +140,7 @@ HOE = Hoe.spec 'nokogiri' do ["rake-compiler-dock", "~> 0.6.0"], ["racc", "~> 1.4.14"], ["rexical", "~> 1.0.5"], - ["concourse", "~> 0.11"], + ["concourse", "~> 0.15"], ] if java? diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 4713d14d44..478a25e0e2 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -18,7 +18,10 @@ groups: - "rbx-<%= rbx_version %>-system" - "rbx-<%= rbx_version %>-vendored" <% end %> - - win-ruby-2.3-devkit + <% for ruby_version in RUBIES[:windows] %> + - "win-ruby-<%= ruby_version %>-devkit" + <% end %> + - name: PRs jobs: @@ -257,21 +260,26 @@ jobs: path: ci/concourse/tasks/rake-test/run.sh <% end %> - - name: win-ruby-2.3-devkit + <% for ruby_version in RUBIES[:windows] %> + - name: win-ruby-<%= ruby_version %>-devkit public: true plan: - get: ci - get: nokogiri trigger: true + passed: ["ruby-<%= ruby_version %>-system"] - task: rake-test config: platform: windows inputs: - name: ci - name: nokogiri + params: + WIN_RUBY_VERSION: "<%= ruby_version %>" run: path: powershell args: ["-File", "ci/concourse/tasks/rake-test/run.ps1"] + <% end %> # # PRs From ac7060c7565c3ddedee9e875672e5fdd05d841c4 Mon Sep 17 00:00:00 2001 From: Andrew Aladjev Date: Thu, 28 Sep 2017 23:43:02 +0300 Subject: [PATCH 004/176] replaced character stack with string buffer, fixed characters population mechanism --- .../nokogiri/internals/NokogiriHandler.java | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 0b0c482dfb..2dfabed2e8 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -17,10 +17,10 @@ * 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: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -38,7 +38,6 @@ import static nokogiri.internals.NokogiriHelpers.stringOrNil; import java.util.LinkedList; -import java.util.Stack; import nokogiri.XmlSyntaxError; @@ -57,12 +56,12 @@ /** * A handler for SAX parsing. - * + * * @author sergio * @author Yoko Harada */ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { - Stack characterStack; + StringBuffer charactersBuffer; private final Ruby ruby; private final RubyClass attrClass; private final IRubyObject object; @@ -100,7 +99,7 @@ public void setDocumentLocator(Locator locator) { @Override public void startDocument() throws SAXException { call("start_document"); - characterStack = new Stack(); + charactersBuffer = new StringBuffer(); } @Override @@ -112,13 +111,7 @@ public void xmlDecl(String version, String encoding, String standalone) { @Override public void endDocument() throws SAXException { - StringBuffer sb; - if (!characterStack.empty()) { - for (int i=0; i 0) { + call("characters", ruby.newString(charactersBuffer.toString())); + charactersBuffer.setLength(0); + } + } } From 91d8e3e0fd7f310414f402b44771c1d0185dfb3f Mon Sep 17 00:00:00 2001 From: Andrew Aladjev Date: Thu, 28 Sep 2017 23:45:46 +0300 Subject: [PATCH 005/176] added helper document that can test a strict order of items produced by parsers --- test/helper.rb | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/helper.rb b/test/helper.rb index 2a58127b12..649279f4c7 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -186,6 +186,86 @@ def processing_instruction name, content @processing_instructions << [name, content] end end + + # This document will help us to test the strict order of items. + + class DocWithOrderedItems < XML::SAX::Document + attr_reader :items + + def initialize + # [ + # [ :method_1, argument_1, ... ], + # [ :method_2, argument_2, ... ], + # ... + # ] + @items = Items.new + end + + %i[ + xmldecl + start_document end_document + start_element end_element + start_element_namespace end_element_namespace + characters comment cdata_block + processing_instruction + error warning + ] + .each do |name| + define_method name do |*arguments| + @items << [name, *arguments] + super *arguments + end + end + + class Items < Array + def get_root_content root_name + items = clone + is_inside_root = false + + items.select! do |item| + method_name = item[0] + element_name = item[1] + + case method_name + when :start_element, :start_element_namespace + if element_name == root_name + is_inside_root = true + next false + end + + when :end_element, :end_element_namespace + is_inside_root = false if element_name == root_name and is_inside_root + end + + is_inside_root + end + + items + end + + def select_methods(names) + items = clone + + items.select! do |item| + name = item[0] + names.include? name + end + + items + end + + def strip_text! method_names + each do |item| + method_name = item[0] + text = item[1] + + text.strip! if method_names.include? method_name + end + + nil + end + end + end end end end From 41c6faff8ac575bd370eaf831df49a90908f6b6c Mon Sep 17 00:00:00 2001 From: Andrew Aladjev Date: Thu, 28 Sep 2017 23:50:14 +0300 Subject: [PATCH 006/176] added tests for html and xml sax parsers that will verify the order of parsed text items --- Manifest.txt | 2 + test/html/sax/test_parser_text.rb | 163 ++++++++++++++++++++++++ test/xml/sax/test_parser_text.rb | 202 ++++++++++++++++++++++++++++++ 3 files changed, 367 insertions(+) create mode 100644 test/html/sax/test_parser_text.rb create mode 100644 test/xml/sax/test_parser_text.rb diff --git a/Manifest.txt b/Manifest.txt index 6af78741fd..f5483fcfb9 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -298,6 +298,7 @@ test/helper.rb test/html/sax/test_parser.rb test/html/sax/test_parser_context.rb test/html/sax/test_push_parser.rb +test/html/sax/test_parser_text.rb test/html/test_builder.rb test/html/test_document.rb test/html/test_document_encoding.rb @@ -325,6 +326,7 @@ test/xml/node/test_subclass.rb test/xml/sax/test_parser.rb test/xml/sax/test_parser_context.rb test/xml/sax/test_push_parser.rb +test/xml/sax/test_parser_text.rb test/xml/test_attr.rb test/xml/test_attribute_decl.rb test/xml/test_builder.rb diff --git a/test/html/sax/test_parser_text.rb b/test/html/sax/test_parser_text.rb new file mode 100644 index 0000000000..f670c5fb0b --- /dev/null +++ b/test/html/sax/test_parser_text.rb @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- +require "helper" + +module Nokogiri + module HTML + module SAX + class TestParserText < Nokogiri::SAX::TestCase + def setup + super + @doc = DocWithOrderedItems.new + @parser = HTML::SAX::Parser.new @doc + end + + def test_texts_order + html = <<-eohtml + + + + + text 0 +

+ text 1 + text 2 + text 3 +

+ + text 4 + + +

+ + + +

+ + + + + eohtml + + @parser.parse html + items = @doc.items.get_root_content "body" + items = items.select_methods %i[ + start_element end_element + characters comment + ] + items.strip_text! %i[characters comment] + + assert_equal [ + [:characters, 'text 0'], + + [:start_element, 'p', []], + [:characters, 'text 1'], + + [:start_element, 'span', []], + [:characters, 'text 2'], + [:end_element, 'span'], + + [:characters, 'text 3'], + [:end_element, 'p'], + + [:characters, 'text 4'], + [:comment, 'text 5'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + [:comment, 'text 6'], + [:characters, ''], + + [:start_element, 'span', []], + [:comment, 'text 7'], + [:end_element, 'span'], + [:characters, ''], + + [:comment, 'text 8'], + [:characters, ''], + [:end_element, 'p'], + [:characters, ''], + + [:comment, 'text 9'], + [:characters, ''] + ], items + + nil + end + + def text_whitespace + html = <<-eohtml + + + + +

+ + + + + +

+

+ + + +

+ + + eohtml + + @parser.parse html + items = @doc.items.get_root_content "body" + items = items.select_methods %i[ + start_element end_element + characters comment + ] + items.strip_text! %i[characters comment] + + assert_equal [ + [:characters, ''], + [:start_element, 'p', []], + + [:characters, ''], + [:start_element, 'span', []], + [:end_element, 'span'], + [:characters, ''], + + [:start_element, 'span', []], + [:characters, ''], + [:end_element, 'span'], + [:characters, ''], + + [:start_element, 'span', []], + [:characters, ''], + [:end_element, 'span'], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + + [:comment, ''], + [:characters, ''], + [:comment, ''], + [:characters, ''], + [:comment, ''], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''] + ], items + + nil + end + end + end + end +end diff --git a/test/xml/sax/test_parser_text.rb b/test/xml/sax/test_parser_text.rb new file mode 100644 index 0000000000..38df773593 --- /dev/null +++ b/test/xml/sax/test_parser_text.rb @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +require "helper" + +module Nokogiri + module XML + module SAX + class TestParserText < Nokogiri::SAX::TestCase + def setup + super + @doc = DocWithOrderedItems.new + @parser = XML::SAX::Parser.new @doc + end + + def test_texts_order + xml = <<-eoxml + + + text 0 +

+ text 1 + text 2 + text 3 +

+ + text 4 + + +

+ + + +

+ + + + +

+ + + +

+
+ eoxml + + @parser.parse xml + items = @doc.items.get_root_content "root" + items = items.select_methods %i[ + start_element end_element + characters comment cdata_block + ] + items.strip_text! %i[characters comment cdata_block] + + assert_equal [ + [:characters, 'text 0'], + + [:start_element, 'p', []], + [:characters, 'text 1'], + + [:start_element, 'span', []], + [:characters, 'text 2'], + [:end_element, 'span'], + + [:characters, 'text 3'], + [:end_element, 'p'], + + [:characters, 'text 4'], + [:comment, 'text 5'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + [:comment, 'text 6'], + [:characters, ''], + + [:start_element, 'span', []], + [:comment, 'text 7'], + [:end_element, 'span'], + [:characters, ''], + + [:comment, 'text 8'], + [:characters, ''], + [:end_element, 'p'], + [:characters, ''], + + [:comment, 'text 9'], + [:characters, ''], + [:cdata_block, 'text 10'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + [:cdata_block, 'text 11'], + [:characters, ''], + + [:start_element, 'span', []], + [:cdata_block, 'text 12'], + [:end_element, 'span'], + [:characters, ''], + + [:cdata_block, 'text 13'], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''] + ], items + + nil + end + + def text_whitespace + xml = <<-eoxml + + +

+ + + + + +

+

+ + + +

+

+ + + +

+
+ eoxml + + @parser.parse xml + items = @doc.items.get_root_content "root" + items = items.select_methods %i[ + start_element end_element + characters comment cdata_block + ] + items.strip_text! %i[characters comment cdata_block] + + assert_equal [ + [:characters, ''], + [:start_element, 'p', []], + + [:characters, ''], + [:start_element, 'span', []], + [:end_element, 'span'], + [:characters, ''], + + [:start_element, 'span', []], + [:characters, ''], + [:end_element, 'span'], + [:characters, ''], + + [:start_element, 'span', []], + [:characters, ''], + [:end_element, 'span'], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + + [:comment, ''], + [:characters, ''], + [:comment, ''], + [:characters, ''], + [:comment, ''], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''], + + [:start_element, 'p', []], + [:characters, ''], + + [:cdata_block, ''], + [:characters, ''], + [:cdata_block, ''], + [:characters, ''], + [:cdata_block, ''], + [:characters, ''], + + [:end_element, 'p'], + [:characters, ''] + ], items + + nil + end + end + end + end +end From be56b1e0084d1fc2ff63bc273ab6f6e7ccfcbea5 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 29 Sep 2017 00:04:04 -0400 Subject: [PATCH 007/176] concourse: more coverage for PRs [skip ci] --- concourse/nokogiri.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 478a25e0e2..97ecb7f3ec 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -26,9 +26,13 @@ groups: - name: PRs jobs: - pr-pending + - ruby-<%= RUBIES[:mri].first %>-system-pr + - ruby-<%= RUBIES[:mri].first %>-vendored-pr + - ruby-<%= RUBIES[:mri].first %>-valgrind-pr - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - jruby-<%= RUBIES[:jruby].first %>-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - pr-success @@ -294,7 +298,7 @@ jobs: - put: nokogiri-pr params: {path: nokogiri-pr, status: pending} -% ruby_version = RUBIES[:mri].last + <% [RUBIES[:mri].first, RUBIES[:mri].last].each do |ruby_version| %> - name: ruby-<%= ruby_version %>-system-pr public: true max_in_flight: 1 @@ -373,8 +377,9 @@ jobs: on_failure: put: nokogiri-pr params: {path: nokogiri-pr, status: failure} + <% end %> -% jruby_version = RUBIES[:jruby].last + <% [RUBIES[:jruby].first, RUBIES[:jruby].last].each do |jruby_version| %> - name: jruby-<%= jruby_version %>-pr public: true max_in_flight: 1 @@ -401,6 +406,7 @@ jobs: on_failure: put: nokogiri-pr params: {path: nokogiri-pr, status: failure} + <% end %> % rbx_version = RUBIES[:rbx].last - name: rbx-<%= rbx_version %>-pr @@ -439,9 +445,13 @@ jobs: trigger: true version: every passed: + - ruby-<%= RUBIES[:mri].first %>-system-pr + - ruby-<%= RUBIES[:mri].first %>-vendored-pr + - ruby-<%= RUBIES[:mri].first %>-valgrind-pr - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - jruby-<%= RUBIES[:jruby].first %>-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - put: nokogiri-pr From 66cc8ee1cb84573783b729c909d8e0e87e0a412a Mon Sep 17 00:00:00 2001 From: Andrew Aladjev Date: Fri, 29 Sep 2017 10:07:11 +0300 Subject: [PATCH 008/176] replaced %i with regular array of symbols to fit ruby-1.9.3 --- test/helper.rb | 16 ++++++++-------- test/html/sax/test_parser_text.rb | 16 ++++++++-------- test/xml/sax/test_parser_text.rb | 16 ++++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index 649279f4c7..e7b6442ecf 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -201,14 +201,14 @@ def initialize @items = Items.new end - %i[ - xmldecl - start_document end_document - start_element end_element - start_element_namespace end_element_namespace - characters comment cdata_block - processing_instruction - error warning + [ + :xmldecl, + :start_document, :end_document, + :start_element, :end_element, + :start_element_namespace, :end_element_namespace, + :characters, :comment, :cdata_block, + :processing_instruction, + :error, :warning ] .each do |name| define_method name do |*arguments| diff --git a/test/html/sax/test_parser_text.rb b/test/html/sax/test_parser_text.rb index f670c5fb0b..1784f06cbe 100644 --- a/test/html/sax/test_parser_text.rb +++ b/test/html/sax/test_parser_text.rb @@ -42,11 +42,11 @@ def test_texts_order @parser.parse html items = @doc.items.get_root_content "body" - items = items.select_methods %i[ - start_element end_element - characters comment + items = items.select_methods [ + :start_element, :end_element, + :characters, :comment ] - items.strip_text! %i[characters comment] + items.strip_text! [:characters, :comment] assert_equal [ [:characters, 'text 0'], @@ -113,11 +113,11 @@ def text_whitespace @parser.parse html items = @doc.items.get_root_content "body" - items = items.select_methods %i[ - start_element end_element - characters comment + items = items.select_methods [ + :start_element, :end_element, + :characters, :comment ] - items.strip_text! %i[characters comment] + items.strip_text! [:characters, :comment] assert_equal [ [:characters, ''], diff --git a/test/xml/sax/test_parser_text.rb b/test/xml/sax/test_parser_text.rb index 38df773593..a1c56eeec6 100644 --- a/test/xml/sax/test_parser_text.rb +++ b/test/xml/sax/test_parser_text.rb @@ -46,11 +46,11 @@ def test_texts_order @parser.parse xml items = @doc.items.get_root_content "root" - items = items.select_methods %i[ - start_element end_element - characters comment cdata_block + items = items.select_methods [ + :start_element, :end_element, + :characters, :comment, :cdata_block ] - items.strip_text! %i[characters comment cdata_block] + items.strip_text! [:characters, :comment, :cdata_block] assert_equal [ [:characters, 'text 0'], @@ -139,11 +139,11 @@ def text_whitespace @parser.parse xml items = @doc.items.get_root_content "root" - items = items.select_methods %i[ - start_element end_element - characters comment cdata_block + items = items.select_methods [ + :start_element, :end_element, + :characters, :comment, :cdata_block ] - items.strip_text! %i[characters comment cdata_block] + items.strip_text! [:characters, :comment, :cdata_block] assert_equal [ [:characters, ''], From c3914e46b1b5f9463ed778f511bfdfc0a968d07d Mon Sep 17 00:00:00 2001 From: Andrew Aladjev Date: Fri, 29 Sep 2017 12:08:02 +0300 Subject: [PATCH 009/176] replaced StringBuffer with StringBuilder, because we don't need synchronization in handler --- ext/java/nokogiri/internals/NokogiriHandler.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 2dfabed2e8..3bd8c240f3 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -61,7 +61,7 @@ * @author Yoko Harada */ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { - StringBuffer charactersBuffer; + StringBuilder charactersBuilder; private final Ruby ruby; private final RubyClass attrClass; private final IRubyObject object; @@ -99,7 +99,7 @@ public void setDocumentLocator(Locator locator) { @Override public void startDocument() throws SAXException { call("start_document"); - charactersBuffer = new StringBuffer(); + charactersBuilder = new StringBuilder(); } @Override @@ -233,7 +233,7 @@ public void endElement(String uri, String localName, String qName) throws SAXExc @Override public void characters(char[] ch, int start, int length) throws SAXException { - charactersBuffer.append(new String(ch, start, length)); + charactersBuilder.append(ch, start, length); } @Override @@ -249,8 +249,8 @@ public void startCDATA() throws SAXException { @Override public void endCDATA() throws SAXException { - call("cdata_block", ruby.newString(charactersBuffer.toString())); - charactersBuffer.setLength(0); + call("cdata_block", ruby.newString(charactersBuilder.toString())); + charactersBuilder.setLength(0); } @Override @@ -330,9 +330,9 @@ private IRubyObject document(ThreadContext context) { } protected void populateCharacters() { - if (charactersBuffer.length() > 0) { - call("characters", ruby.newString(charactersBuffer.toString())); - charactersBuffer.setLength(0); + if (charactersBuilder.length() > 0) { + call("characters", ruby.newString(charactersBuilder.toString())); + charactersBuilder.setLength(0); } } } From 6b65ecb5d44cb0477dc02d659dcb9bb442222be5 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 1 Nov 2017 20:48:57 +0100 Subject: [PATCH 010/176] Fix a couple of issues on OpenBSD If the base compiler or compiler specified by CC is clang, then don't require egcc. Add /usr/local/include as an include directory when compiling. With these changes, the current release of OpenBSD should be able to install nokogiri using gem install. --- ext/nokogiri/extconf.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index 83401a578a..ae89b01992 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -393,8 +393,11 @@ def using_system_libraries? end if openbsd? && !using_system_libraries? - ENV['CC'] ||= find_executable('egcc') or - abort "Please install gcc 4.9+ from ports using `pkg_add -v gcc`" + if `#{ENV['CC'] || '/usr/bin/cc'} -v 2>&1` !~ /clang/ + ENV['CC'] ||= find_executable('egcc') or + abort "Please install gcc 4.9+ from ports using `pkg_add -v gcc`" + end + ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /usr/local/include" end RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] From 53dba0f47a15169db3e0d6c2c623957dac40a85b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 13 Nov 2017 14:06:00 -0500 Subject: [PATCH 011/176] update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec24a1041..cd68f172f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# unreleased + +## Features + +* [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) + + # 1.8.1 / 2017-09-19 ## Dependencies From d69af24ea5931b62916ce3c93a01e644a656e1e9 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 13 Nov 2017 14:10:11 -0500 Subject: [PATCH 012/176] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd68f172f3..d437898c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) +## Bug fixes + +* Node#serialize once again returns UTF-8-encoded strings. [#1659] + + # 1.8.1 / 2017-09-19 ## Dependencies From 1756096d2cd43b3832812e5ac71ecf7244a8db0c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 13 Nov 2017 14:17:56 -0500 Subject: [PATCH 013/176] update libxml2 from 2.9.5 to 2.9.7 --- dependencies.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dependencies.yml b/dependencies.yml index 894fd2a5e5..6d3cecd454 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -1,10 +1,10 @@ libxml2: - version: "2.9.5" - sha256: "4031c1ecee9ce7ba4f313e91ef6284164885cdb69937a123f6a83bb6a72dcd38" + version: "2.9.7" + sha256: "f63c5e7d30362ed28b38bfa1ac6313f9a80230720b7fb6c80575eeab3ff5900c" # manually verified checksum: # - # $ gpg --verify libxml2-2.9.5.tar.gz.asc libxml2-2.9.5.tar.gz - # gpg: Signature made Mon 04 Sep 2017 09:00:53 AM EDT using RSA key ID 596BEA5D + # $ gpg --verify libxml2-2.9.7.tar.gz.asc libxml2-2.9.7.tar.gz + # gpg: Signature made Thu 02 Nov 2017 04:17:54 PM EDT using RSA key ID 596BEA5D # gpg: Good signature from "Daniel Veillard (Red Hat work email) " # gpg: aka "Daniel Veillard " # gpg: WARNING: This key is not certified with a trusted signature! @@ -13,17 +13,17 @@ libxml2: # Subkey fingerprint: DB46 681B B91A DCEA 170F A2D4 1558 8B26 596B EA5D # # using this pgp signature: - # # -----BEGIN PGP SIGNATURE----- # - # iQEcBAABAgAGBQJZrU6FAAoJEBVYiyZZa+pd73cIAMZpWcbiWwFqPgEJtscDfUqs - # V0LjMKYXMDZCUs9/SPV/d6yXbOWSx2PgQ0wa7eCq2KmitIKYlcwnqB1WfAgSvNc+ - # cK8rVwIF4MfZQTzWie6uBvwukDn3224b3qjXxJtPS6J8HmiyK6suwDX5auEgEF8f - # Ac1xy0K/hfAo+W5x7bm+suPHUduI7d6pWo1hNMwW/lyPiQthT4pPElkMBeKTi4vl - # HTRTVEJKjVkdQ2tJ9b5pUYE0Aa6T54SVpCyBRmTu4d/MoOX5VnXBoiZIJDbSA5cD - # GLQeXjDg/tYdq9DpYuT3otYd+6VWuWdH+f6jM6L2+82rAMtOAjBm97Z45XxH31I= - # =T2TF + # iQEcBAABAgAGBQJZ+31yAAoJEBVYiyZZa+pd+MMH/RTsPCo8CegAHsSUlNCae2Ay + # HpM6J7sNWs0b2xwaYRtwhewJ5z/rsCcM5nn7MeGiU8dX7W5MKF69uGXUywufRxzO + # GFoQSxO0a1z5mtGu7jC/W6DTYHFBeOJcEfMa3zUZjZ0RXqrENRhX55okse4pJPmG + # dWQphbu9G3qoCuWD7QpyI7Mjhjemmyi4Ai/4vJPO8WtB7VDfdtpuZFVCRLG2cp0X + # 90SZde+0oWJcN8oIG3FaTd7O4OuJPAceqNhTvF90dLvqSqRBd0RqZNnjYNYZ6uRy + # FQSlQBVCxdLY0AI7Yooq79TJD+0vcqiQNwQwH7L+hBWgvPos4DKN1M9LaJc/RTk= + # =5Qzo # -----END PGP SIGNATURE----- + # libxslt: version: "1.1.30" From a0c6f9b29184516da9eddf432d12da120039625a Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 13 Nov 2017 14:22:18 -0500 Subject: [PATCH 014/176] update libxslt from 1.1.30 to 1.1.32 --- dependencies.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dependencies.yml b/dependencies.yml index 6d3cecd454..f6ab5430a5 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -26,12 +26,12 @@ libxml2: # libxslt: - version: "1.1.30" - sha256: "ba65236116de8326d83378b2bd929879fa185195bc530b9d1aba72107910b6b3" + version: "1.1.32" + sha256: "526ecd0abaf4a7789041622c3950c0e7f2c4c8835471515fd77eec684a355460" # manually verified checksum: # - # $ gpg --verify libxslt-1.1.30.tar.gz.asc libxslt-1.1.30.tar.gz - # gpg: Signature made Mon 04 Sep 2017 09:36:06 AM EDT using RSA key ID 596BEA5D + # $ gpg --verify libxslt-1.1.32.tar.gz.asc libxslt-1.1.32.tar.gz + # gpg: Signature made Thu 02 Nov 2017 04:35:04 PM EDT using RSA key ID 596BEA5D # gpg: Good signature from "Daniel Veillard (Red Hat work email) " # gpg: aka "Daniel Veillard " # gpg: WARNING: This key is not certified with a trusted signature! @@ -43,13 +43,13 @@ libxslt: # # -----BEGIN PGP SIGNATURE----- # - # iQEcBAABAgAGBQJZrVbGAAoJEBVYiyZZa+pdVrMH/Ru0J8zvwx8Geu6PX8ykvdEU - # o5U/izwg8C8a1mtI9M8PcVUsERQinBcngO14Vk0V0dXHLp7/IEpRuXksCYkcTJL9 - # HawU2uDXTE/VwUl9aM2OXJOCk9W/JUkElbqEG11LCfU6uGlV+mFpLVO+eMDPxlRZ - # v2LMs/yBFSiwNw757771ADShdRe3QxqhRscikK/yz/BRESdqls3/3y6GSEV2rx2n - # VKVvsuHFisviwEn+1pvqcAGNCm0pIkPX6/nr+ayK3rBX7tmS493Stp6e/qUYKo6e - # 5cmdTkPhpzICQH2yqeUlfMp1M1nN50oShpvQqyjmpI+SV1udw08suIxVTDUCTRc= - # =LjYD + # iQEcBAABAgAGBQJZ+4F4AAoJEBVYiyZZa+pdy1IIAMX1DpzYGdnv6GCPSKeZ0woD + # sHmSkygJep0/sUQD1cYunNsNZnGDgWhnsLAvHOn3opJgsiaZhmhJ8Uo7QNlT+ni1 + # AvRFgQoSXLWSF5kkun4u7RvnpDI6jYfCuYSwb9SO4EAYFAQQJXQaKCeFq71gad+p + # XGHJFAy2TqUVLNZ5I1mQz/oBeDsJ7RzHpYqaBxsLDqrCzRQ9ai23q+dFGS3jvLBr + # 0gXw0MK73ceOwW12L5aLj4erNbATWmMFMDYZZwftysv3bgx2YfiOoZUTzufrB/Bc + # MG8hP76aYBwIKNbhiDFGa2qdHGZGF7YQ4mi1/ZDX1K1G2tKKeEYxscM13JwiGb8= + # =NuQO # -----END PGP SIGNATURE----- # From b934748148749a553d2353694bc85afe233cd2ae Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 13 Nov 2017 17:10:30 -0500 Subject: [PATCH 015/176] update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d437898c67..25b374ca27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # unreleased +## Dependencies + +* [MRI] libxml2 is updated from 2.9.5 to 2.9.7 +* [MRI] libxml2 is updated from 1.1.30 to 1.1.32 + + ## Features * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) From 9e69d636881e7ad10a8ac8ba11d0c37998468f2d Mon Sep 17 00:00:00 2001 From: Toshi MARUYAMA Date: Mon, 11 Dec 2017 23:50:30 +0900 Subject: [PATCH 016/176] use recent ruby 2.3 and 2.4 on travis --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 625d00b198..5a2af7fd7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,15 +18,15 @@ matrix: - os: osx rvm: 2.2.5 - os: linux - rvm: 2.3.1 + rvm: 2.3.5 - os: osx - rvm: 2.3.1 + rvm: 2.3.5 - os: linux - rvm: 2.4.0 + rvm: 2.4.2 env: - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal" - os: osx - rvm: 2.4.0 + rvm: 2.4.2 env: - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal" - os: linux From 992d81b5bd3a41c4c928700095e2d7dc6663b6d8 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Mon, 25 Dec 2017 12:50:32 +0100 Subject: [PATCH 017/176] Windows: Add cross build for ruby-2.5 --- .cross_rubies | 2 ++ CHANGELOG.md | 1 + Gemfile | 2 +- Rakefile | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.cross_rubies b/.cross_rubies index 027b97e6c8..1600cf4caa 100644 --- a/.cross_rubies +++ b/.cross_rubies @@ -1,3 +1,5 @@ +2.5.0:i686-w64-mingw32 +2.5.0:x86_64-w64-mingw32 2.4.0:i686-w64-mingw32 2.4.0:x86_64-w64-mingw32 2.3.0:i686-w64-mingw32 diff --git a/CHANGELOG.md b/CHANGELOG.md index 25b374ca27..60592e302e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ## Features * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) +* [MRI] Cross-built Windows gems now support Ruby 2.5 ## Bug fixes diff --git a/Gemfile b/Gemfile index 11c67e7bb6..38861dc002 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ gem "hoe-git", "~>1.6", :group => [:development, :test] gem "minitest", "~>5.8.4", :group => [:development, :test] gem "rake", "~>12.0", :group => [:development, :test] gem "rake-compiler", "~>1.0.3", :group => [:development, :test] -gem "rake-compiler-dock", "~>0.6.0", :group => [:development, :test] +gem "rake-compiler-dock", "~>0.6.2", :group => [:development, :test] gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] gem "concourse", "~>0.15", :group => [:development, :test] diff --git a/Rakefile b/Rakefile index 60a6dc3b6a..ef996d0a89 100644 --- a/Rakefile +++ b/Rakefile @@ -137,7 +137,7 @@ HOE = Hoe.spec 'nokogiri' do ["minitest", "~> 5.8.4"], ["rake", "~> 12.0"], ["rake-compiler", "~> 1.0.3"], - ["rake-compiler-dock", "~> 0.6.0"], + ["rake-compiler-dock", "~> 0.6.2"], ["racc", "~> 1.4.14"], ["rexical", "~> 1.0.5"], ["concourse", "~> 0.15"], From cc80904c9770e83df97548e02f5c829fe24a25bc Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Mon, 25 Dec 2017 20:55:21 +0100 Subject: [PATCH 018/176] Appveyor: Add ruby-2.4 and ruby-head to build matrix Testing both x86 and x64 builds of all ruby versions isn't very useful, so let's alternate between x86 and x64, to decrease test time. Ruby-2.5 is not yet available on Appveyor, but ruby-head should be enough for now. Bundler is pre-installed on Appveyor, but missing on ruby-head. Thanks to MSP-Greg for initial patch! Closes #1702 --- appveyor.yml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a838745aea..8080664f76 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,24 +1,29 @@ install: - - SET PATH=C:\Ruby%ruby_version%\bin;%PATH% - - SET PATH=C:\MinGW\bin;%PATH% - - SET RAKEOPT=-rdevkit + - SET PATH=C:\ruby%ruby_version%\bin;%PATH% + - ps: | + if ($env:ruby_version -like "*head*") { + $(new-object net.webclient).DownloadFile("https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller-$env:ruby_version.exe", "$pwd/ruby-setup.exe") + cmd /c ruby-setup.exe /verysilent /dir=C:/Ruby$env:ruby_version + } - ruby --version - gem --version + - gem install bundler --conservative - bundle install build: off test_script: - - bundle exec rake + - bundle exec rake -rdevkit environment: matrix: - - ruby_version: "23" - - ruby_version: "23-x64" - - ruby_version: "22" - - ruby_version: "22-x64" - - ruby_version: "21" - - ruby_version: "21-x64" - - ruby_version: "200" - - ruby_version: "200-x64" - - ruby_version: "193" + - ruby_version: head-x64 + - ruby_version: 24 + - ruby_version: 23-x64 + - ruby_version: 22 + - ruby_version: 21-x64 + - ruby_version: 200 + +matrix: + allow_failures: + - ruby_version: head From bf94cf503394edf2e74462e9ff3a6b822c21bf0c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 27 Jan 2018 21:39:11 -0500 Subject: [PATCH 019/176] remove hacks to discover the path to `racc` this wasn't working properly on mingw32 platforms, and is unnecessary in any case in a bundler world. this code was originally added in 2008 with commit da6292d, then was later hacked in 2010 and 2011 to work around things that don't matter anymore. yay for progress. --- Rakefile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index ef996d0a89..3440cadfa7 100644 --- a/Rakefile +++ b/Rakefile @@ -264,10 +264,7 @@ task 'bundler:gemfile' do end file GENERATED_PARSER => "lib/nokogiri/css/parser.y" do |t| - racc = RbConfig::CONFIG['target_os'] =~ /mswin32/ ? '' : `which racc`.strip - racc = "#{::RbConfig::CONFIG['bindir']}/racc" if racc.empty? - racc = %x{command -v racc}.strip if racc.empty? - sh "#{racc} -l -o #{t.name} #{t.prerequisites.first}" + sh "racc -l -o #{t.name} #{t.prerequisites.first}" end file GENERATED_TOKENIZER => "lib/nokogiri/css/tokenizer.rex" do |t| From d3456e456328e8af9809e216204622a40d012525 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 09:14:50 -0500 Subject: [PATCH 020/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60592e302e..b732ccfd29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ## Bug fixes * Node#serialize once again returns UTF-8-encoded strings. [#1659] +* [JRuby] made SAX parsing of characters consistent with C implementation [#1676] (Thanks, @andrew-aladev!) # 1.8.1 / 2017-09-19 From b1494e5ae55ad704efb4a7d7d3aca4294f42a0ce Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 12:28:05 -0500 Subject: [PATCH 021/176] ensure EntityReferences ignore malformed children libxml2 will cause EntityReferences to have a malformed child node for predefined entities. because any use of that child is likely to cause a segfault, we shall pretend that it doesn't exist. [fixes #1238] --- Manifest.txt | 5 +++-- lib/nokogiri/xml.rb | 1 + lib/nokogiri/xml/entity_reference.rb | 18 ++++++++++++++++++ test/xml/test_entity_reference.rb | 11 +++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 lib/nokogiri/xml/entity_reference.rb diff --git a/Manifest.txt b/Manifest.txt index f5483fcfb9..5c7f4f0aa3 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -217,6 +217,7 @@ lib/nokogiri/xml/dtd.rb lib/nokogiri/xml/element_content.rb lib/nokogiri/xml/element_decl.rb lib/nokogiri/xml/entity_decl.rb +lib/nokogiri/xml/entity_reference.rb lib/nokogiri/xml/namespace.rb lib/nokogiri/xml/node.rb lib/nokogiri/xml/node/save_options.rb @@ -297,8 +298,8 @@ test/files/xinclude.xml test/helper.rb test/html/sax/test_parser.rb test/html/sax/test_parser_context.rb -test/html/sax/test_push_parser.rb test/html/sax/test_parser_text.rb +test/html/sax/test_push_parser.rb test/html/test_builder.rb test/html/test_document.rb test/html/test_document_encoding.rb @@ -325,8 +326,8 @@ test/xml/node/test_save_options.rb test/xml/node/test_subclass.rb test/xml/sax/test_parser.rb test/xml/sax/test_parser_context.rb -test/xml/sax/test_push_parser.rb test/xml/sax/test_parser_text.rb +test/xml/sax/test_push_parser.rb test/xml/test_attr.rb test/xml/test_attribute_decl.rb test/xml/test_builder.rb diff --git a/lib/nokogiri/xml.rb b/lib/nokogiri/xml.rb index a298e74601..bbb8c81b88 100644 --- a/lib/nokogiri/xml.rb +++ b/lib/nokogiri/xml.rb @@ -23,6 +23,7 @@ require 'nokogiri/xml/reader' require 'nokogiri/xml/notation' require 'nokogiri/xml/entity_decl' +require 'nokogiri/xml/entity_reference' require 'nokogiri/xml/schema' require 'nokogiri/xml/relax_ng' diff --git a/lib/nokogiri/xml/entity_reference.rb b/lib/nokogiri/xml/entity_reference.rb new file mode 100644 index 0000000000..56edffd42d --- /dev/null +++ b/lib/nokogiri/xml/entity_reference.rb @@ -0,0 +1,18 @@ +module Nokogiri + module XML + class EntityReference < Nokogiri::XML::Node + def children + # libxml2 will create a malformed child node for predefined + # entities. because any use of that child is likely to cause a + # segfault, we shall pretend that it doesn't exist. + # + # see https://github.com/sparklemotion/nokogiri/issues/1238 for details + NodeSet.new(document) + end + + def inspect_attributes + [:name] + end + end + end +end diff --git a/test/xml/test_entity_reference.rb b/test/xml/test_entity_reference.rb index aae98753c2..ea67c32f00 100644 --- a/test/xml/test_entity_reference.rb +++ b/test/xml/test_entity_reference.rb @@ -28,6 +28,17 @@ def test_newline_node doc.xpath('/item').first.add_child(lf_node) assert_match(/ /, doc.to_xml) end + + def test_children_should_always_be_empty + # https://github.com/sparklemotion/nokogiri/issues/1238 + # + # libxml2 will create a malformed child node for predefined + # entities. because any use of that child is likely to cause a + # segfault, we shall pretend that it doesn't exist. + entity = Nokogiri::XML::EntityReference.new(@xml, "amp") + assert_equal 0, entity.children.length + entity.inspect # should not segfault + end end module Common From 62b1a5b1a9aa32983d5dc4d09a156241f97c8797 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 12:56:24 -0500 Subject: [PATCH 022/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b732ccfd29..3fd359ec21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * Node#serialize once again returns UTF-8-encoded strings. [#1659] * [JRuby] made SAX parsing of characters consistent with C implementation [#1676] (Thanks, @andrew-aladev!) +* [MRI] Predefined entities, when inspected, no longer cause a segfault. [#1238] # 1.8.1 / 2017-09-19 From d35ed46f618e9c41e464a392fbc43df2b6cfa529 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 29 Jan 2018 00:05:05 -0500 Subject: [PATCH 023/176] update CHANGELOG [related to #1714] [skip ci] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fd359ec21..7281fb8b63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # unreleased +## Security Notes + +[MRI] The update of vendored libxml2 from 2.9.5 to 2.9.7 addresses at least one published vulnerability, CVE-2017-15412. [#1714 has complete details] + + ## Dependencies * [MRI] libxml2 is updated from 2.9.5 to 2.9.7 From f80f4ad9f553811435aa2c40908a49fcd26c4533 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 29 Jan 2018 00:11:48 -0500 Subject: [PATCH 024/176] version bump to 1.8.2 --- CHANGELOG.md | 2 +- lib/nokogiri/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7281fb8b63..07ee03c1aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# unreleased +# 1.8.2 / 2018-01-29 ## Security Notes diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index cd08e26995..de96be9b7c 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.8.1' + VERSION = '1.8.2' class VersionInfo # :nodoc: def jruby? From b56e2ee0f97f26623cce374047f35b6f3391d4d2 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 29 Jan 2018 00:48:13 -0500 Subject: [PATCH 025/176] move build of JRuby gem to using JRuby 9000 --- build_all | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_all b/build_all index 49a27ddf4c..8b983d3829 100755 --- a/build_all +++ b/build_all @@ -37,8 +37,8 @@ cp -v pkg/nokogiri*.gem gems bundle exec rake clean clobber bundle exec rake generate -rvm jruby-1.7.19 +rvm jruby gem install bundler --conservative bundle install --quiet --local || bundle install -bundle exec rake gem +bundle exec ruby -S rake gem cp -v pkg/nokogiri*java.gem gems From 24e75bc5c52c6de5858bea5223abb1fa614f08ee Mon Sep 17 00:00:00 2001 From: John Shahid Date: Mon, 29 Jan 2018 10:35:24 -0500 Subject: [PATCH 026/176] remove unecessary calls to clearCachedNode fixes #1708 --- ext/java/nokogiri/XmlNode.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 265cb77263..f4a2e95d6c 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -464,9 +464,6 @@ public void relink_namespace(ThreadContext context) { return; } - // TODO: this feels kind of weird, why are we clearing the XmlNode - // cache here !!! - clearCachedNode(node); Element e = (Element) node; // disable error checking to prevent lines like the following @@ -512,7 +509,6 @@ public void relink_namespace(ThreadContext context) { // TODO: why do we need the namespace cache ? XmlNamespace.createFromAttr(context.getRuntime(), attr); } - clearCachedNode(attr); NokogiriHelpers.renameNode(attr, nsUri, nodeName); } } From 79fad66fea3166139c68cb2325583bb2acd69c51 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 30 Jan 2018 12:46:36 -0500 Subject: [PATCH 027/176] writing nil is a no-op --- ext/java/nokogiri/XmlSaxPushParser.java | 3 +-- test/xml/sax/test_push_parser.rb | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index ff5effd680..1224584097 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -146,8 +146,7 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } final ByteArrayInputStream data = NokogiriHelpers.stringBytesToStream(chunk); if (data == null) { - terminateTask(context); - throw new RaiseException(XmlSyntaxError.createXMLSyntaxError(context.runtime)); // Nokogiri::XML::SyntaxError + return this; } int errorCount0 = parserTask.getErrorCount(); diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index d2fac2e7c6..2b7c064d21 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -21,6 +21,10 @@ def test_exception end end + def test_writing_nil + assert_equal @parser.write(nil), @parser + end + def test_end_document_called @parser.<<(<<-eoxml)

From 38ba4ab99b54be6a22532db0501c5584ed8d4796 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 30 Jan 2018 12:54:34 -0500 Subject: [PATCH 028/176] rethrow exceptions raised by the sax handler --- ext/java/nokogiri/HtmlSaxPushParser.java | 6 ++--- ext/java/nokogiri/XmlSaxPushParser.java | 6 ++--- .../nokogiri/internals/NokogiriHandler.java | 23 +++++++++++++------ test/xml/sax/test_push_parser.rb | 18 +++++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/ext/java/nokogiri/HtmlSaxPushParser.java b/ext/java/nokogiri/HtmlSaxPushParser.java index 6a6461c6de..0653d38757 100644 --- a/ext/java/nokogiri/HtmlSaxPushParser.java +++ b/ext/java/nokogiri/HtmlSaxPushParser.java @@ -160,7 +160,7 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, if (!options.recover && parserTask.getErrorCount() > errorCount0) { terminateTask(context); - throw new RaiseException(parserTask.getLastError(), true); + throw parserTask.getLastError(); } return this; @@ -233,8 +233,8 @@ private synchronized int getErrorCount() { else return parser.getNokogiriHandler().getErrorCount(); } - private synchronized RubyException getLastError() { - return (RubyException) parser.getNokogiriHandler().getLastError(); + private synchronized RaiseException getLastError() { + return parser.getNokogiriHandler().getLastError(); } } } diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index 1224584097..ea1e5b0548 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -176,7 +176,7 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, if (!options.recover && parserTask.getErrorCount() > errorCount0) { terminateTask(context); - throw new RaiseException(parserTask.getLastError(), true); + throw parserTask.getLastError(); } return this; @@ -248,8 +248,8 @@ private synchronized int getErrorCount() { else return parser.getNokogiriHandler().getErrorCount(); } - private synchronized RubyException getLastError() { - return (RubyException) parser.getNokogiriHandler().getLastError(); + private synchronized RaiseException getLastError() { + return parser.getNokogiriHandler().getLastError(); } } } diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 3bd8c240f3..823f877191 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -45,6 +45,7 @@ import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyObject; +import org.jruby.exceptions.RaiseException; import org.jruby.javasupport.util.RuntimeHelpers; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @@ -72,7 +73,7 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { * TODO: should these be stored in the document 'errors' array? * Currently only string messages are stored there. */ - private final LinkedList errors = new LinkedList(); + private final LinkedList errors = new LinkedList(); private Locator locator; private static String htmlParserName = "Nokogiri::HTML::SAX::Parser"; @@ -255,15 +256,23 @@ public void endCDATA() throws SAXException { @Override public void error(SAXParseException saxpe) { - addError(XmlSyntaxError.createError(ruby, saxpe)); - call("error", ruby.newString(saxpe.getMessage())); + try { + call("error", ruby.newString(saxpe.getMessage())); + addError(new RaiseException(XmlSyntaxError.createError(ruby, saxpe), true)); + } catch(RaiseException e) { + addError(e); + } } @Override public void fatalError(SAXParseException saxpe) throws SAXException { - addError(XmlSyntaxError.createFatalError(ruby, saxpe)); - call("error", ruby.newString(saxpe.getMessage())); + try { + call("error", ruby.newString(saxpe.getMessage())); + addError(new RaiseException(XmlSyntaxError.createFatalError(ruby, saxpe), true)); + } catch(RaiseException e) { + addError(e); + } } @Override @@ -272,7 +281,7 @@ public void warning(SAXParseException saxpe) { call("warning", ruby.newString(saxpe.getMessage())); } - protected synchronized void addError(XmlSyntaxError e) { + protected synchronized void addError(RaiseException e) { errors.add(e); } @@ -280,7 +289,7 @@ public synchronized int getErrorCount() { return errors.size(); } - public synchronized IRubyObject getLastError() { + public synchronized RaiseException getLastError() { return errors.getLast(); } diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index 2b7c064d21..e5118608d8 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -21,6 +21,24 @@ def test_exception end end + def test_should_throw_error_returned_by_document + doc = Doc.new + class << doc + def error msg + raise "parse error" + end + end + + @parser = XML::SAX::PushParser.new(doc) + begin + @parser << "" + rescue => e + actual = e + end + + assert_equal actual.message, "parse error" + end + def test_writing_nil assert_equal @parser.write(nil), @parser end From 8fe8a104f52a43e859b0b79fac0546b7a0a301c2 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 30 Jan 2018 12:57:37 -0500 Subject: [PATCH 029/176] rethrow the last exception in finish --- ext/java/nokogiri/XmlSaxPushParser.java | 10 +++++++++- test/xml/sax/test_push_parser.rb | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index ea1e5b0548..b6119fb005 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -77,6 +77,7 @@ public class XmlSaxPushParser extends RubyObject { ParserTask parserTask = null; FutureTask futureTask = null; ExecutorService executor = null; + RaiseException ex = null; public XmlSaxPushParser(Ruby ruby, RubyClass rubyClass) { super(ruby, rubyClass); @@ -139,6 +140,11 @@ public IRubyObject getReplaceEntities(ThreadContext context) { @JRubyMethod public IRubyObject native_write(ThreadContext context, IRubyObject chunk, IRubyObject isLast) { + if (ex != null) { + // parser has already errored, rethrow the exception + throw ex; + } + try { initialize_task(context); } catch (IOException e) { @@ -158,8 +164,9 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } catch (SAXException e) { throw context.runtime.newRuntimeError(e.getMessage()); + } finally { + terminateTask(context); } - terminateTask(context); } else { try { Future task = stream.addChunk(data); @@ -176,6 +183,7 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, if (!options.recover && parserTask.getErrorCount() > errorCount0) { terminateTask(context); + ex = parserTask.getLastError(); throw parserTask.getLastError(); } diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index e5118608d8..300d0305bc 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -21,6 +21,22 @@ def test_exception end end + def test_finish_should_rethrow_last_error + begin + @parser << "" + rescue => e + expected = e + end + + begin + @parser.finish + rescue => e + actual = e + end + + assert_equal actual.message, expected.message + end + def test_should_throw_error_returned_by_document doc = Doc.new class << doc From c5a36217e64cb6af1c4210d8da5f447c8757c897 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 30 Jan 2018 13:00:51 -0500 Subject: [PATCH 030/176] native_write should write the last chunk when last is true --- ext/java/nokogiri/XmlSaxPushParser.java | 20 ++++++++------------ test/xml/sax/test_push_parser.rb | 8 ++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index b6119fb005..19a183e81e 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -157,6 +157,14 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, int errorCount0 = parserTask.getErrorCount(); + try { + Future task = stream.addChunk(data); + task.get(); + } catch (ClosedStreamException ex) { + // this means the stream is closed, ignore this exception + } catch (Exception e) { + throw context.runtime.newRuntimeError(e.toString()); + } if (isLast.isTrue()) { try { @@ -167,18 +175,6 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } finally { terminateTask(context); } - } else { - try { - Future task = stream.addChunk(data); - task.get(); - } - catch (ClosedStreamException ex) { - // this means the stream is closed, ignore this exception - } - catch (Exception e) { - throw context.runtime.newRuntimeError(e.toString()); - } - } if (!options.recover && parserTask.getErrorCount() > errorCount0) { diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index 300d0305bc..845a6cf155 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -21,6 +21,14 @@ def test_exception end end + def test_write_last_chunk + @parser << "" + @parser.write "", true + assert_equal [["foo", []]], @parser.document.start_elements + assert_equal [["foo"]], @parser.document.end_elements + end + + def test_finish_should_rethrow_last_error begin @parser << "" From 090563c4094761ebbb5fe396ffcb197211b41557 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 30 Jan 2018 13:09:13 -0500 Subject: [PATCH 031/176] finishing the document prematurely should raise an SyntaxError prior to this fix the JRuby implementation raised RuntimeError instead --- ext/java/nokogiri/XmlSaxPushParser.java | 4 ++++ test/xml/sax/test_push_parser.rb | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index 19a183e81e..4616482868 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -206,6 +206,10 @@ public Thread newThread(Runnable r) { } private synchronized void terminateTask(ThreadContext context) { + if (futureTask == null || stream == null) { + return; + } + try { Future task = stream.addChunk(NokogiriBlockingQueueInputStream.END); task.get(); diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index 845a6cf155..29204fc1cd 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -21,6 +21,13 @@ def test_exception end end + def test_early_finish + @parser << "" + assert_raises(SyntaxError) do + @parser.finish + end + end + def test_write_last_chunk @parser << "" @parser.write "", true From d5d66be4e2fb3b4eac42c434895c3db40d57f7ca Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Feb 2018 17:22:59 -0500 Subject: [PATCH 032/176] fix type in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07ee03c1aa..8a7ee79524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ## Dependencies * [MRI] libxml2 is updated from 2.9.5 to 2.9.7 -* [MRI] libxml2 is updated from 1.1.30 to 1.1.32 +* [MRI] libxslt is updated from 1.1.30 to 1.1.32 ## Features From 3b273ad59e46e8f22eaf550ab2cb193cfb837be8 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Feb 2018 17:54:21 -0500 Subject: [PATCH 033/176] CSS attribute selectors gracefully handle integers [fixes #711] --- lib/nokogiri/css/parser.rb | 186 +++++++++++++++++++------------------ lib/nokogiri/css/parser.y | 1 + test/css/test_parser.rb | 5 + test/xml/test_xpath.rb | 8 ++ 4 files changed, 111 insertions(+), 89 deletions(-) diff --git a/lib/nokogiri/css/parser.rb b/lib/nokogiri/css/parser.rb index 345a50dcd7..6cdbf907b2 100644 --- a/lib/nokogiri/css/parser.rb +++ b/lib/nokogiri/css/parser.rb @@ -1,6 +1,6 @@ # # DO NOT MODIFY!!!! -# This file is automatically generated by Racc 1.4.12 +# This file is automatically generated by Racc 1.4.14 # from Racc grammer file "". # @@ -21,99 +21,101 @@ def unescape_css_identifier(identifier) racc_action_table = [ 24, 93, 56, 57, 33, 55, 94, 23, 24, 22, - 12, 93, 33, 27, 35, 52, 88, 22, -23, 25, - 92, 98, 23, 33, 26, 18, 20, 25, 27, 86, + 12, 93, 33, 27, 35, 52, 44, 22, -23, 25, + 45, 98, 23, 33, 26, 18, 20, 25, 27, -23, 23, 24, 26, 18, 20, 33, 27, 11, 39, 24, - 22, 23, 89, 33, 18, 101, 100, 27, 22, 12, - 25, 24, 95, 23, 90, 26, 18, 20, 25, 27, - 66, 23, 24, 26, 18, 20, 33, 27, 91, 90, - 51, 22, 96, 85, 33, 26, 33, -23, 33, 56, - 87, 25, 60, 99, 23, 74, 26, 18, 20, 39, - 27, 39, 23, 39, 23, 18, 23, 18, 27, 18, - 27, 33, 27, 33, 56, 87, 22, 60, 56, 87, - 102, 60, 56, 87, 33, 60, 39, 24, 39, 23, - 103, 23, 18, 20, 18, 27, 46, 27, 49, 39, - 93, 44, 23, 105, 33, 18, 51, 45, 27, 33, - -23, 26, 108, 56, 58, 109, 60, nil, nil, 39, - nil, nil, 23, nil, 39, 18, nil, 23, 27, nil, - 18, 20, nil, 27, 82, 83, nil, nil, nil, 82, - 83, nil, nil, nil, nil, 78, 79, 80, nil, 81, - 78, 79, 80, 77, 81, 4, 5, 10, 77, 4, - 5, 43, nil, nil, nil, 6, nil, 8, 7, 6, - nil, 8, 7, 4, 5, 10, nil, nil, nil, nil, - nil, nil, nil, 6, nil, 8, 7 ] + 22, 23, 74, 33, 18, 91, 90, 27, 22, 12, + 25, 24, -23, 23, 85, 26, 18, 20, 25, 27, + 66, 23, 24, 26, 18, 20, 33, 27, 86, 88, + 51, 22, 89, 92, 24, 26, 56, 87, 95, 60, + 90, 25, 96, 46, 23, 49, 26, 18, 20, 99, + 27, 33, 33, 51, 103, 104, 56, 58, 26, 60, + 93, 106, 33, 33, 33, 109, 39, 39, 110, 23, + 23, nil, 18, 18, 20, 27, 27, 39, 39, 39, + 23, 23, 23, 18, 18, 18, 27, 27, 27, 33, + 33, 101, 100, nil, 102, 22, 56, 87, nil, 60, + 33, nil, nil, nil, 39, 39, nil, 23, 23, nil, + 18, 18, 20, 27, 27, 39, 82, 83, 23, 56, + 87, 18, 60, nil, 27, 82, 83, 78, 79, 80, + nil, 81, nil, nil, nil, 77, 78, 79, 80, nil, + 81, 4, 5, 10, 77, 4, 5, 43, nil, 56, + 87, 6, 60, 8, 7, 6, nil, 8, 7, 4, + 5, 10, nil, nil, nil, nil, nil, nil, nil, 6, + nil, 8, 7 ] racc_action_check = [ - 42, 58, 24, 24, 42, 24, 57, 15, 43, 42, - 64, 57, 43, 15, 11, 24, 53, 43, 58, 42, - 56, 64, 42, 14, 42, 42, 42, 43, 42, 50, - 43, 3, 43, 43, 43, 3, 43, 1, 14, 9, - 3, 14, 54, 9, 14, 76, 76, 14, 9, 1, - 3, 27, 59, 3, 60, 3, 3, 3, 9, 3, - 27, 9, 12, 9, 9, 9, 12, 9, 55, 55, - 27, 12, 61, 49, 28, 27, 62, 46, 30, 92, - 92, 12, 92, 75, 12, 45, 12, 12, 12, 28, - 12, 62, 28, 30, 62, 28, 30, 62, 28, 30, - 62, 39, 30, 32, 90, 90, 39, 90, 51, 51, - 84, 51, 93, 93, 31, 93, 39, 23, 32, 39, - 86, 32, 39, 39, 32, 39, 23, 32, 23, 31, - 87, 18, 31, 91, 29, 31, 23, 21, 31, 25, - 22, 23, 94, 25, 25, 105, 25, nil, nil, 29, - nil, nil, 29, nil, 25, 29, nil, 25, 29, nil, - 25, 25, nil, 25, 48, 48, nil, nil, nil, 47, - 47, nil, nil, nil, nil, 48, 48, 48, nil, 48, - 47, 47, 47, 48, 47, 0, 0, 0, 47, 17, - 17, 17, nil, nil, nil, 0, nil, 0, 0, 17, - nil, 17, 17, 26, 26, 26, nil, nil, nil, nil, - nil, nil, nil, 26, nil, 26, 26 ] + 3, 58, 24, 24, 3, 24, 57, 15, 9, 3, + 64, 57, 9, 15, 11, 24, 18, 9, 58, 3, + 21, 64, 3, 14, 3, 3, 3, 9, 3, 22, + 9, 12, 9, 9, 9, 12, 9, 1, 14, 42, + 12, 14, 45, 42, 14, 55, 55, 14, 42, 1, + 12, 27, 46, 12, 49, 12, 12, 12, 42, 12, + 27, 42, 43, 42, 42, 42, 43, 42, 50, 53, + 27, 43, 54, 56, 23, 27, 51, 51, 59, 51, + 60, 43, 61, 23, 43, 23, 43, 43, 43, 75, + 43, 28, 25, 23, 84, 86, 25, 25, 23, 25, + 87, 91, 29, 30, 31, 94, 28, 25, 106, 28, + 25, nil, 28, 25, 25, 28, 25, 29, 30, 31, + 29, 30, 31, 29, 30, 31, 29, 30, 31, 32, + 39, 76, 76, nil, 76, 39, 90, 90, nil, 90, + 62, nil, nil, nil, 32, 39, nil, 32, 39, nil, + 32, 39, 39, 32, 39, 62, 47, 47, 62, 92, + 92, 62, 92, nil, 62, 48, 48, 47, 47, 47, + nil, 47, nil, nil, nil, 47, 48, 48, 48, nil, + 48, 0, 0, 0, 48, 17, 17, 17, nil, 93, + 93, 0, 93, 0, 0, 17, nil, 17, 17, 26, + 26, 26, nil, nil, nil, nil, nil, nil, nil, 26, + nil, 26, 26 ] racc_action_pointer = [ - 178, 37, nil, 29, nil, nil, nil, nil, nil, 37, - nil, 14, 60, nil, 17, -17, nil, 182, 120, nil, - nil, 108, 111, 115, -8, 133, 196, 49, 68, 128, - 72, 108, 97, nil, nil, nil, nil, nil, nil, 95, - nil, nil, -2, 6, nil, 74, 48, 166, 161, 48, - 0, 98, nil, -7, 19, 57, 8, -1, -11, 29, - 42, 49, 70, nil, -2, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 58, 35, nil, nil, nil, - nil, nil, nil, nil, 85, nil, 109, 118, nil, nil, - 94, 126, 69, 102, 129, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 132, nil, nil, nil, nil ] + 174, 37, nil, -2, nil, nil, nil, nil, nil, 6, + nil, 14, 29, nil, 17, -17, nil, 178, 5, nil, + nil, -9, 0, 72, -8, 86, 192, 49, 85, 96, + 97, 98, 123, nil, nil, nil, nil, nil, nil, 124, + nil, nil, 37, 60, nil, 31, 23, 153, 162, 29, + 39, 66, nil, 46, 49, 34, 61, -1, -11, 55, + 68, 59, 134, nil, -2, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 121, nil, nil, nil, + nil, nil, nil, nil, 69, nil, 84, 88, nil, nil, + 126, 94, 149, 179, 92, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 95, nil, nil, nil, + nil ] racc_action_default = [ - -74, -75, -2, -24, -4, -5, -6, -7, -8, -24, - -73, -75, -24, -3, -47, -10, -13, -17, -75, -19, - -20, -75, -22, -24, -75, -24, -74, -75, -53, -54, - -55, -56, -57, -58, -14, 110, -1, -9, -46, -24, - -11, -12, -24, -24, -18, -75, -29, -61, -61, -75, - -75, -75, -30, -75, -75, -38, -39, -40, -22, -75, - -38, -75, -70, -72, -75, -44, -45, -48, -49, -50, - -51, -52, -15, -16, -21, -75, -75, -62, -63, -64, - -65, -66, -67, -68, -75, -27, -75, -40, -31, -32, - -75, -43, -75, -75, -75, -33, -69, -71, -34, -25, - -59, -60, -26, -28, -35, -75, -36, -37, -42, -41 ] + -75, -76, -2, -24, -4, -5, -6, -7, -8, -24, + -74, -76, -24, -3, -47, -10, -13, -17, -76, -19, + -20, -76, -22, -24, -76, -24, -75, -76, -53, -54, + -55, -56, -57, -58, -14, 111, -1, -9, -46, -24, + -11, -12, -24, -24, -18, -76, -29, -62, -62, -76, + -76, -76, -30, -76, -76, -38, -39, -40, -22, -76, + -38, -76, -71, -73, -76, -44, -45, -48, -49, -50, + -51, -52, -15, -16, -21, -76, -76, -63, -64, -65, + -66, -67, -68, -69, -76, -27, -76, -40, -31, -32, + -76, -43, -76, -76, -76, -33, -70, -72, -34, -25, + -59, -60, -61, -26, -28, -35, -76, -36, -37, -42, + -41 ] racc_goto_table = [ - 53, 38, 13, 1, 41, 48, 62, 40, 34, 65, - 50, 36, 63, 75, 84, 67, 68, 69, 70, 71, - 62, 47, 37, 42, 54, nil, 63, nil, nil, 64, + 53, 38, 13, 1, 42, 48, 62, 37, 34, 65, + 40, 36, 63, 75, 84, 67, 68, 69, 70, 71, + 62, 41, 50, 47, 54, nil, 63, nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 72, 73, nil, nil, nil, nil, nil, nil, 97, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 104, nil, 106, 107 ] + nil, nil, nil, nil, nil, nil, 105, nil, 107, 108 ] racc_goto_check = [ - 18, 12, 2, 1, 11, 9, 7, 10, 2, 9, - 15, 2, 12, 17, 17, 12, 12, 12, 12, 12, - 7, 16, 8, 5, 19, nil, 12, nil, nil, 1, + 18, 12, 2, 1, 5, 9, 7, 8, 2, 9, + 10, 2, 12, 17, 17, 12, 12, 12, 12, 12, + 7, 11, 15, 16, 19, nil, 12, nil, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2, 2, nil, nil, nil, nil, nil, nil, 12, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, 18, 18 ] racc_goto_pointer = [ - nil, 3, -1, nil, nil, 6, nil, -19, 8, -18, - -8, -11, -13, nil, nil, -13, -2, -34, -24, 0, + nil, 3, -1, nil, nil, -13, nil, -19, -7, -18, + -5, 6, -13, nil, nil, -1, 0, -34, -24, 0, nil, nil, nil, nil ] racc_goto_default = [ @@ -183,24 +185,25 @@ def unescape_css_identifier(identifier) 1, 51, :_reduce_58, 2, 48, :_reduce_59, 2, 48, :_reduce_60, + 2, 48, :_reduce_61, 0, 48, :_reduce_none, - 1, 53, :_reduce_62, 1, 53, :_reduce_63, 1, 53, :_reduce_64, 1, 53, :_reduce_65, 1, 53, :_reduce_66, 1, 53, :_reduce_67, 1, 53, :_reduce_68, - 3, 52, :_reduce_69, + 1, 53, :_reduce_69, + 3, 52, :_reduce_70, 1, 54, :_reduce_none, 2, 54, :_reduce_none, 1, 54, :_reduce_none, 1, 35, :_reduce_none, 0, 35, :_reduce_none ] -racc_reduce_n = 75 +racc_reduce_n = 76 -racc_shift_n = 110 +racc_shift_n = 111 racc_token_table = { false => 0, @@ -670,51 +673,54 @@ def _reduce_60(val, _values, result) result end -# reduce 61 omitted +def _reduce_61(val, _values, result) + result = [val.first, val[1]] + result +end -def _reduce_62(val, _values, result) +# reduce 62 omitted + +def _reduce_63(val, _values, result) result = :equal result end -def _reduce_63(val, _values, result) +def _reduce_64(val, _values, result) result = :prefix_match result end -def _reduce_64(val, _values, result) +def _reduce_65(val, _values, result) result = :suffix_match result end -def _reduce_65(val, _values, result) +def _reduce_66(val, _values, result) result = :substring_match result end -def _reduce_66(val, _values, result) +def _reduce_67(val, _values, result) result = :not_equal result end -def _reduce_67(val, _values, result) +def _reduce_68(val, _values, result) result = :includes result end -def _reduce_68(val, _values, result) +def _reduce_69(val, _values, result) result = :dash_match result end -def _reduce_69(val, _values, result) +def _reduce_70(val, _values, result) result = Node.new(:NOT, [val[1]]) result end -# reduce 70 omitted - # reduce 71 omitted # reduce 72 omitted @@ -723,6 +729,8 @@ def _reduce_69(val, _values, result) # reduce 74 omitted +# reduce 75 omitted + def _reduce_none(val, _values, result) val[0] end diff --git a/lib/nokogiri/css/parser.y b/lib/nokogiri/css/parser.y index 1146f8f588..9195510ec1 100644 --- a/lib/nokogiri/css/parser.y +++ b/lib/nokogiri/css/parser.y @@ -223,6 +223,7 @@ rule attrib_val_0or1 : eql_incl_dash IDENT { result = [val.first, val[1]] } | eql_incl_dash STRING { result = [val.first, val[1]] } + | eql_incl_dash NUMBER { result = [val.first, val[1]] } | ; eql_incl_dash diff --git a/test/css/test_parser.rb b/test/css/test_parser.rb index c1c8b5f944..0ff9d24adb 100644 --- a/test/css/test_parser.rb +++ b/test/css/test_parser.rb @@ -257,6 +257,11 @@ def test_attribute @parser.parse("h1[a='Tender Lovemaking']") end + def test_attribute_with_number_or_string + assert_xpath "//img[@width = '200']", @parser.parse("img[width='200']") + assert_xpath "//img[@width = '200']", @parser.parse("img[width=200]") + end + def test_id assert_xpath "//*[@id = 'foo']", @parser.parse('#foo') assert_xpath "//*[@id = 'escape:needed,']", @parser.parse('#escape\:needed\,') diff --git a/test/xml/test_xpath.rb b/test/xml/test_xpath.rb index f253aa5347..ea03e1d009 100644 --- a/test/xml/test_xpath.rb +++ b/test/xml/test_xpath.rb @@ -108,6 +108,14 @@ def test_node_search_with_multiple_queries assert_equal 3, node.search('.//div', 'p.blah').length end + def test_css_search_with_ambiguous_integer_or_string_attributes + # https://github.com/sparklemotion/nokogiri/issues/711 + html = "

" + doc = Nokogiri::HTML(html) + assert_not_nil doc.at_css("img[width='200']") + assert_not_nil doc.at_css("img[width=200]") + end + def test_css_search_uses_custom_selectors_with_arguments set = @xml.css('employee > address:my_filter("domestic", "Yes")', @handler) assert set.length > 0 From 3b1237792e728dd83bec2e870f963cbd889d4a7b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Feb 2018 17:56:06 -0500 Subject: [PATCH 034/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7ee79524..220233b638 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# unreleased + +## Bug fixes + +* CSS attribute selectors now gracefully handle queries using integers. [#711] + + # 1.8.2 / 2018-01-29 ## Security Notes From 52933c6310535840aa7105549fe97810e716a4a9 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Feb 2018 23:56:53 -0500 Subject: [PATCH 035/176] address minitest deprecation warnings --- test/xml/test_cdata.rb | 2 +- test/xml/test_document.rb | 10 +++++----- test/xml/test_node.rb | 12 ++++++------ test/xml/test_node_attributes.rb | 6 +++--- test/xml/test_node_set.rb | 8 ++++---- test/xml/test_reader.rb | 2 +- test/xml/test_syntax_error.rb | 6 +++--- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/test/xml/test_cdata.rb b/test/xml/test_cdata.rb index 7888f6f396..6dd8d2d0df 100644 --- a/test/xml/test_cdata.rb +++ b/test/xml/test_cdata.rb @@ -25,7 +25,7 @@ def test_new def test_new_with_nil node = CDATA.new(@xml, nil) - assert_equal nil, node.content + assert_nil node.content end def test_new_with_non_string diff --git a/test/xml/test_document.rb b/test/xml/test_document.rb index fc30d8ac42..fd748ec21c 100644 --- a/test/xml/test_document.rb +++ b/test/xml/test_document.rb @@ -69,7 +69,7 @@ def test_document_with_initial_space def test_root_set_to_nil @xml.root = nil - assert_equal nil, @xml.root + assert_nil @xml.root end def test_million_laugh_attach @@ -869,9 +869,9 @@ def test_remove_namespaces assert_equal 1, doc.xpath("//x:foo", "x" => "http://c.flavorjon.es/").length assert_match %r{foo c:attr}, doc.to_xml doc.at_xpath("//x:foo", "x" => "http://c.flavorjon.es/").tap do |node| - assert_equal nil, node["attr"] + assert_nil node["attr"] assert_equal "attr-value", node["c:attr"] - assert_equal nil, node.attribute_with_ns("attr", nil) + assert_nil node.attribute_with_ns("attr", nil) assert_equal "attr-value", node.attribute_with_ns("attr", "http://c.flavorjon.es/").value assert_equal "attr-value", node.attributes["attr"].value end @@ -887,9 +887,9 @@ def test_remove_namespaces assert_match %r{foo attr}, doc.to_xml doc.at_xpath("//container/foo").tap do |node| assert_equal "attr-value", node["attr"] - assert_equal nil, node["c:attr"] + assert_nil node["c:attr"] assert_equal "attr-value", node.attribute_with_ns("attr", nil).value - assert_equal nil, node.attribute_with_ns("attr", "http://c.flavorjon.es/") + assert_nil node.attribute_with_ns("attr", "http://c.flavorjon.es/") assert_equal "attr-value", node.attributes["attr"].value # doesn't change! end end diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index e14d9ce0a6..c19b9a6676 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -1054,15 +1054,15 @@ def test_namespace assert_equal 'http://bar.com/', set[1].namespace.href assert_equal "c", set[2].namespace.prefix assert_equal 'http://bazz.com/', set[2].namespace.href - assert_equal nil, set[3].namespace.prefix # default namespace + assert_nil set[3].namespace.prefix # default namespace assert_equal 'http://ns.example.com/d', set[3].namespace.href - assert_equal nil, set[4].namespace # no namespace + assert_nil set[4].namespace # no namespace assert_equal 'b', set[2].attributes['y'].namespace.prefix assert_equal 'http://bar.com/', set[2].attributes['y'].namespace.href - assert_equal nil, set[2].attributes['x'].namespace - assert_equal nil, set[3].attributes['x'].namespace - assert_equal nil, set[4].attributes['x'].namespace + assert_nil set[2].attributes['x'].namespace + assert_nil set[3].attributes['x'].namespace + assert_nil set[4].attributes['x'].namespace end if Nokogiri.uses_libxml? @@ -1076,7 +1076,7 @@ def test_namespace_without_an_href_on_html_node assert_equal 1, node.namespaces.keys.size assert node.namespaces.has_key?('xmlns:o') - assert_equal nil, node.namespaces['xmlns:o'] + assert_nil node.namespaces['xmlns:o'] end end diff --git a/test/xml/test_node_attributes.rb b/test/xml/test_node_attributes.rb index 030d53d62c..efe8813724 100644 --- a/test/xml/test_node_attributes.rb +++ b/test/xml/test_node_attributes.rb @@ -23,7 +23,7 @@ def test_prefixed_attributes assert_equal 'en-GB', node['xml:lang'] assert_equal 'en-GB', node.attributes['lang'].value - assert_equal nil, node['lang'] + assert_nil node['lang'] end def test_unknown_namespace_prefix_should_not_be_removed @@ -42,12 +42,12 @@ def test_set_prefixed_attributes assert_equal 'en-GB', node['xml:lang'] assert_equal 'en-GB', node.attributes['lang'].value - assert_equal nil, node['lang'] + assert_nil node['lang'] assert_equal 'http://www.w3.org/XML/1998/namespace', node.attributes['lang'].namespace.href assert_equal 'bazz', node['foo:bar'] assert_equal 'bazz', node.attributes['bar'].value - assert_equal nil, node['bar'] + assert_nil node['bar'] assert_equal 'x', node.attributes['bar'].namespace.href end diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index db7cf23fde..46babd40bb 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -408,7 +408,7 @@ def test_delete_when_not_present def test_delete_on_empty_set empty_set = Nokogiri::XML::NodeSet.new @xml, [] employee = @xml.at_xpath("//employee") - assert_equal nil, empty_set.delete(employee) + assert_nil empty_set.delete(employee) end def test_unlink @@ -573,9 +573,9 @@ def test_slice_too_far def test_slice_on_empty_node_set empty_set = Nokogiri::XML::NodeSet.new @xml, [] - assert_equal nil, empty_set[99] - assert_equal nil, empty_set[99..101] - assert_equal nil, empty_set[99,2] + assert_nil empty_set[99] + assert_nil empty_set[99..101] + assert_nil empty_set[99,2] end def test_slice_waaaaaay_off_the_end diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb index afc292232e..c3a12b3f0f 100644 --- a/test/xml/test_reader.rb +++ b/test/xml/test_reader.rb @@ -601,7 +601,7 @@ def test_nonexistent_attribute reader = Nokogiri::XML::Reader("") reader.read # root reader.read # el - assert_equal nil, reader.attribute('other') + assert_nil reader.attribute('other') end end end diff --git a/test/xml/test_syntax_error.rb b/test/xml/test_syntax_error.rb index 31a57db9d2..91df9784f7 100644 --- a/test/xml/test_syntax_error.rb +++ b/test/xml/test_syntax_error.rb @@ -27,9 +27,9 @@ def test_line_column_level_jruby error = bad_doc.errors.first assert_equal "The element type \"root\" must be terminated by the matching end-tag \"\".", error.message - assert_equal nil, error.line - assert_equal nil, error.column - assert_equal nil, error.level + assert_nil error.line + assert_nil error.column + assert_nil error.level end end end From 45d36fa9f38c965c1a291f85b988f19bd6c3baed Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 18 Feb 2018 15:03:46 -0500 Subject: [PATCH 036/176] travis: stop notifying the irc channel [skip ci] --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 625d00b198..587b4e509c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,15 +47,15 @@ matrix: - rvm: ruby-head fast_finish: true -notifications: - irc: - channels: - - "chat.freenode.net#nokogiri" - on_success: always - on_failure: always - template: - - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})" - skip_join: true +# notifications: +# irc: +# channels: +# - "chat.freenode.net#nokogiri" +# on_success: always +# on_failure: always +# template: +# - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})" +# skip_join: true addons: apt: From 7539b14a75bd6c3599705c25b120387de5e72099 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 19 Feb 2018 16:02:49 -0800 Subject: [PATCH 037/176] Handle ASCII-8BIT encoding on fragment input If we don't know the encoding, we default to using UTF-8. I think this was correct behavior on 1.8, but now that Ruby is encoding aware, I think we should raise an exception if someone passes a document encoded as ASCII-8BIT. However, to remain backwards compatible, we'll just assume UTF-8 for now. Fixes #553 --- lib/nokogiri/html/document_fragment.rb | 12 +++++++++++- test/html/test_document_fragment.rb | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/nokogiri/html/document_fragment.rb b/lib/nokogiri/html/document_fragment.rb index 265f865dfd..466d0ce223 100644 --- a/lib/nokogiri/html/document_fragment.rb +++ b/lib/nokogiri/html/document_fragment.rb @@ -6,7 +6,17 @@ class DocumentFragment < Nokogiri::XML::DocumentFragment def self.parse tags, encoding = nil doc = HTML::Document.new - encoding ||= tags.respond_to?(:encoding) ? tags.encoding.name : 'UTF-8' + encoding ||= if tags.respond_to?(:encoding) + encoding = tags.encoding + if encoding == ::Encoding::ASCII_8BIT + 'UTF-8' + else + encoding.name + end + else + 'UTF-8' + end + doc.encoding = encoding new(doc, tags) diff --git a/test/html/test_document_fragment.rb b/test/html/test_document_fragment.rb index bdf999bf91..5476ffca15 100644 --- a/test/html/test_document_fragment.rb +++ b/test/html/test_document_fragment.rb @@ -9,6 +9,11 @@ def setup @html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE) end + def test_ascii_8bit_encoding + s = String.new 'hello', encoding: Encoding::ASCII_8BIT + assert_equal "hello", Nokogiri::HTML::DocumentFragment.parse(s).to_html + end + def test_inspect_encoding fragment = "
こんにちは!
".encode('EUC-JP') f = Nokogiri::HTML::DocumentFragment.parse fragment @@ -21,7 +26,7 @@ def test_html_parse_encoding assert_equal 'EUC-JP', f.document.encoding assert_equal "こんにちは!", f.content end - + def test_unlink_empty_document frag = Nokogiri::HTML::DocumentFragment.parse('').unlink # must_not_raise assert_nil frag.parent From 4f9bfd11ddb6f68cb508fefd97dbb3068f117986 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 19 Feb 2018 16:09:09 -0800 Subject: [PATCH 038/176] Minitest 6 compatibility --- test/test_css_cache.rb | 8 +++++--- test/xml/sax/test_parser.rb | 10 +++++++++- test/xml/test_dtd.rb | 8 ++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/test/test_css_cache.rb b/test/test_css_cache.rb index d8dbe2f0ce..abf321341a 100644 --- a/test/test_css_cache.rb +++ b/test/test_css_cache.rb @@ -28,8 +28,6 @@ def teardown [ false, true ].each do |cache_setting| define_method "test_css_cache_#{cache_setting ? "true" : "false"}" do - times = cache_setting ? 4 : nil - Nokogiri::CSS::Parser.set_cache cache_setting Nokogiri::CSS.xpath_for(@css) @@ -37,7 +35,11 @@ def teardown Nokogiri::CSS::Parser.new.xpath_for(@css) Nokogiri::CSS::Parser.new.xpath_for(@css) - assert_equal(times, Nokogiri::CSS::Parser.class_eval { @cache.count }) + if cache_setting + assert_equal(4, Nokogiri::CSS::Parser.class_eval { @cache.count }) + else + assert_nil(Nokogiri::CSS::Parser.class_eval { @cache.count }) + end end end diff --git a/test/xml/sax/test_parser.rb b/test/xml/sax/test_parser.rb index 8e29c5470e..c51a1131d5 100644 --- a/test/xml/sax/test_parser.rb +++ b/test/xml/sax/test_parser.rb @@ -43,9 +43,17 @@ def test_parser_context_yielded_in_memory assert_equal [['foo', [['a', '&b']]]], doc.start_elements end + def test_empty_decl + parser = XML::SAX::Parser.new(Doc.new) + + xml = "" + parser.parse xml + assert parser.document.start_document_called, xml + assert_nil parser.document.xmldecls, xml + end + def test_xml_decl [ - ['', nil], ['', ['1.0']], ['', diff --git a/test/xml/test_dtd.rb b/test/xml/test_dtd.rb index f36aef5516..93e30d62ee 100644 --- a/test/xml/test_dtd.rb +++ b/test/xml/test_dtd.rb @@ -91,14 +91,14 @@ def test_html_dtd dtd = doc.internal_subset assert_instance_of Nokogiri::XML::DTD, dtd, name if html_p - assert_send [dtd, :html_dtd?], name + assert dtd.html_dtd?, name else - assert_not_send [dtd, :html_dtd?], name + refute dtd.html_dtd?, name end if html5_p - assert_send [dtd, :html5_dtd?], name + assert dtd.html5_dtd?, name else - assert_not_send [dtd, :html5_dtd?], name + refute dtd.html5_dtd?, name end } end From a24b92e41cde36297e71a1d9612b189cbecfba38 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 19 Feb 2018 16:25:07 -0800 Subject: [PATCH 039/176] Don't SEGV if user returns a non string object Make sure the object we get back on the reader function is actually a string. If it isn't, return an error to libxml2. Fixes #898 --- ext/nokogiri/xml_io.c | 1 + test/xml/test_reader.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/ext/nokogiri/xml_io.c b/ext/nokogiri/xml_io.c index e37c7885e2..46655e4731 100644 --- a/ext/nokogiri/xml_io.c +++ b/ext/nokogiri/xml_io.c @@ -21,6 +21,7 @@ int io_read_callback(void * ctx, char * buffer, int len) { if (NIL_P(string)) return 0; if (string == Qundef) return -1; + if (TYPE(string) != T_STRING) return -1; str_len = (size_t)RSTRING_LEN(string); safe_len = str_len > (size_t)len ? (size_t)len : str_len; diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb index c3a12b3f0f..588194ac79 100644 --- a/test/xml/test_reader.rb +++ b/test/xml/test_reader.rb @@ -4,6 +4,18 @@ module Nokogiri module XML class TestReader < Nokogiri::TestCase + class NonStringIO + def read(size) + :invalid_object + end + end + + def test_io_non_string + io = NonStringIO.new + reader = Nokogiri::XML::Reader(io) + assert_equal io, reader.source + end + def test_from_io_sets_io_as_source io = File.open SNUGGLES_FILE reader = Nokogiri::XML::Reader.from_io(io) From 462129853a1f93f01914017ddaea3734746dd823 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 21 Feb 2018 08:56:54 +0100 Subject: [PATCH 040/176] [ci] bump JRuby 9K to latest and greatest atm: 9.1.15.0 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 625d00b198..8d10dda08a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ matrix: - os: linux rvm: jruby-1.7 - os: linux - rvm: jruby-9.1.5.0 + rvm: jruby-9.1.15.0 - os: linux rvm: rbx-3 allow_failures: From 2d4e56efa93e6de442219b2ab74751467c4300f9 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 21 Feb 2018 09:10:03 +0100 Subject: [PATCH 041/176] [build] these (1.8/1.9 JRuby mode) tasks are no longer used --- Rakefile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Rakefile b/Rakefile index 3440cadfa7..467f880530 100644 --- a/Rakefile +++ b/Rakefile @@ -292,14 +292,6 @@ task :java_debug do ENV['JAVA_OPTS'] = '-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y' if ENV['JAVA_DEBUG'] end -if java? - task :test_19 => :test - task :test_20 do - ENV['JRUBY_OPTS'] = "--2.0" - Rake::Task["test"].invoke - end -end - Rake::Task[:test].prerequisites << :compile Rake::Task[:test].prerequisites << :java_debug Rake::Task[:test].prerequisites << :check_extra_deps unless java? From 71bd4be7f32e3ea00191cfd112fbeb32de6b1077 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 21 Feb 2018 09:09:30 +0100 Subject: [PATCH 042/176] [fix] avoid potential (legacy) issues booting on newer JRubies see #1720 where JRuby (head) 9.2 had to work around 1.8 compat mode ... this is safe todo since require_ruby_version >= 1.9.3 (no 1.8 support) --- ext/java/nokogiri/XmlSyntaxError.java | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/ext/java/nokogiri/XmlSyntaxError.java b/ext/java/nokogiri/XmlSyntaxError.java index f65d8fe04c..feb0852b72 100644 --- a/ext/java/nokogiri/XmlSyntaxError.java +++ b/ext/java/nokogiri/XmlSyntaxError.java @@ -34,10 +34,10 @@ import static nokogiri.internals.NokogiriHelpers.stringOrNil; -import org.jruby.CompatVersion; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyException; +import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ThreadContext; @@ -120,26 +120,18 @@ public void setException(Ruby runtime, SAXParseException exception, int level) { setInstanceVariable("@file", stringOrNil(runtime, exception.getSystemId())); } - //@Override - //"to_s" method was branched in 1.8 and 1.9 since JRuby 1.6.6 - // to support older version of JRuby, the annotation is commented out + // NOTE: special care - due JRuby 1.7.x + @Override - @JRubyMethod(name = "to_s", compat = CompatVersion.RUBY1_8) - public IRubyObject to_s(ThreadContext context) { - IRubyObject msg = msg(context.runtime); - return msg != null ? msg : super.to_s(context); - } + public IRubyObject to_s(ThreadContext context) { return to_s19(context); } - //@Override - //"to_s" method was branched in 1.8 and 1.9 since JRuby 1.6.6 - // to support older version of JRuby, the annotation is commented out - @JRubyMethod(name = "to_s", compat = CompatVersion.RUBY1_9) - public IRubyObject to_s19(ThreadContext context) { - IRubyObject msg = msg(context.runtime); - return msg != null ? msg : super.to_s19(context); + @JRubyMethod(name = "to_s") + public RubyString to_s19(ThreadContext context) { + RubyString msg = msg(context.runtime); + return msg != null ? msg : super.to_s(context).asString(); } - private IRubyObject msg(final Ruby runtime) { + private RubyString msg(final Ruby runtime) { if (exception != null && exception.getMessage() != null) { if (messageSet) return null; return runtime.newString( exception.getMessage() ); From d70985d97b82f28a421d1403ff5f552610643f28 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sat, 24 Feb 2018 15:36:01 -0600 Subject: [PATCH 043/176] Older Ruby's don't have `encoding` on String constructor Support older Ruby's in test --- test/html/test_document_fragment.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/html/test_document_fragment.rb b/test/html/test_document_fragment.rb index 5476ffca15..3a85740b42 100644 --- a/test/html/test_document_fragment.rb +++ b/test/html/test_document_fragment.rb @@ -10,7 +10,8 @@ def setup end def test_ascii_8bit_encoding - s = String.new 'hello', encoding: Encoding::ASCII_8BIT + s = String.new 'hello' + s.force_encoding ::Encoding::ASCII_8BIT assert_equal "hello", Nokogiri::HTML::DocumentFragment.parse(s).to_html end From f59e4af5148f6592a4590a2d0b416836094a7df2 Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 09:11:09 +0100 Subject: [PATCH 044/176] simplify/dry-up ext internals around (JRuby's) sax-parser --- ext/java/nokogiri/HtmlSaxParserContext.java | 20 +-- ext/java/nokogiri/HtmlSaxPushParser.java | 4 +- ext/java/nokogiri/XmlSaxParserContext.java | 148 ++++++++---------- .../nokogiri/internals/NokogiriHelpers.java | 17 +- 4 files changed, 83 insertions(+), 106 deletions(-) diff --git a/ext/java/nokogiri/HtmlSaxParserContext.java b/ext/java/nokogiri/HtmlSaxParserContext.java index 93ae6b63ed..2fa4ee71c5 100644 --- a/ext/java/nokogiri/HtmlSaxParserContext.java +++ b/ext/java/nokogiri/HtmlSaxParserContext.java @@ -223,30 +223,24 @@ public static IRubyObject parse_io(ThreadContext context, } /** - * Create a new parser context that will read from a raw input - * stream. Not a JRuby method. Meant to be run in a separate - * thread by HtmlSaxPushParser. + * Create a new parser context that will read from a raw input stream. + * Meant to be run in a separate thread by HtmlSaxPushParser. */ - public static IRubyObject parse_stream(ThreadContext context, - IRubyObject klazz, - InputStream stream) { - HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz); - ctx.initialize(context.getRuntime()); + static HtmlSaxParserContext parse_stream(final Ruby runtime, RubyClass klazz, InputStream stream) { + HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(runtime, klazz); + ctx.initialize(runtime); ctx.setInputSource(stream); return ctx; } @Override - protected void preParse(ThreadContext context, - IRubyObject handlerRuby, - NokogiriHandler handler) { + protected void preParse(final Ruby runtime, IRubyObject handlerRuby, NokogiriHandler handler) { // final String path = "Nokogiri::XML::FragmentHandler"; // final String docFrag = // "http://cyberneko.org/html/features/balance-tags/document-fragment"; // RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter(); // IRubyObject doc = adapter.getInstanceVariable(handlerRuby, "@document"); - // RubyModule mod = - // context.getRuntime().getClassFromPath(path); + // RubyModule mod = runtime.getClassFromPath(path); // try { // if (doc != null && !doc.isNil() && adapter.isKindOf(doc, mod)) // parser.setFeature(docFrag, true); diff --git a/ext/java/nokogiri/HtmlSaxPushParser.java b/ext/java/nokogiri/HtmlSaxPushParser.java index 0653d38757..cee6ac0d07 100644 --- a/ext/java/nokogiri/HtmlSaxPushParser.java +++ b/ext/java/nokogiri/HtmlSaxPushParser.java @@ -209,10 +209,10 @@ private class ParserTask implements Callable { private final HtmlSaxParserContext parser; private ParserTask(ThreadContext context, IRubyObject handler) { - RubyClass klazz = getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::SAX::ParserContext"); + RubyClass klazz = getNokogiriClass(context.runtime, "Nokogiri::HTML::SAX::ParserContext"); this.context = context; this.handler = handler; - this.parser = (HtmlSaxParserContext) HtmlSaxParserContext.parse_stream(context, klazz, stream); + this.parser = HtmlSaxParserContext.parse_stream(context.runtime, klazz, stream); } @Override diff --git a/ext/java/nokogiri/XmlSaxParserContext.java b/ext/java/nokogiri/XmlSaxParserContext.java index addf113289..dbdcd90b89 100644 --- a/ext/java/nokogiri/XmlSaxParserContext.java +++ b/ext/java/nokogiri/XmlSaxParserContext.java @@ -80,20 +80,19 @@ public class XmlSaxParserContext extends ParserContext { protected AbstractSAXParser parser; - protected NokogiriHandler handler = null; - private IRubyObject replaceEntities; - private IRubyObject recovery; + protected NokogiriHandler handler; + private boolean replaceEntities = true; + private boolean recovery = false; public XmlSaxParserContext(final Ruby ruby, RubyClass rubyClass) { super(ruby, rubyClass); } protected void initialize(Ruby runtime) { - replaceEntities = runtime.getTrue(); - recovery = runtime.getFalse(); try { parser = createParser(); - } catch (SAXException se) { + } + catch (SAXException se) { throw RaiseException.createNativeRaiseException(runtime, se); } } @@ -123,9 +122,10 @@ protected AbstractSAXParser createParser() throws SAXException { public static IRubyObject parse_memory(ThreadContext context, IRubyObject klazz, IRubyObject data) { - XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz); - ctx.initialize(context.getRuntime()); - ctx.setInputSource(context, data, context.getRuntime().getNil()); + final Ruby runtime = context.runtime; + XmlSaxParserContext ctx = newInstance(runtime, (RubyClass) klazz); + ctx.initialize(runtime); + ctx.setInputSource(context, data, runtime.getNil()); return ctx; } @@ -137,7 +137,8 @@ public static IRubyObject parse_memory(ThreadContext context, public static IRubyObject parse_file(ThreadContext context, IRubyObject klazz, IRubyObject data) { - XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz); + final Ruby runtime = context.runtime; + XmlSaxParserContext ctx = newInstance(runtime, (RubyClass) klazz); ctx.initialize(context.getRuntime()); ctx.setInputSourceFile(context, data); return ctx; @@ -155,9 +156,10 @@ public static IRubyObject parse_io(ThreadContext context, IRubyObject data, IRubyObject enc) { //int encoding = (int)enc.convertToInteger().getLongValue(); - XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz); - ctx.initialize(context.getRuntime()); - ctx.setInputSource(context, data, context.getRuntime().getNil()); + final Ruby runtime = context.runtime; + XmlSaxParserContext ctx = newInstance(runtime, (RubyClass) klazz); + ctx.initialize(runtime); + ctx.setInputSource(context, data, runtime.getNil()); return ctx; } @@ -169,12 +171,17 @@ public static IRubyObject parse_io(ThreadContext context, public static IRubyObject parse_stream(ThreadContext context, IRubyObject klazz, InputStream stream) { - XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz); - ctx.initialize(context.getRuntime()); + final Ruby runtime = context.runtime; + XmlSaxParserContext ctx = newInstance(runtime, (RubyClass) klazz); + ctx.initialize(runtime); ctx.setInputSource(stream); return ctx; } + private static XmlSaxParserContext newInstance(final Ruby runtime, final RubyClass klazz) { + return (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(runtime, klazz); + } + /** * Set a property of the underlying parser. */ @@ -199,22 +206,19 @@ public NokogiriHandler getNokogiriHandler() { * Perform any initialization prior to parsing with the handler * handlerRuby. Convenience hook for subclasses. */ - protected void preParse(ThreadContext context, - IRubyObject handlerRuby, - NokogiriHandler handler) { + protected void preParse(Ruby runtime, IRubyObject handlerRuby, NokogiriHandler handler) { ((XmlSaxParser) parser).setXmlDeclHandler(handler); - if(recovery.isTrue()) { - try { - ((XmlSaxParser) parser).setFeature(FEATURE_CONTINUE_AFTER_FATAL_ERROR, true); - } catch(Exception e) { - throw RaiseException.createNativeRaiseException(context.getRuntime(), e); - } + if (recovery) { + try { + parser.setFeature(FEATURE_CONTINUE_AFTER_FATAL_ERROR, true); + } + catch (Exception e) { + throw RaiseException.createNativeRaiseException(runtime, e); + } } } - protected void postParse(ThreadContext context, - IRubyObject handlerRuby, - NokogiriHandler handler) { + protected void postParse(Ruby runtime, IRubyObject handlerRuby, NokogiriHandler handler) { // noop } @@ -223,34 +227,31 @@ protected void do_parse() throws SAXException, IOException { } @JRubyMethod - public IRubyObject parse_with(ThreadContext context, - IRubyObject handlerRuby) { - Ruby ruby = context.getRuntime(); - - if(!invoke(context, handlerRuby, "respond_to?", - ruby.newSymbol("document")).isTrue()) { - String msg = "argument must respond_to document"; - throw ruby.newArgumentError(msg); + public IRubyObject parse_with(ThreadContext context, IRubyObject handlerRuby) { + final Ruby runtime = context.getRuntime(); + + if(!invoke(context, handlerRuby, "respond_to?", runtime.newSymbol("document")).isTrue()) { + throw runtime.newArgumentError("argument must respond_to document"); } - handler = new NokogiriHandler(ruby, handlerRuby); - preParse(context, handlerRuby, handler); + NokogiriHandler handler = this.handler = new NokogiriHandler(runtime, handlerRuby); + preParse(runtime, handlerRuby, handler); setContentHandler(handler); setErrorHandler(handler); try{ - setProperty("http://xml.org/sax/properties/lexical-handler", - handler); - } catch(Exception ex) { - throw ruby.newRuntimeError( - "Problem while creating XML SAX Parser: " + ex.toString()); + setProperty("http://xml.org/sax/properties/lexical-handler", handler); + } + catch (Exception ex) { + throw runtime.newRuntimeError("Problem while creating XML SAX Parser: " + ex.toString()); } try{ try { do_parse(); - } catch(SAXParseException spe) { + } + catch (SAXParseException spe) { // A bad document () should call the // error handler instead of raising a SAX exception. @@ -260,24 +261,23 @@ public IRubyObject parse_with(ThreadContext context, // Nokogiri does. String message = spe.getMessage(); if ("Premature end of file.".matches(message) && stringDataSize < 1) { - throw ruby.newRuntimeError( - "couldn't parse document: " + message); - } else { - handler.error(spe); + throw runtime.newRuntimeError("couldn't parse document: " + message); } - + handler.error(spe); } - } catch(SAXException se) { - throw RaiseException.createNativeRaiseException(ruby, se); - } catch(IOException ioe) { - throw ruby.newIOErrorFromException(ioe); + } + catch (SAXException se) { + throw RaiseException.createNativeRaiseException(runtime, se); + } + catch (IOException ioe) { + throw runtime.newIOErrorFromException(ioe); } - postParse(context, handlerRuby, handler); + postParse(runtime, handlerRuby, handler); //maybeTrimLeadingAndTrailingWhitespace(context, handlerRuby); - return ruby.getNil(); + return runtime.getNil(); } /** @@ -288,17 +288,14 @@ public IRubyObject parse_with(ThreadContext context, * @return */ @JRubyMethod(name = "replace_entities=") - public IRubyObject set_replace_entities(ThreadContext context, - IRubyObject value) { - if (!value.isTrue()) replaceEntities = context.getRuntime().getFalse(); - else replaceEntities = context.getRuntime().getTrue(); - + public IRubyObject set_replace_entities(ThreadContext context, IRubyObject value) { + replaceEntities = value.isTrue(); return this; } @JRubyMethod(name="replace_entities") public IRubyObject get_replace_entities(ThreadContext context) { - return replaceEntities; + return context.runtime.newBoolean(replaceEntities); } /** @@ -309,21 +306,16 @@ public IRubyObject get_replace_entities(ThreadContext context) { * @return */ @JRubyMethod(name = "recovery=") - public IRubyObject set_recovery(ThreadContext context, - IRubyObject value) { - if (!value.isTrue()) recovery = context.getRuntime().getFalse(); - else recovery = context.getRuntime().getTrue(); - + public IRubyObject set_recovery(ThreadContext context, IRubyObject value) { + recovery = value.isTrue(); return this; } @JRubyMethod(name="recovery") public IRubyObject get_recovery(ThreadContext context) { - return recovery; + return context.runtime.newBoolean(recovery); } - - /** * If the handler's document is a FragmentHandler, attempt to trim * leading and trailing whitespace. @@ -331,12 +323,9 @@ public IRubyObject get_recovery(ThreadContext context) { * This is a bit hackish and depends heavily on the internals of * FragmentHandler. */ - protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, - IRubyObject parser) { - final String path = "Nokogiri::XML::FragmentHandler"; + protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, IRubyObject parser) { RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter(); - RubyModule mod = - context.getRuntime().getClassFromPath(path); + RubyModule mod = context.getRuntime().getClassFromPath("Nokogiri::XML::FragmentHandler"); IRubyObject handler = adapter.getInstanceVariable(parser, "@document"); if (handler == null || handler.isNil() || !adapter.isKindOf(handler, mod)) @@ -354,7 +343,7 @@ protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, for (;;) { children = adapter.callMethod(doc, "children"); IRubyObject first = adapter.callMethod(children, "first"); - if (isWhitespaceText(context, first)) + if (isWhitespaceText(first)) adapter.callMethod(first, "unlink"); else break; @@ -363,7 +352,7 @@ protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, for (;;) { children = adapter.callMethod(doc, "children"); IRubyObject last = adapter.callMethod(children, "last"); - if (isWhitespaceText(context, last)) + if (isWhitespaceText(last)) adapter.callMethod(last, "unlink"); else break; @@ -375,15 +364,16 @@ protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, @JRubyMethod(name="column") public IRubyObject column(ThreadContext context) { - Integer number = handler.getColumn(); + final Integer number = handler.getColumn(); if (number == null) return context.getRuntime().getNil(); - else return RubyFixnum.newFixnum(context.getRuntime(), number.longValue()); + return RubyFixnum.newFixnum(context.getRuntime(), number.longValue()); } @JRubyMethod(name="line") public IRubyObject line(ThreadContext context) { - Integer number = handler.getLine(); + final Integer number = handler.getLine(); if (number == null) return context.getRuntime().getNil(); - else return RubyFixnum.newFixnum(context.getRuntime(), number.longValue()); + return RubyFixnum.newFixnum(context.getRuntime(), number.longValue()); } + } diff --git a/ext/java/nokogiri/internals/NokogiriHelpers.java b/ext/java/nokogiri/internals/NokogiriHelpers.java index 5376b80ec8..542fb1326c 100644 --- a/ext/java/nokogiri/internals/NokogiriHelpers.java +++ b/ext/java/nokogiri/internals/NokogiriHelpers.java @@ -229,11 +229,8 @@ public static IRubyObject nonEmptyStringOrNil(Ruby runtime, String s) { public static String getPrefix(String qName) { if (qName == null) return null; - int pos = qName.indexOf(':'); - if (pos > 0) - return qName.substring(0, pos); - else - return null; + final int pos = qName.indexOf(':'); + return pos > 0 ? qName.substring(0, pos) : null; } /** @@ -243,11 +240,8 @@ public static String getPrefix(String qName) { public static String getLocalPart(String qName) { if (qName == null) return null; - int pos = qName.indexOf(':'); - if (pos > 0) - return qName.substring(pos + 1); - else - return qName; + final int pos = qName.indexOf(':'); + return pos > 0 ? qName.substring(pos + 1) : qName; } public static String getLocalNameForNamespace(String name) { @@ -593,8 +587,7 @@ public static boolean isXmlBase(String attrName) { return "xml:base".equals(attrName) || "xlink:href".equals(attrName); } - public static boolean isWhitespaceText(ThreadContext context, IRubyObject obj) { - //if (obj == null || obj.isNil()) return false; + public static boolean isWhitespaceText(IRubyObject obj) { if ( !(obj instanceof XmlText) ) return false; CharSequence content = ((XmlNode) obj).getContentImpl(); From d6a2d8506bc30dd8681e9830b0da1acd8a983986 Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 09:36:59 +0100 Subject: [PATCH 045/176] rename isWhitespaceTest to isBlank and add (String str) version --- ext/java/nokogiri/XmlSaxParserContext.java | 14 +++++--------- ext/java/nokogiri/internals/NokogiriHelpers.java | 10 +++++++--- .../nokogiri/internals/SaveContextVisitor.java | 7 ++++--- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ext/java/nokogiri/XmlSaxParserContext.java b/ext/java/nokogiri/XmlSaxParserContext.java index dbdcd90b89..e7f0f1c79a 100644 --- a/ext/java/nokogiri/XmlSaxParserContext.java +++ b/ext/java/nokogiri/XmlSaxParserContext.java @@ -32,13 +32,13 @@ package nokogiri; -import static nokogiri.internals.NokogiriHelpers.isWhitespaceText; import static org.jruby.javasupport.util.RuntimeHelpers.invoke; import java.io.IOException; import java.io.InputStream; import nokogiri.internals.NokogiriHandler; +import nokogiri.internals.NokogiriHelpers; import nokogiri.internals.ParserContext; import nokogiri.internals.XmlSaxParser; @@ -343,19 +343,15 @@ protected void maybeTrimLeadingAndTrailingWhitespace(ThreadContext context, IRub for (;;) { children = adapter.callMethod(doc, "children"); IRubyObject first = adapter.callMethod(children, "first"); - if (isWhitespaceText(first)) - adapter.callMethod(first, "unlink"); - else - break; + if (NokogiriHelpers.isBlank(first)) adapter.callMethod(first, "unlink"); + else break; } for (;;) { children = adapter.callMethod(doc, "children"); IRubyObject last = adapter.callMethod(children, "last"); - if (isWhitespaceText(last)) - adapter.callMethod(last, "unlink"); - else - break; + if (NokogiriHelpers.isBlank(last)) adapter.callMethod(last, "unlink"); + else break; } // While we have a document, normalize it. diff --git a/ext/java/nokogiri/internals/NokogiriHelpers.java b/ext/java/nokogiri/internals/NokogiriHelpers.java index 542fb1326c..5487d40843 100644 --- a/ext/java/nokogiri/internals/NokogiriHelpers.java +++ b/ext/java/nokogiri/internals/NokogiriHelpers.java @@ -587,19 +587,23 @@ public static boolean isXmlBase(String attrName) { return "xml:base".equals(attrName) || "xlink:href".equals(attrName); } - public static boolean isWhitespaceText(IRubyObject obj) { + public static boolean isBlank(IRubyObject obj) { if ( !(obj instanceof XmlText) ) return false; CharSequence content = ((XmlNode) obj).getContentImpl(); - return content == null || isWhitespaceText(content); + return content == null || isBlank(content); } - public static boolean isWhitespaceText(CharSequence str) { + public static boolean isBlank(CharSequence str) { int len = str.length(); int beg = 0; while ((beg < len) && (str.charAt(beg) <= ' ')) beg++; return beg == len; } + public static boolean isBlank(String str) { + return str.isEmpty() || isBlank((CharSequence) str); + } + public static CharSequence canonicalizeWhitespace(CharSequence str) { final int len = str.length(); StringBuilder sb = new StringBuilder(len); diff --git a/ext/java/nokogiri/internals/SaveContextVisitor.java b/ext/java/nokogiri/internals/SaveContextVisitor.java index 085134c88e..ba7be98ceb 100644 --- a/ext/java/nokogiri/internals/SaveContextVisitor.java +++ b/ext/java/nokogiri/internals/SaveContextVisitor.java @@ -35,7 +35,8 @@ import static nokogiri.internals.NokogiriHelpers.canonicalizeWhitespace; import static nokogiri.internals.NokogiriHelpers.encodeJavaString; import static nokogiri.internals.NokogiriHelpers.isNamespace; -import static nokogiri.internals.NokogiriHelpers.isWhitespaceText; +import static nokogiri.internals.NokogiriHelpers.isBlank; +import static nokogiri.internals.NokogiriHelpers.shouldEncode; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; @@ -737,13 +738,13 @@ public boolean enter(Text text) { CharSequence textContent = text.getNodeValue(); if (canonical) { c14nNodeList.add(text); - if (isWhitespaceText(textContent)) { + if (isBlank(textContent)) { buffer.append(canonicalizeWhitespace(textContent)); return true; } } - if (NokogiriHelpers.shouldEncode(text) && !isHtmlScript(text) && !isHtmlStyle(text)) { + if (shouldEncode(text) && !isHtmlScript(text) && !isHtmlStyle(text)) { textContent = encodeJavaString(textContent); } From c30b0e3291923f08fdf285628bf762a3327881da Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 11:00:12 +0100 Subject: [PATCH 046/176] avoid trim()-ing (in mem string copy-ing) to test for blank text --- ext/java/nokogiri/XmlNode.java | 14 ++------------ ext/java/nokogiri/internals/ReaderNode.java | 16 ++++++---------- .../nokogiri/internals/XmlDomParserContext.java | 3 ++- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index f4a2e95d6c..508da09eb8 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -33,21 +33,11 @@ package nokogiri; import static java.lang.Math.max; -import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate; -import static nokogiri.internals.NokogiriHelpers.clearCachedNode; -import static nokogiri.internals.NokogiriHelpers.clearXpathContext; -import static nokogiri.internals.NokogiriHelpers.convertEncoding; -import static nokogiri.internals.NokogiriHelpers.convertString; -import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; -import static nokogiri.internals.NokogiriHelpers.nodeArrayToRubyArray; -import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil; -import static nokogiri.internals.NokogiriHelpers.rubyStringToString; -import static nokogiri.internals.NokogiriHelpers.stringOrNil; +import static nokogiri.internals.NokogiriHelpers.*; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.ByteBuffer; -import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Iterator; @@ -696,7 +686,7 @@ public IRubyObject blank_p(ThreadContext context) { // a node is blank if if it is a Text or CDATA node consisting of whitespace only if (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) { String data = node.getTextContent(); - return context.runtime.newBoolean(data == null || data.isEmpty() || data.trim().isEmpty()); + return context.runtime.newBoolean(data == null || isBlank(data)); } return context.runtime.getFalse(); } diff --git a/ext/java/nokogiri/internals/ReaderNode.java b/ext/java/nokogiri/internals/ReaderNode.java index d47e140aaa..8fb6b403db 100644 --- a/ext/java/nokogiri/internals/ReaderNode.java +++ b/ext/java/nokogiri/internals/ReaderNode.java @@ -32,13 +32,6 @@ package nokogiri.internals; -import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; -import static nokogiri.internals.NokogiriHelpers.isNamespace; -import static nokogiri.internals.NokogiriHelpers.isXmlBase; -import static nokogiri.internals.NokogiriHelpers.rubyStringToString; -import static nokogiri.internals.NokogiriHelpers.stringOrBlank; -import static nokogiri.internals.NokogiriHelpers.stringOrNil; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -61,6 +54,8 @@ import org.w3c.dom.Attr; import org.w3c.dom.Document; +import static nokogiri.internals.NokogiriHelpers.*; + /** * Abstract class of Node for XmlReader. * @@ -263,7 +258,7 @@ public static class ClosingNode extends ReaderNode { super(runtime); nodeType = ReaderNodeType.END_ELEMENT.getValue(); this.uri = "".equals(uri) ? null : uri; - this.localName = localName.trim().length() > 0 ? localName : qName; + this.localName = ! isBlank(localName) ? localName : qName; this.name = qName; parsePrefix(qName); this.depth = depth; @@ -299,7 +294,7 @@ public static class ElementNode extends ReaderNode { super(runtime); this.nodeType = ReaderNodeType.ELEMENT.getValue(); this.uri = "".equals(uri) ? null : uri; - this.localName = localName.trim().length() > 0 ? localName : qName; + this.localName = ! isBlank(localName) ? localName : qName; this.name = qName; parsePrefix(qName); this.depth = depth; @@ -475,7 +470,7 @@ public static class TextNode extends ReaderNode { this.localName = "#text"; this.name = "#text"; this.depth = depth; - if (content.trim().length() > 0) nodeType = ReaderNodeType.TEXT.getValue(); + if (!isBlank(content)) nodeType = ReaderNodeType.TEXT.getValue(); else nodeType = ReaderNodeType.SIGNIFICANT_WHITESPACE.getValue(); if (!langStack.isEmpty()) this.lang = langStack.peek(); if (!xmlBaseStack.isEmpty()) this.xmlBase = xmlBaseStack.peek(); @@ -491,4 +486,5 @@ public String getString() { return value; } } + } diff --git a/ext/java/nokogiri/internals/XmlDomParserContext.java b/ext/java/nokogiri/internals/XmlDomParserContext.java index f208892c1d..b9782073d1 100644 --- a/ext/java/nokogiri/internals/XmlDomParserContext.java +++ b/ext/java/nokogiri/internals/XmlDomParserContext.java @@ -33,6 +33,7 @@ package nokogiri.internals; import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; +import static nokogiri.internals.NokogiriHelpers.isBlank; import java.io.IOException; import java.util.ArrayList; @@ -274,7 +275,7 @@ protected Document do_parse() throws SAXException, IOException { } private static void findEmptyTexts(Node node, List emptyNodes) { - if (node.getNodeType() == Node.TEXT_NODE && "".equals(node.getTextContent().trim())) { + if (node.getNodeType() == Node.TEXT_NODE && isBlank(node.getTextContent())) { emptyNodes.add(node); } else { NodeList children = node.getChildNodes(); From 9851ce9ecdcd5be0d42e4a085f8cc34161572c90 Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 11:00:57 +0100 Subject: [PATCH 047/176] avoid trim() - skip ending empty chars from builder directly --- ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java b/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java index 94873993b4..467b62f8e2 100644 --- a/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +++ b/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java @@ -75,7 +75,7 @@ public InclusiveNamespaces(Document doc, Set prefixes) { prefixList = new TreeSet(prefixes); } - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(prefixList.size() * 8); for (String prefix : prefixList) { if (prefix.equals("xmlns")) { sb.append("#default "); @@ -83,9 +83,10 @@ public InclusiveNamespaces(Document doc, Set prefixes) { sb.append(prefix).append(' '); } } + int last = sb.length() - 1; + while (last >= 0 && sb.charAt(last) == ' ') sb.setLength(last--); // trim - this.constructionElement.setAttributeNS( - null, InclusiveNamespaces._ATT_EC_PREFIXLIST, sb.toString().trim()); + this.constructionElement.setAttributeNS(null, InclusiveNamespaces._ATT_EC_PREFIXLIST, sb.toString()); } /** From da315afd7df4fc1cd4c7cbf4a48b59f16116ce0e Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 12:37:47 +0100 Subject: [PATCH 048/176] handle unavailable (-1) line/column as nil + use set for empty attr check --- ext/java/nokogiri/XmlSaxPushParser.java | 10 +- .../nokogiri/internals/NokogiriHandler.java | 92 ++++++++----------- 2 files changed, 39 insertions(+), 63 deletions(-) diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index 4616482868..0cb759d05d 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -167,14 +167,8 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } if (isLast.isTrue()) { - try { - parserTask.parser.getNokogiriHandler().endDocument(); - } - catch (SAXException e) { - throw context.runtime.newRuntimeError(e.getMessage()); - } finally { - terminateTask(context); - } + parserTask.parser.getNokogiriHandler().endDocument(); + terminateTask(context); } if (!options.recover && parserTask.getErrorCount() > errorCount0) { diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 823f877191..7e55d38529 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -37,7 +37,10 @@ import static nokogiri.internals.NokogiriHelpers.isNamespace; import static nokogiri.internals.NokogiriHelpers.stringOrNil; +import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedList; +import java.util.Set; import nokogiri.XmlSyntaxError; @@ -98,7 +101,7 @@ public void setDocumentLocator(Locator locator) { } @Override - public void startDocument() throws SAXException { + public void startDocument() { call("start_document"); charactersBuilder = new StringBuilder(); } @@ -111,7 +114,7 @@ public void xmlDecl(String version, String encoding, String standalone) { } @Override - public void endDocument() throws SAXException { + public void endDocument() { populateCharacters(); call("end_document"); } @@ -146,7 +149,7 @@ public void startElement(String uri, String localName, String qName, Attributes String pre; pre = getPrefix(qn); - if (ln == null || ln.equals("")) ln = getLocalPart(qn); + if (ln == null || ln.isEmpty()) ln = getLocalPart(qn); if (isNamespace(qn) && !fromFragmentHandler) { // I haven't figured the reason out yet, but, in somewhere, @@ -161,18 +164,15 @@ public void startElement(String uri, String localName, String qName, Attributes IRubyObject[] args = null; if (needEmptyAttrCheck) { if (isEmptyAttr(ln)) { - args = new IRubyObject[3]; - args[0] = stringOrNil(ruby, ln); - args[1] = stringOrNil(ruby, pre); - args[2] = stringOrNil(ruby, u); + args = new IRubyObject[] { + stringOrNil(ruby, ln), stringOrNil(ruby, pre), stringOrNil(ruby, u) + }; } } if (args == null) { - args = new IRubyObject[4]; - args[0] = stringOrNil(ruby, ln); - args[1] = stringOrNil(ruby, pre); - args[2] = stringOrNil(ruby, u); - args[3] = stringOrNil(ruby, val); + args = new IRubyObject[] { + stringOrNil(ruby, ln), stringOrNil(ruby, pre), stringOrNil(ruby, u), stringOrNil(ruby, val) + }; } IRubyObject attr = RuntimeHelpers.invoke(context, attrClass, "new", args); @@ -180,7 +180,7 @@ public void startElement(String uri, String localName, String qName, Attributes } } - if (localName == null || localName.equals("")) localName = getLocalPart(qName); + if (localName == null || localName.isEmpty()) localName = getLocalPart(qName); populateCharacters(); call("start_element_namespace", stringOrNil(ruby, localName), @@ -190,37 +190,27 @@ public void startElement(String uri, String localName, String qName, Attributes rubyNSAttr); } - private static String[] emptyAttrs = - {"checked", "compact", "declare", "defer", "disabled", "ismap", "multiple", - "noresize", "nohref", "noshade", "nowrap", "readonly", "selected"}; - - private boolean isEmptyAttr(String name) { - for (String emptyAttr : emptyAttrs) { - if (emptyAttr.equals(name)) return true; - } - return false; + static final Set EMPTY_ATTRS; + static { + final String[] emptyAttrs = { + "checked", "compact", "declare", "defer", "disabled", "ismap", "multiple", + "noresize", "nohref", "noshade", "nowrap", "readonly", "selected" + }; + EMPTY_ATTRS = new HashSet(Arrays.asList(emptyAttrs)); } - - public Integer getLine() { - return locator.getLineNumber(); + + private static boolean isEmptyAttr(String name) { + return EMPTY_ATTRS.contains(name); } - - public Integer getColumn() { - return locator.getColumnNumber() - 1; + + public final Integer getLine() { // -1 if none is available + final int line = locator.getLineNumber(); + return line == -1 ? null : line; } - - private boolean isFromFragmentHandler() { - if (object != null && object instanceof RubyObject) { - RubyObject rubyObj = (RubyObject)object; - IRubyObject document = rubyObj.getInstanceVariable("@document"); - if (document != null) { - String name = document.getMetaClass().getName(); - if ("Nokogiri::XML::FragmentHandler".equals(name)) { - return true; - } - } - } - return false; + + public final Integer getColumn() { // -1 if none is available + final int column = locator.getColumnNumber(); + return column == -1 ? null : column - 1; } @Override @@ -244,12 +234,12 @@ public void comment(char[] ch, int start, int length) throws SAXException { } @Override - public void startCDATA() throws SAXException { + public void startCDATA() { populateCharacters(); } @Override - public void endCDATA() throws SAXException { + public void endCDATA() { call("cdata_block", ruby.newString(charactersBuilder.toString())); charactersBuilder.setLength(0); } @@ -265,8 +255,7 @@ public void error(SAXParseException saxpe) { } @Override - public void fatalError(SAXParseException saxpe) throws SAXException - { + public void fatalError(SAXParseException saxpe) { try { call("error", ruby.newString(saxpe.getMessage())); addError(new RaiseException(XmlSyntaxError.createFatalError(ruby, saxpe), true)); @@ -311,8 +300,7 @@ private void call(String methodName, IRubyObject arg1, IRubyObject arg2) { private void call(String methodName, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) { ThreadContext context = ruby.getCurrentContext(); - RuntimeHelpers.invoke(context, document(context), methodName, - arg1, arg2, arg3); + RuntimeHelpers.invoke(context, document(context), methodName, arg1, arg2, arg3); } private void call(String methodName, @@ -321,19 +309,13 @@ private void call(String methodName, IRubyObject arg2, IRubyObject arg3, IRubyObject arg4) { - IRubyObject[] args = new IRubyObject[5]; - args[0] = arg0; - args[1] = arg1; - args[2] = arg2; - args[3] = arg3; - args[4] = arg4; ThreadContext context = ruby.getCurrentContext(); - RuntimeHelpers.invoke(context, document(context), methodName, args); + RuntimeHelpers.invoke(context, document(context), methodName, arg0, arg1, arg2, arg3, arg4); } private IRubyObject document(ThreadContext context) { if (object instanceof RubyObject) { - return ((RubyObject)object).fastGetInstanceVariable("@document"); + return ((RubyObject) object).fastGetInstanceVariable("@document"); } return context.getRuntime().getNil(); } From cc0d25d6837dc67a52e611c515418757c2626543 Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 12:40:10 +0100 Subject: [PATCH 049/176] refactor/simplify/format NokogiriHandler's code --- .../nokogiri/internals/NokogiriHandler.java | 107 +++++++++--------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 7e55d38529..48f2bcbf4f 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -65,8 +65,9 @@ * @author Yoko Harada */ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { + StringBuilder charactersBuilder; - private final Ruby ruby; + private final Ruby runtime; private final RubyClass attrClass; private final IRubyObject object; @@ -79,20 +80,19 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { private final LinkedList errors = new LinkedList(); private Locator locator; - private static String htmlParserName = "Nokogiri::HTML::SAX::Parser"; - private boolean needEmptyAttrCheck = false; + private boolean needEmptyAttrCheck; public NokogiriHandler(Ruby runtime, IRubyObject object) { - this.ruby = runtime; + this.runtime = runtime; this.attrClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SAX::Parser::Attribute"); this.object = object; String objectName = object.getMetaClass().getName(); - if (htmlParserName.equals(objectName)) needEmptyAttrCheck = true; + if ("Nokogiri::HTML::SAX::Parser".equals(objectName)) needEmptyAttrCheck = true; } @Override public void skippedEntity(String skippedEntity) { - call("error", ruby.newString("Entity '" + skippedEntity + "' not defined\n")); + call("error", runtime.newString("Entity '" + skippedEntity + "' not defined\n")); } @Override @@ -108,9 +108,7 @@ public void startDocument() { @Override public void xmlDecl(String version, String encoding, String standalone) { - call("xmldecl", stringOrNil(ruby, version), - stringOrNil(ruby, encoding), - stringOrNil(ruby, standalone)); + call("xmldecl", stringOrNil(runtime, version), stringOrNil(runtime, encoding), stringOrNil(runtime, standalone)); } @Override @@ -121,7 +119,7 @@ public void endDocument() { @Override public void processingInstruction(String target, String data) { - call("processing_instruction", ruby.newString(target), ruby.newString(data)); + call("processing_instruction", runtime.newString(target), runtime.newString(data)); } /* @@ -133,12 +131,14 @@ public void processingInstruction(String target, String data) { */ @Override public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { + final Ruby runtime = this.runtime; + final ThreadContext context = runtime.getCurrentContext(); + // for attributes other than namespace attrs - RubyArray rubyAttr = RubyArray.newArray(ruby); + RubyArray rubyAttr = RubyArray.newArray(runtime); // for namespace defining attributes - RubyArray rubyNSAttr = RubyArray.newArray(ruby); + RubyArray rubyNSAttr = RubyArray.newArray(runtime); - ThreadContext context = ruby.getCurrentContext(); boolean fromFragmentHandler = false; // isFromFragmentHandler(); for (int i = 0; i < attrs.getLength(); i++) { @@ -155,38 +155,39 @@ public void startElement(String uri, String localName, String qName, Attributes // I haven't figured the reason out yet, but, in somewhere, // namespace is converted to array in array and cause // TypeError at line 45 in fragment_handler.rb - RubyArray ns = RubyArray.newArray(ruby, 2); if (ln.equals("xmlns")) ln = null; - ns.add(stringOrNil(ruby, ln)); - ns.add(ruby.newString(val)); - rubyNSAttr.add(ns); + rubyNSAttr.append( runtime.newArray( stringOrNil(runtime, ln), runtime.newString(val) ) ); } else { IRubyObject[] args = null; if (needEmptyAttrCheck) { if (isEmptyAttr(ln)) { args = new IRubyObject[] { - stringOrNil(ruby, ln), stringOrNil(ruby, pre), stringOrNil(ruby, u) + stringOrNil(runtime, ln), + stringOrNil(runtime, pre), + stringOrNil(runtime, u) }; } } if (args == null) { args = new IRubyObject[] { - stringOrNil(ruby, ln), stringOrNil(ruby, pre), stringOrNil(ruby, u), stringOrNil(ruby, val) + stringOrNil(runtime, ln), + stringOrNil(runtime, pre), + stringOrNil(runtime, u), + stringOrNil(runtime, val) }; } - IRubyObject attr = RuntimeHelpers.invoke(context, attrClass, "new", args); - rubyAttr.add(attr); + rubyAttr.append( RuntimeHelpers.invoke(context, attrClass, "new", args) ); } } if (localName == null || localName.isEmpty()) localName = getLocalPart(qName); populateCharacters(); call("start_element_namespace", - stringOrNil(ruby, localName), + stringOrNil(runtime, localName), rubyAttr, - stringOrNil(ruby, getPrefix(qName)), - stringOrNil(ruby, uri), + stringOrNil(runtime, getPrefix(qName)), + stringOrNil(runtime, uri), rubyNSAttr); } @@ -214,23 +215,23 @@ public final Integer getColumn() { // -1 if none is available } @Override - public void endElement(String uri, String localName, String qName) throws SAXException { + public void endElement(String uri, String localName, String qName) { populateCharacters(); call("end_element_namespace", - stringOrNil(ruby, localName), - stringOrNil(ruby, getPrefix(qName)), - stringOrNil(ruby, uri)); + stringOrNil(runtime, localName), + stringOrNil(runtime, getPrefix(qName)), + stringOrNil(runtime, uri)); } @Override - public void characters(char[] ch, int start, int length) throws SAXException { + public void characters(char[] ch, int start, int length) { charactersBuilder.append(ch, start, length); } @Override - public void comment(char[] ch, int start, int length) throws SAXException { + public void comment(char[] ch, int start, int length) { populateCharacters(); - call("comment", ruby.newString(new String(ch, start, length))); + call("comment", runtime.newString(new String(ch, start, length))); } @Override @@ -240,34 +241,37 @@ public void startCDATA() { @Override public void endCDATA() { - call("cdata_block", ruby.newString(charactersBuilder.toString())); + call("cdata_block", runtime.newString(charactersBuilder.toString())); charactersBuilder.setLength(0); } @Override - public void error(SAXParseException saxpe) { + public void error(SAXParseException ex) { try { - call("error", ruby.newString(saxpe.getMessage())); - addError(new RaiseException(XmlSyntaxError.createError(ruby, saxpe), true)); + final String msg = ex.getMessage(); + call("error", runtime.newString(msg == null ? "" : msg)); + addError(new RaiseException(XmlSyntaxError.createError(runtime, ex), true)); } catch(RaiseException e) { addError(e); } } @Override - public void fatalError(SAXParseException saxpe) { + public void fatalError(SAXParseException ex) { try { - call("error", ruby.newString(saxpe.getMessage())); - addError(new RaiseException(XmlSyntaxError.createFatalError(ruby, saxpe), true)); + final String msg = ex.getMessage(); + call("error", runtime.newString(msg == null ? "" : msg)); + addError(new RaiseException(XmlSyntaxError.createFatalError(runtime, ex), true)); + } catch(RaiseException e) { addError(e); } } @Override - public void warning(SAXParseException saxpe) { - //System.out.println("warning: " + saxpe); - call("warning", ruby.newString(saxpe.getMessage())); + public void warning(SAXParseException ex) { + final String msg = ex.getMessage(); + call("warning", runtime.newString(msg == null ? "" : msg)); } protected synchronized void addError(RaiseException e) { @@ -283,23 +287,22 @@ public synchronized RaiseException getLastError() { } private void call(String methodName) { - ThreadContext context = ruby.getCurrentContext(); + ThreadContext context = runtime.getCurrentContext(); RuntimeHelpers.invoke(context, document(context), methodName); } private void call(String methodName, IRubyObject argument) { - ThreadContext context = ruby.getCurrentContext(); + ThreadContext context = runtime.getCurrentContext(); RuntimeHelpers.invoke(context, document(context), methodName, argument); } private void call(String methodName, IRubyObject arg1, IRubyObject arg2) { - ThreadContext context = ruby.getCurrentContext(); + ThreadContext context = runtime.getCurrentContext(); RuntimeHelpers.invoke(context, document(context), methodName, arg1, arg2); } - private void call(String methodName, IRubyObject arg1, IRubyObject arg2, - IRubyObject arg3) { - ThreadContext context = ruby.getCurrentContext(); + private void call(String methodName, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) { + ThreadContext context = runtime.getCurrentContext(); RuntimeHelpers.invoke(context, document(context), methodName, arg1, arg2, arg3); } @@ -309,20 +312,18 @@ private void call(String methodName, IRubyObject arg2, IRubyObject arg3, IRubyObject arg4) { - ThreadContext context = ruby.getCurrentContext(); + ThreadContext context = runtime.getCurrentContext(); RuntimeHelpers.invoke(context, document(context), methodName, arg0, arg1, arg2, arg3, arg4); } private IRubyObject document(ThreadContext context) { - if (object instanceof RubyObject) { - return ((RubyObject) object).fastGetInstanceVariable("@document"); - } - return context.getRuntime().getNil(); + if (object == null) return context.nil; + return object.getInstanceVariables().getInstanceVariable("@document"); } protected void populateCharacters() { if (charactersBuilder.length() > 0) { - call("characters", ruby.newString(charactersBuilder.toString())); + call("characters", runtime.newString(charactersBuilder.toString())); charactersBuilder.setLength(0); } } From 4c0b1e277acba714ac93658ffddabdb63ae4659a Mon Sep 17 00:00:00 2001 From: kares Date: Tue, 14 Feb 2017 14:41:57 +0100 Subject: [PATCH 050/176] SAX exception's message might be null + don't use string matching --- ext/java/nokogiri/XmlSaxParserContext.java | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ext/java/nokogiri/XmlSaxParserContext.java b/ext/java/nokogiri/XmlSaxParserContext.java index e7f0f1c79a..bf42c9b5e6 100644 --- a/ext/java/nokogiri/XmlSaxParserContext.java +++ b/ext/java/nokogiri/XmlSaxParserContext.java @@ -251,26 +251,25 @@ public IRubyObject parse_with(ThreadContext context, IRubyObject handlerRuby) { try { do_parse(); } - catch (SAXParseException spe) { + catch (SAXParseException ex) { // A bad document () should call the // error handler instead of raising a SAX exception. - // However, an EMPTY document should raise a - // RuntimeError. This is a bit kludgy, but AFAIK SAX - // doesn't distinguish between empty and bad whereas - // Nokogiri does. - String message = spe.getMessage(); - if ("Premature end of file.".matches(message) && stringDataSize < 1) { + // However, an EMPTY document should raise a RuntimeError. + // This is a bit kludgy, but AFAIK SAX doesn't distinguish + // between empty and bad whereas Nokogiri does. + String message = ex.getMessage(); + if (message != null && message.contains("Premature end of file.") && stringDataSize < 1) { throw runtime.newRuntimeError("couldn't parse document: " + message); } - handler.error(spe); + handler.error(ex); } } - catch (SAXException se) { - throw RaiseException.createNativeRaiseException(runtime, se); + catch (SAXException ex) { + throw RaiseException.createNativeRaiseException(runtime, ex); } - catch (IOException ioe) { - throw runtime.newIOErrorFromException(ioe); + catch (IOException ex) { + throw runtime.newIOErrorFromException(ex); } postParse(runtime, handlerRuby, handler); From f73bd4e268b8182fb008727eb554aa58624630ff Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 15 Feb 2017 10:32:40 +0100 Subject: [PATCH 051/176] abstract!; make option's fields final; introduce a ParserTask base --- .../nokogiri/internals/ParserContext.java | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/ext/java/nokogiri/internals/ParserContext.java b/ext/java/nokogiri/internals/ParserContext.java index c9dc46decf..eb97c65fb0 100644 --- a/ext/java/nokogiri/internals/ParserContext.java +++ b/ext/java/nokogiri/internals/ParserContext.java @@ -43,6 +43,7 @@ import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; +import java.util.concurrent.Callable; import org.jruby.Ruby; import org.jruby.RubyClass; @@ -54,7 +55,6 @@ import org.jruby.util.ByteList; import org.jruby.util.TypeConverter; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Base class for the various parser contexts. Handles converting @@ -63,7 +63,7 @@ * @author Patrick Mahoney * @author Yoko Harada */ -public class ParserContext extends RubyObject { +public abstract class ParserContext extends RubyObject { protected InputSource source = null; protected IRubyObject detected_encoding = null; protected int stringDataSize = -1; @@ -229,23 +229,23 @@ public static class Options { protected static final long NOCDATA = 16384; protected static final long NOXINCNODE = 32768; - public boolean strict; - public boolean recover; - public boolean noEnt; - public boolean dtdLoad; - public boolean dtdAttr; - public boolean dtdValid; - public boolean noError; - public boolean noWarning; - public boolean pedantic; - public boolean noBlanks; - public boolean sax1; - public boolean xInclude; - public boolean noNet; - public boolean noDict; - public boolean nsClean; - public boolean noCdata; - public boolean noXIncNode; + public final boolean strict; + public final boolean recover; + public final boolean noEnt; + public final boolean dtdLoad; + public final boolean dtdAttr; + public final boolean dtdValid; + public final boolean noError; + public final boolean noWarning; + public final boolean pedantic; + public final boolean noBlanks; + public final boolean sax1; + public final boolean xInclude; + public final boolean noNet; + public final boolean noDict; + public final boolean nsClean; + public final boolean noCdata; + public final boolean noXIncNode; protected static boolean test(long options, long mask) { return ((options & mask) == mask); @@ -272,6 +272,7 @@ public Options(long options) { } } + /* public static class NokogiriXInlcudeEntityResolver implements org.xml.sax.EntityResolver { InputSource source; public NokogiriXInlcudeEntityResolver(InputSource source) { @@ -285,6 +286,20 @@ public InputSource resolveEntity(String publicId, String systemId) if (publicId != null) source.setPublicId(publicId); return source; } + } */ + + public static abstract class ParserTask implements Callable { + + protected final ThreadContext context; // TODO does not seem like a good idea!? + protected final IRubyObject handler; + protected final T parser; + + protected ParserTask(ThreadContext context, IRubyObject handler, T parser) { + this.context = context; + this.handler = handler; + this.parser = parser; + } + } } From 4657325a678aa918dd4dc9099af7196fcdabb148 Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 15 Feb 2017 11:02:09 +0100 Subject: [PATCH 052/176] share ParserTask logic for Xml/Html push-parser; improve termination --- ext/java/nokogiri/HtmlSaxPushParser.java | 127 +++++++++---------- ext/java/nokogiri/XmlSaxParserContext.java | 17 +-- ext/java/nokogiri/XmlSaxPushParser.java | 140 +++++++++++++-------- 3 files changed, 148 insertions(+), 136 deletions(-) diff --git a/ext/java/nokogiri/HtmlSaxPushParser.java b/ext/java/nokogiri/HtmlSaxPushParser.java index cee6ac0d07..5c13eff21b 100644 --- a/ext/java/nokogiri/HtmlSaxPushParser.java +++ b/ext/java/nokogiri/HtmlSaxPushParser.java @@ -32,33 +32,26 @@ package nokogiri; +import static nokogiri.XmlSaxPushParser.terminateExecution; import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; import static org.jruby.javasupport.util.RuntimeHelpers.invoke; -import static nokogiri.internals.NokogiriHelpers.rubyStringToString; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.EnumSet; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; -import nokogiri.internals.ClosedStreamException; -import nokogiri.internals.NokogiriBlockingQueueInputStream; -import nokogiri.internals.NokogiriHelpers; -import nokogiri.internals.ParserContext; +import nokogiri.internals.*; import org.jruby.Ruby; import org.jruby.RubyClass; -import org.jruby.RubyException; -import org.jruby.RubyFixnum; import org.jruby.RubyObject; -import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; @@ -76,10 +69,12 @@ public class HtmlSaxPushParser extends RubyObject { ParserContext.Options options; IRubyObject optionsRuby; IRubyObject saxParser; + NokogiriBlockingQueueInputStream stream; - ParserTask parserTask = null; - FutureTask futureTask = null; - ExecutorService executor = null; + + private ParserTask parserTask = null; + private FutureTask futureTask = null; + private ExecutorService executor = null; public HtmlSaxPushParser(Ruby ruby, RubyClass rubyClass) { super(ruby, rubyClass); @@ -87,7 +82,10 @@ public HtmlSaxPushParser(Ruby ruby, RubyClass rubyClass) { @Override public void finalize() { - terminateTask(null); + try { + terminateImpl(); + } + catch (Exception e) { /* ignored */ } } /** @@ -127,8 +125,7 @@ public IRubyObject setOptions(ThreadContext context, IRubyObject val) { } @JRubyMethod - public IRubyObject native_write(ThreadContext context, IRubyObject chunk, - IRubyObject isLast) { + public IRubyObject native_write(ThreadContext context, IRubyObject chunk, IRubyObject isLast) { try { initialize_task(context); } catch (IOException e) { @@ -136,7 +133,7 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } final ByteArrayInputStream data = NokogiriHelpers.stringBytesToStream(chunk); if (data == null) { - terminateTask(context); + terminateTask(context.runtime); throw new RaiseException(XmlSyntaxError.createHTMLSyntaxError(context.runtime)); // Nokogiri::HTML::SyntaxError } @@ -145,33 +142,37 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, if (isLast.isTrue()) { IRubyObject document = invoke(context, this, "document"); invoke(context, document, "end_document"); - terminateTask(context); + terminateTask(context.runtime); } else { try { - Future task = stream.addChunk(data); - task.get(); - } catch (ClosedStreamException ex) { - // this means the stream is closed, ignore this exception - } catch (Exception e) { - throw context.getRuntime().newRuntimeError(e.getMessage()); + Future task = stream.addChunk(data); + task.get(); + } + catch (ClosedStreamException ex) { + // this means the stream is closed, ignore this exception + } + catch (Exception e) { + throw context.runtime.newRuntimeError(e.getMessage()); } } if (!options.recover && parserTask.getErrorCount() > errorCount0) { - terminateTask(context); + terminateTask(context.runtime); throw parserTask.getLastError(); } return this; } + @SuppressWarnings("unchecked") private void initialize_task(ThreadContext context) throws IOException { if (futureTask == null || stream == null) { stream = new NokogiriBlockingQueueInputStream(); - parserTask = new ParserTask(context, saxParser); - futureTask = new FutureTask(parserTask); + assert saxParser != null : "saxParser null"; + parserTask = new ParserTask(context, saxParser, stream); + futureTask = new FutureTask((Callable) parserTask); executor = Executors.newSingleThreadExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { @@ -185,56 +186,42 @@ public Thread newThread(Runnable r) { } } - private synchronized void terminateTask(ThreadContext context) { + private void terminateTask(final Ruby runtime) { + if (executor == null) return; + try { - Future task = stream.addChunk(NokogiriBlockingQueueInputStream.END); - task.get(); - } catch (ClosedStreamException ex) { - // ignore this exception, it means the stream was closed - } catch (Exception e) { - if (context != null) - throw context.getRuntime().newRuntimeError(e.getMessage()); + terminateImpl(); + } + catch (InterruptedException e) { + throw runtime.newRuntimeError(e.toString()); } - futureTask.cancel(true); - executor.shutdown(); - executor = null; - stream = null; - futureTask = null; + catch (Exception e) { + throw runtime.newRuntimeError(e.toString()); + } + } + + private synchronized void terminateImpl() throws InterruptedException, ExecutionException { + terminateExecution(executor, stream, futureTask); + + executor = null; stream = null; futureTask = null; } - - - private class ParserTask implements Callable { - private final ThreadContext context; - private final IRubyObject handler; - private final HtmlSaxParserContext parser; - - private ParserTask(ThreadContext context, IRubyObject handler) { - RubyClass klazz = getNokogiriClass(context.runtime, "Nokogiri::HTML::SAX::ParserContext"); - this.context = context; - this.handler = handler; - this.parser = HtmlSaxParserContext.parse_stream(context.runtime, klazz, stream); + + private static HtmlSaxParserContext parse(final Ruby runtime, final InputStream stream) { + RubyClass klazz = getNokogiriClass(runtime, "Nokogiri::HTML::SAX::ParserContext"); + return HtmlSaxParserContext.parse_stream(runtime, klazz, stream); + } + + static class ParserTask extends XmlSaxPushParser.ParserTask /* */ { + + private ParserTask(ThreadContext context, IRubyObject handler, InputStream stream) { + super(context, handler, parse(context.runtime, stream), stream); } @Override public HtmlSaxParserContext call() throws Exception { - try { - parser.parse_with(context, handler); - } finally { - // we have to close the stream before exiting, otherwise someone - // can add a chunk and block on task.get() forever. - stream.close(); - } - return parser; - } - - private synchronized int getErrorCount() { - // check for null because thread may not have started yet - if (parser.getNokogiriHandler() == null) return 0; - else return parser.getNokogiriHandler().getErrorCount(); + return (HtmlSaxParserContext) super.call(); } - private synchronized RaiseException getLastError() { - return parser.getNokogiriHandler().getLastError(); - } } + } diff --git a/ext/java/nokogiri/XmlSaxParserContext.java b/ext/java/nokogiri/XmlSaxParserContext.java index bf42c9b5e6..33ac496553 100644 --- a/ext/java/nokogiri/XmlSaxParserContext.java +++ b/ext/java/nokogiri/XmlSaxParserContext.java @@ -69,6 +69,7 @@ */ @JRubyClass(name="Nokogiri::XML::SAX::ParserContext") public class XmlSaxParserContext extends ParserContext { + protected static final String FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces"; protected static final String FEATURE_NAMESPACE_PREFIXES = @@ -164,15 +165,11 @@ public static IRubyObject parse_io(ThreadContext context, } /** - * Create a new parser context that will read from a raw input - * stream. Not a JRuby method. Meant to be run in a separate - * thread by XmlSaxPushParser. + * Create a new parser context that will read from a raw input stream. + * Meant to be run in a separate thread by XmlSaxPushParser. */ - public static IRubyObject parse_stream(ThreadContext context, - IRubyObject klazz, - InputStream stream) { - final Ruby runtime = context.runtime; - XmlSaxParserContext ctx = newInstance(runtime, (RubyClass) klazz); + static XmlSaxParserContext parse_stream(final Ruby runtime, RubyClass klazz, InputStream stream) { + XmlSaxParserContext ctx = newInstance(runtime, klazz); ctx.initialize(runtime); ctx.setInputSource(stream); return ctx; @@ -198,9 +195,7 @@ protected void setErrorHandler(ErrorHandler handler) { parser.setErrorHandler(handler); } - public NokogiriHandler getNokogiriHandler() { - return handler; - } + public final NokogiriHandler getNokogiriHandler() { return handler; } /** * Perform any initialization prior to parsing with the handler diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index 0cb759d05d..8e2153178c 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -37,29 +37,25 @@ import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.concurrent.Callable; +import java.io.InputStream; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; -import nokogiri.internals.ClosedStreamException; -import nokogiri.internals.NokogiriBlockingQueueInputStream; -import nokogiri.internals.NokogiriHelpers; -import nokogiri.internals.ParserContext; +import nokogiri.internals.*; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyException; import org.jruby.RubyObject; -import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.util.ByteList; import org.xml.sax.SAXException; /** @@ -73,10 +69,12 @@ public class XmlSaxPushParser extends RubyObject { ParserContext.Options options; IRubyObject optionsRuby; IRubyObject saxParser; + NokogiriBlockingQueueInputStream stream; - ParserTask parserTask = null; - FutureTask futureTask = null; - ExecutorService executor = null; + + private ParserTask parserTask = null; + private FutureTask futureTask = null; + private ExecutorService executor = null; RaiseException ex = null; public XmlSaxPushParser(Ruby ruby, RubyClass rubyClass) { @@ -85,7 +83,10 @@ public XmlSaxPushParser(Ruby ruby, RubyClass rubyClass) { @Override public void finalize() { - terminateTask(null); + try { + terminateImpl(); + } + catch (Exception e) { /* ignored */ } } @JRubyMethod @@ -167,14 +168,13 @@ public IRubyObject native_write(ThreadContext context, IRubyObject chunk, } if (isLast.isTrue()) { - parserTask.parser.getNokogiriHandler().endDocument(); - terminateTask(context); + parserTask.getNokogiriHandler().endDocument(); + terminateTask(context.runtime); } if (!options.recover && parserTask.getErrorCount() > errorCount0) { - terminateTask(context); - ex = parserTask.getLastError(); - throw parserTask.getLastError(); + terminateTask(context.runtime); + throw ex = parserTask.getLastError(); } return this; @@ -184,74 +184,104 @@ private void initialize_task(ThreadContext context) throws IOException { if (futureTask == null || stream == null) { stream = new NokogiriBlockingQueueInputStream(); - parserTask = new ParserTask(context, saxParser); + assert saxParser != null : "saxParser null"; + parserTask = new ParserTask(context, saxParser, stream); futureTask = new FutureTask(parserTask); executor = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("XmlSaxPushParser"); - t.setDaemon(true); - return t; - } + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setName("XmlSaxPushParser"); + t.setDaemon(true); + return t; + } }); executor.submit(futureTask); } } - private synchronized void terminateTask(ThreadContext context) { - if (futureTask == null || stream == null) { - return; + private void terminateTask(final Ruby runtime) { + if (executor == null) return; + + try { + terminateImpl(); } + catch (InterruptedException e) { + throw runtime.newRuntimeError(e.toString()); + } + catch (Exception e) { + throw runtime.newRuntimeError(e.toString()); + } + } + + private synchronized void terminateImpl() throws InterruptedException, ExecutionException { + terminateExecution(executor, stream, futureTask); + + executor = null; stream = null; futureTask = null; + } + + // SHARED for HtmlSaxPushParser + static void terminateExecution(final ExecutorService executor, final NokogiriBlockingQueueInputStream stream, + final FutureTask futureTask) + throws InterruptedException, ExecutionException { + + if (executor == null) return; try { - Future task = stream.addChunk(NokogiriBlockingQueueInputStream.END); - task.get(); - } catch (ClosedStreamException ex) { - // ignore this exception, it means the stream was closed - } catch (Exception e) { - if (context != null) - throw context.getRuntime().newRuntimeError(e.getMessage()); + Future task = stream.addChunk(NokogiriBlockingQueueInputStream.END); + task.get(); + } + catch (ClosedStreamException ex) { + // ignore this exception, it means the stream was closed } futureTask.cancel(true); executor.shutdown(); - executor = null; - stream = null; - futureTask = null; } - private class ParserTask implements Callable { - private final ThreadContext context; - private final IRubyObject handler; - private final XmlSaxParserContext parser; + private static XmlSaxParserContext parse(final Ruby runtime, final InputStream stream) { + RubyClass klazz = getNokogiriClass(runtime, "Nokogiri::XML::SAX::ParserContext"); + return XmlSaxParserContext.parse_stream(runtime, klazz, stream); + } + + static class ParserTask extends ParserContext.ParserTask { - private ParserTask(ThreadContext context, IRubyObject handler) { - RubyClass klazz = getNokogiriClass(context.getRuntime(), "Nokogiri::XML::SAX::ParserContext"); - this.context = context; - this.handler = handler; - this.parser = (XmlSaxParserContext) XmlSaxParserContext.parse_stream(context, klazz, stream); + final InputStream stream; + + private ParserTask(ThreadContext context, IRubyObject handler, InputStream stream) { + this(context, handler, parse(context.runtime, stream), stream); + } + + // IMPL with HtmlSaxPushParser + protected ParserTask(ThreadContext context, IRubyObject handler, XmlSaxParserContext parser, InputStream stream) { + super(context, handler, parser); + this.stream = stream; } @Override public XmlSaxParserContext call() throws Exception { - try { - parser.parse_with(context, handler); - } finally { + try { + parser.parse_with(context, handler); + } + finally { stream.close(); } // we have to close the stream before exiting, otherwise someone // can add a chunk and block on task.get() forever. - stream.close(); - } - return parser; + return parser; } - private synchronized int getErrorCount() { + final NokogiriHandler getNokogiriHandler() { + return parser.getNokogiriHandler(); + } + + synchronized final int getErrorCount() { // check for null because thread may not have started yet if (parser.getNokogiriHandler() == null) return 0; - else return parser.getNokogiriHandler().getErrorCount(); + return parser.getNokogiriHandler().getErrorCount(); } - private synchronized RaiseException getLastError() { + synchronized final RaiseException getLastError() { return parser.getNokogiriHandler().getLastError(); } + } + } From 60f724abc4c4f176ccbeb23109c44aae94bf007b Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 15 Feb 2017 11:10:32 +0100 Subject: [PATCH 053/176] object is never null (already have asserts up one level as well) --- ext/java/nokogiri/internals/NokogiriHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 48f2bcbf4f..1969a604eb 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -83,6 +83,7 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler { private boolean needEmptyAttrCheck; public NokogiriHandler(Ruby runtime, IRubyObject object) { + assert object != null; this.runtime = runtime; this.attrClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SAX::Parser::Attribute"); this.object = object; @@ -119,7 +120,7 @@ public void endDocument() { @Override public void processingInstruction(String target, String data) { - call("processing_instruction", runtime.newString(target), runtime.newString(data)); + call("processing_instruction", runtime.newString(target), runtime.newString(data)); } /* @@ -317,7 +318,6 @@ private void call(String methodName, } private IRubyObject document(ThreadContext context) { - if (object == null) return context.nil; return object.getInstanceVariables().getInstanceVariable("@document"); } From b90f5aa9881e84d172abc553e189a732fe23ab6f Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 15 Feb 2017 11:13:29 +0100 Subject: [PATCH 054/176] lazily instantiate XML::ParseOptions as they are needed/used --- ext/java/nokogiri/HtmlSaxPushParser.java | 33 ++++++++++-------------- ext/java/nokogiri/XmlSaxPushParser.java | 31 ++++++++++------------ 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/ext/java/nokogiri/HtmlSaxPushParser.java b/ext/java/nokogiri/HtmlSaxPushParser.java index 5c13eff21b..57b66757b2 100644 --- a/ext/java/nokogiri/HtmlSaxPushParser.java +++ b/ext/java/nokogiri/HtmlSaxPushParser.java @@ -67,7 +67,6 @@ @JRubyClass(name="Nokogiri::HTML::SAX::PushParser") public class HtmlSaxPushParser extends RubyObject { ParserContext.Options options; - IRubyObject optionsRuby; IRubyObject saxParser; NokogiriBlockingQueueInputStream stream; @@ -88,39 +87,35 @@ public void finalize() { catch (Exception e) { /* ignored */ } } - /** - * Silently skips provided encoding - * - */ @JRubyMethod public IRubyObject initialize_native(final ThreadContext context, IRubyObject saxParser, IRubyObject fileName, IRubyObject encoding) { - optionsRuby - = invoke(context, context.getRuntime().getClassFromPath("Nokogiri::XML::ParseOptions"), "new"); - + // NOTE: Silently skips provided encoding options = new ParserContext.Options(0); this.saxParser = saxParser; return this; } - /** - * Returns an integer. - */ + private transient IRubyObject parse_options; + + private IRubyObject parse_options(final ThreadContext context) { + if (parse_options == null) { + parse_options = invoke(context, context.runtime.getClassFromPath("Nokogiri::XML::ParseOptions"), "new"); + } + return parse_options; + } + @JRubyMethod(name="options") public IRubyObject getOptions(ThreadContext context) { - return invoke(context, optionsRuby, "options"); + return invoke(context, parse_options(context), "options"); } - /** - * val is an integer. - */ @JRubyMethod(name="options=") - public IRubyObject setOptions(ThreadContext context, IRubyObject val) { - invoke(context, optionsRuby, "options=", val); - options = - new ParserContext.Options(val.convertToInteger().getLongValue()); + public IRubyObject setOptions(ThreadContext context, IRubyObject opts) { + invoke(context, parse_options(context), "options=", opts); + options = new ParserContext.Options(opts.convertToInteger().getLongValue()); return getOptions(context); } diff --git a/ext/java/nokogiri/XmlSaxPushParser.java b/ext/java/nokogiri/XmlSaxPushParser.java index 8e2153178c..010a3f05e8 100644 --- a/ext/java/nokogiri/XmlSaxPushParser.java +++ b/ext/java/nokogiri/XmlSaxPushParser.java @@ -67,7 +67,6 @@ @JRubyClass(name="Nokogiri::XML::SAX::PushParser") public class XmlSaxPushParser extends RubyObject { ParserContext.Options options; - IRubyObject optionsRuby; IRubyObject saxParser; NokogiriBlockingQueueInputStream stream; @@ -90,32 +89,30 @@ public void finalize() { } @JRubyMethod - public IRubyObject initialize_native(final ThreadContext context, - IRubyObject saxParser, - IRubyObject fileName) { - optionsRuby - = invoke(context, context.getRuntime().getClassFromPath("Nokogiri::XML::ParseOptions"), "new"); + public IRubyObject initialize_native(final ThreadContext context, IRubyObject saxParser, IRubyObject fileName) { options = new ParserContext.Options(0); this.saxParser = saxParser; return this; } - /** - * Returns an integer. - */ + private transient IRubyObject parse_options; + + private IRubyObject parse_options(final ThreadContext context) { + if (parse_options == null) { + parse_options = invoke(context, context.runtime.getClassFromPath("Nokogiri::XML::ParseOptions"), "new"); + } + return parse_options; + } + @JRubyMethod(name="options") public IRubyObject getOptions(ThreadContext context) { - return invoke(context, optionsRuby, "options"); + return invoke(context, parse_options(context), "options"); } - /** - * val is an integer. - */ @JRubyMethod(name="options=") - public IRubyObject setOptions(ThreadContext context, IRubyObject val) { - invoke(context, optionsRuby, "options=", val); - options = - new ParserContext.Options(val.convertToInteger().getLongValue()); + public IRubyObject setOptions(ThreadContext context, IRubyObject opts) { + invoke(context, parse_options(context), "options=", opts); + options = new ParserContext.Options(opts.convertToInteger().getLongValue()); return getOptions(context); } From 062a2ab505a769743fab13a87b090e4ebf8eda6a Mon Sep 17 00:00:00 2001 From: kares Date: Wed, 15 Feb 2017 11:14:17 +0100 Subject: [PATCH 055/176] use fix2long to convert options to long primitive --- ext/java/nokogiri/internals/XmlDomParserContext.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/java/nokogiri/internals/XmlDomParserContext.java b/ext/java/nokogiri/internals/XmlDomParserContext.java index b9782073d1..89af2bc162 100644 --- a/ext/java/nokogiri/internals/XmlDomParserContext.java +++ b/ext/java/nokogiri/internals/XmlDomParserContext.java @@ -48,6 +48,7 @@ import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; +import org.jruby.RubyFixnum; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @@ -65,6 +66,7 @@ * @author Yoko Harada */ public class XmlDomParserContext extends ParserContext { + protected static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; protected static final String FEATURE_LOAD_DTD_GRAMMAR = @@ -91,13 +93,13 @@ public XmlDomParserContext(Ruby runtime, IRubyObject options) { public XmlDomParserContext(Ruby runtime, IRubyObject encoding, IRubyObject options) { super(runtime); - this.options = new ParserContext.Options((Long)options.toJava(Long.class)); + this.options = new ParserContext.Options(RubyFixnum.fix2long(options)); java_encoding = NokogiriHelpers.getValidEncoding(runtime, encoding); ruby_encoding = encoding; initErrorHandler(); initParser(runtime); } - + protected void initErrorHandler() { if (options.recover) { errorHandler = new NokogiriNonStrictErrorHandler(options.noError, options.noWarning); From b5b97bc5db0235745f44af91ccb25d6e28ace7aa Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Mar 2018 19:00:55 -0500 Subject: [PATCH 056/176] concourse: windows moved to allow_failure also, untangle master pipeline a bit [skip ci] --- concourse/nokogiri.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 97ecb7f3ec..0e0da712ea 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -18,7 +18,7 @@ groups: - "rbx-<%= rbx_version %>-system" - "rbx-<%= rbx_version %>-vendored" <% end %> - <% for ruby_version in RUBIES[:windows] %> + <% RUBIES[:windows].first(1).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> @@ -37,6 +37,13 @@ groups: - rbx-<%= RUBIES[:rbx].last %>-pr - pr-success + - name: allow-failure + jobs: + <% RUBIES[:windows].last(2).each do |ruby_version| %> + - "win-ruby-<%= ruby_version %>-devkit" + <% end %> + + resource_types: - name: pull-request type: docker-image @@ -131,14 +138,13 @@ jobs: path: ci/concourse/tasks/rake-test/run.sh <% end %> - <% for ruby_version in RUBIES[:mri][-1,1] %> +% ruby_version = RUBIES[:mri].last - name: ruby-libxmlruby-system public: true plan: - get: ci - get: nokogiri trigger: true - passed: ["ruby-<%= ruby_version %>-system"] - task: rake-test config: platform: linux @@ -160,7 +166,7 @@ jobs: - get: ci - get: nokogiri trigger: true - passed: ["ruby-<%= ruby_version %>-system"] + passed: ["ruby-libxmlruby-system"] - task: rake-test config: platform: linux @@ -196,7 +202,6 @@ jobs: TEST_WITH_VALGRIND: t run: path: ci/concourse/tasks/rake-test/run.sh - <% end %> <% for jruby_version in RUBIES[:jruby] %> - name: jruby-<%= jruby_version %> @@ -271,7 +276,6 @@ jobs: - get: ci - get: nokogiri trigger: true - passed: ["ruby-<%= ruby_version %>-system"] - task: rake-test config: platform: windows From 77be60c3681f76db0416d98da2e940a10bd1169d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Mar 2018 19:45:37 -0500 Subject: [PATCH 057/176] tweak compiler flags to reduce noise remove a few that generate lots of warnings on ruby.h: - -Wcast-qual - -Wconversion add -Wextra back (it was removed in 2008) --- ext/nokogiri/extconf.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index ae89b01992..0c160419f0 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -434,7 +434,7 @@ def using_system_libraries? if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/] - $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline" + $CFLAGS << " -Wall -Wextra -Wwrite-strings -Wmissing-noreturn -Winline" end case From b0a12b92ee1621779a4bd5257132288dcc3a3941 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Mar 2018 22:02:02 -0500 Subject: [PATCH 058/176] fix some compiler warnings --- ext/nokogiri/xml_cdata.c | 10 ++++++---- ext/nokogiri/xml_node.c | 32 ++++++++++++++++++++------------ ext/nokogiri/xslt_stylesheet.c | 4 ++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/ext/nokogiri/xml_cdata.c b/ext/nokogiri/xml_cdata.c index 61c8a8a8ac..636e7eeaa6 100644 --- a/ext/nokogiri/xml_cdata.c +++ b/ext/nokogiri/xml_cdata.c @@ -17,15 +17,17 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) VALUE content; VALUE rest; VALUE rb_node; - const xmlChar *content_str; - int content_str_len; + const xmlChar *content_str = NULL; + int content_str_len = 0; rb_scan_args(argc, argv, "2*", &doc, &content, &rest); Data_Get_Struct(doc, xmlDoc, xml_doc); - content_str = NIL_P(content) ? NULL : (const xmlChar *)StringValueCStr(content); - content_str_len = (content_str == NULL) ? 0 : strlen(content_str); + if (!NIL_P(content)) { + content_str = (const xmlChar *)StringValueCStr(content); + content_str_len = strlen((char *)content_str); + } node = xmlNewCDataBlock(xml_doc->doc, content_str, content_str_len); diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 9bdef4d9a5..46682f9815 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -168,18 +168,20 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: switch (reparentee->type) { - case XML_ELEMENT_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: - case XML_DOCUMENT_TYPE_NODE: - /* - * The DOM specification says no to adding text-like nodes - * directly to a document, but we allow it for compatibility. - */ - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_ENTITY_REF_NODE: - goto ok; + case XML_ELEMENT_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + /* + * The DOM specification says no to adding text-like nodes + * directly to a document, but we allow it for compatibility. + */ + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + goto ok; + default: + break; } break; case XML_DOCUMENT_FRAG_NODE: @@ -193,6 +195,8 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: goto ok; + default: + break; } break; case XML_ATTRIBUTE_NODE: @@ -200,6 +204,8 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep case XML_TEXT_NODE: case XML_ENTITY_REF_NODE: goto ok; + default: + break; } break; case XML_TEXT_NODE: @@ -210,6 +216,8 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep * operation, we should inhibit it. */ break; + default: + break; } rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj)); diff --git a/ext/nokogiri/xslt_stylesheet.c b/ext/nokogiri/xslt_stylesheet.c index 1520697758..d0ad6eaaf1 100644 --- a/ext/nokogiri/xslt_stylesheet.c +++ b/ext/nokogiri/xslt_stylesheet.c @@ -214,7 +214,7 @@ static void * initFunc(xsltTransformContextPtr ctxt, const xmlChar *uri) (unsigned char *)StringValueCStr(method_name), uri, method_caller); } - Data_Get_Struct(ctxt->style->_private, nokogiriXsltStylesheetTuple, + Data_Get_Struct((VALUE)ctxt->style->_private, nokogiriXsltStylesheetTuple, wrapper); inst = rb_class_new_instance(0, NULL, obj); rb_ary_push(wrapper->func_instances, inst); @@ -227,7 +227,7 @@ static void shutdownFunc(xsltTransformContextPtr ctxt, { nokogiriXsltStylesheetTuple *wrapper; - Data_Get_Struct(ctxt->style->_private, nokogiriXsltStylesheetTuple, + Data_Get_Struct((VALUE)ctxt->style->_private, nokogiriXsltStylesheetTuple, wrapper); rb_ary_clear(wrapper->func_instances); From 0b9c82894a2d4702da48048e9b9e1dd3f8acbe79 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Mar 2018 14:12:59 -0500 Subject: [PATCH 059/176] replace namespace_eh function with a macro to fix compiler warnings. the node->type check is polymorphic, and so a macro makes more sense to me (so we get some compile-time checking) than force-typecasting. --- ext/nokogiri/xml_namespace.c | 8 +------- ext/nokogiri/xml_namespace.h | 2 ++ ext/nokogiri/xml_node_set.c | 6 +++--- ext/nokogiri/xml_node_set.h | 1 - 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ext/nokogiri/xml_namespace.c b/ext/nokogiri/xml_namespace.c index f3374650f1..bd27f2d07d 100644 --- a/ext/nokogiri/xml_namespace.c +++ b/ext/nokogiri/xml_namespace.c @@ -24,12 +24,6 @@ static void dealloc_namespace(xmlNsPtr ns) } -int Nokogiri_namespace_eh(xmlNodePtr node) -{ - return (node->type == XML_NAMESPACE_DECL); -} - - /* * call-seq: * prefix @@ -64,7 +58,7 @@ static VALUE href(VALUE self) static int part_of_an_xpath_node_set_eh(xmlNsPtr node) { - return (node->next && ! Nokogiri_namespace_eh(node->next)); + return (node->next && ! NOKOGIRI_NAMESPACE_EH(node->next)); } VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) diff --git a/ext/nokogiri/xml_namespace.h b/ext/nokogiri/xml_namespace.h index f38cf00ad9..3ffd5343cc 100644 --- a/ext/nokogiri/xml_namespace.h +++ b/ext/nokogiri/xml_namespace.h @@ -10,4 +10,6 @@ extern VALUE cNokogiriXmlNamespace ; VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) ; VALUE Nokogiri_wrap_xml_namespace2(VALUE document, xmlNsPtr node) ; +#define NOKOGIRI_NAMESPACE_EH(node) ((node)->type == XML_NAMESPACE_DECL) + #endif diff --git a/ext/nokogiri/xml_node_set.c b/ext/nokogiri/xml_node_set.c index 553da7a92f..c38497d08a 100644 --- a/ext/nokogiri/xml_node_set.c +++ b/ext/nokogiri/xml_node_set.c @@ -350,7 +350,7 @@ static VALUE unlink_nodeset(VALUE self) nodeNr = node_set->nodeNr ; for (j = 0 ; j < nodeNr ; j++) { - if (! Nokogiri_namespace_eh(node_set->nodeTab[j])) { + if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) { VALUE node ; xmlNodePtr node_ptr; node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]); @@ -388,7 +388,7 @@ static void reify_node_set_namespaces(VALUE self) namespace_cache = rb_iv_get(self, "@namespace_cache"); for (j = 0 ; j < node_set->nodeNr ; j++) { - if (Nokogiri_namespace_eh(node_set->nodeTab[j])) { + if (NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) { rb_ary_push(namespace_cache, Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[j], self)); } } @@ -420,7 +420,7 @@ VALUE Nokogiri_wrap_xml_node_set_node(xmlNodePtr node, VALUE node_set) { xmlDocPtr document ; - if (Nokogiri_namespace_eh(node)) { + if (NOKOGIRI_NAMESPACE_EH(node)) { Data_Get_Struct(rb_iv_get(node_set, "@document"), xmlDoc, document); return Nokogiri_wrap_xml_namespace(document, (xmlNsPtr)node); } else { diff --git a/ext/nokogiri/xml_node_set.h b/ext/nokogiri/xml_node_set.h index 02a688cfe6..210eee3057 100644 --- a/ext/nokogiri/xml_node_set.h +++ b/ext/nokogiri/xml_node_set.h @@ -8,6 +8,5 @@ extern VALUE cNokogiriXmlNodeSet ; VALUE Nokogiri_wrap_xml_node_set(xmlNodeSetPtr node_set, VALUE document) ; VALUE Nokogiri_wrap_xml_node_set_node(xmlNodePtr node, VALUE node_set) ; VALUE Nokogiri_wrap_xml_node_set_namespace(xmlNsPtr node, VALUE node_set) ; -int Nokogiri_namespace_eh(xmlNodePtr node) ; #endif From ec91453bb1dc5a51b886499aa597865c1c892330 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Mar 2018 21:23:00 -0500 Subject: [PATCH 060/176] add @jvshahid and @larskanis to LICENSE and update the copyright date, and add Lars to the Gem authors list. [skip ci] --- LICENSE.md | 3 ++- Rakefile | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index c9c7d63f2a..248f4accb4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ (The MIT License) -Copyright (c) 2008 - 2017: +Copyright (c) 2008 - 2018: * [Aaron Patterson](http://tenderlovemaking.com) * [Mike Dalessio](http://mike.daless.io) @@ -10,6 +10,7 @@ Copyright (c) 2008 - 2017: * [Yoko Harada](http://yokolet.blogspot.com) * [Akinori MUSHA](https://akinori.org) * [John Shahid](https://github.com/jvshahid) +* [Lars Kanis](https://github.com/larskanis) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Rakefile b/Rakefile index 467f880530..86a75cdb87 100644 --- a/Rakefile +++ b/Rakefile @@ -107,6 +107,8 @@ HOE = Hoe.spec 'nokogiri' do developer 'Yoko Harada', 'yokolet@gmail.com' developer 'Tim Elliott', 'tle@holymonkey.com' developer 'Akinori MUSHA', 'knu@idaemons.org' + developer 'John Shahid', 'jvshahid@gmail.com' + developer 'Lars Kanis', 'lars@greiz-reinsdorf.de' license "MIT" From 85d0b62164ebec9b9148a89c196e01b1bdea6a2a Mon Sep 17 00:00:00 2001 From: suginoy Date: Sat, 10 Mar 2018 02:53:35 +0900 Subject: [PATCH 061/176] Enable Nokogiri::XML::NodeSet#index to pass a block It's expected to have the same interface as Array#index. --- lib/nokogiri/xml/node_set.rb | 11 ++++++++--- test/xml/test_node_set.rb | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 0a9b5a4c14..4de7460d39 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -43,9 +43,14 @@ def empty? end ### - # Returns the index of the first node in self that is == to +node+. Returns nil if no match is found. - def index(node) - each_with_index { |member, j| return j if member == node } + # Returns the index of the first node in self that is == to +node+ or meets the given block. Returns nil if no match is found. + def index(node = nil, &block) + if node + warn "given block not used" if block_given? + each_with_index { |member, j| return j if member == node } + elsif block_given? + each_with_index { |member, j| return j if yield(member) } + end nil end diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 46babd40bb..7701c1246f 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -563,6 +563,8 @@ def test_array_index assert_equal 3, employees.index(employees[3]) assert_nil employees.index(other) + assert_equal 3, employees.index {|employee| employee.search("employeeId/text()").to_s == "EMP0004" } + assert_nil employees.index {|employee| employee.search("employeeId/text()").to_s == "EMP0000" } end def test_slice_too_far From ca22ccbceb4d545f7adbd41ab4ec73885937f761 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Wed, 14 Mar 2018 21:43:55 +0100 Subject: [PATCH 062/176] Re-add gcc option -Wconst-qual --- ext/nokogiri/extconf.rb | 2 +- ext/nokogiri/html_element_description.c | 28 ++++++++++++------------- ext/nokogiri/xml_document.c | 5 ++--- ext/nokogiri/xml_namespace.c | 4 ++-- ext/nokogiri/xml_node.c | 6 +++--- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index 0c160419f0..1b0ca4ede6 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -434,7 +434,7 @@ def using_system_libraries? if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/] - $CFLAGS << " -Wall -Wextra -Wwrite-strings -Wmissing-noreturn -Winline" + $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wextra -Wmissing-noreturn -Winline" end case diff --git a/ext/nokogiri/html_element_description.c b/ext/nokogiri/html_element_description.c index 196757e99b..f5e9270d34 100644 --- a/ext/nokogiri/html_element_description.c +++ b/ext/nokogiri/html_element_description.c @@ -8,7 +8,7 @@ */ static VALUE required_attributes(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; VALUE list; int i; @@ -33,7 +33,7 @@ static VALUE required_attributes(VALUE self) */ static VALUE deprecated_attributes(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; VALUE list; int i; @@ -58,7 +58,7 @@ static VALUE deprecated_attributes(VALUE self) */ static VALUE optional_attributes(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; VALUE list; int i; @@ -83,7 +83,7 @@ static VALUE optional_attributes(VALUE self) */ static VALUE default_sub_element(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if (description->defaultsubelt) @@ -100,7 +100,7 @@ static VALUE default_sub_element(VALUE self) */ static VALUE sub_elements(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; VALUE list; int i; @@ -125,7 +125,7 @@ static VALUE sub_elements(VALUE self) */ static VALUE description(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); return NOKOGIRI_STR_NEW2(description->desc); @@ -139,7 +139,7 @@ static VALUE description(VALUE self) */ static VALUE inline_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->isinline) return Qtrue; @@ -154,7 +154,7 @@ static VALUE inline_eh(VALUE self) */ static VALUE deprecated_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->depr) return Qtrue; @@ -169,7 +169,7 @@ static VALUE deprecated_eh(VALUE self) */ static VALUE empty_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->empty) return Qtrue; @@ -184,7 +184,7 @@ static VALUE empty_eh(VALUE self) */ static VALUE save_end_tag_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->saveEndTag) return Qtrue; @@ -199,7 +199,7 @@ static VALUE save_end_tag_eh(VALUE self) */ static VALUE implied_end_tag_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->endTag) return Qtrue; @@ -214,7 +214,7 @@ static VALUE implied_end_tag_eh(VALUE self) */ static VALUE implied_start_tag_eh(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(description->startTag) return Qtrue; @@ -229,7 +229,7 @@ static VALUE implied_start_tag_eh(VALUE self) */ static VALUE name(VALUE self) { - htmlElemDesc * description; + const htmlElemDesc * description; Data_Get_Struct(self, htmlElemDesc, description); if(NULL == description->name) return Qnil; @@ -249,7 +249,7 @@ static VALUE get_description(VALUE klass, VALUE tag_name) ); if(NULL == description) return Qnil; - return Data_Wrap_Struct(klass, 0, 0, (void *)description); + return Data_Wrap_Struct(klass, 0, 0, (void *)(uintptr_t)description); } VALUE cNokogiriHtmlElementDescription ; diff --git a/ext/nokogiri/xml_document.c b/ext/nokogiri/xml_document.c index 33c147fca5..ca48ffac99 100644 --- a/ext/nokogiri/xml_document.c +++ b/ext/nokogiri/xml_document.c @@ -179,7 +179,7 @@ static VALUE set_encoding(VALUE self, VALUE encoding) Data_Get_Struct(self, xmlDoc, doc); if (doc->encoding) - free((char *) doc->encoding); /* this may produce a gcc cast warning */ + free((char *)(uintptr_t) doc->encoding); /* avoid gcc cast warning */ doc->encoding = xmlStrdup((xmlChar *)StringValueCStr(encoding)); @@ -531,8 +531,7 @@ static VALUE canonicalize(int argc, VALUE* argv, VALUE self) ns = calloc((size_t)ns_len+1, sizeof(xmlChar *)); for (i = 0 ; i < ns_len ; i++) { VALUE entry = rb_ary_entry(incl_ns, i); - const char * ptr = StringValueCStr(entry); - ns[i] = (xmlChar*) ptr; + ns[i] = (xmlChar*)StringValueCStr(entry); } } diff --git a/ext/nokogiri/xml_namespace.c b/ext/nokogiri/xml_namespace.c index bd27f2d07d..773fe919bb 100644 --- a/ext/nokogiri/xml_namespace.c +++ b/ext/nokogiri/xml_namespace.c @@ -14,10 +14,10 @@ static void dealloc_namespace(xmlNsPtr ns) */ NOKOGIRI_DEBUG_START(ns) ; if (ns->href) { - xmlFree((xmlChar *)ns->href); + xmlFree((xmlChar *)(uintptr_t)ns->href); } if (ns->prefix) { - xmlFree((xmlChar *)ns->prefix); + xmlFree((xmlChar *)(uintptr_t)ns->prefix); } xmlFree(ns); NOKOGIRI_DEBUG_END(ns) ; diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 46682f9815..3af6f9a4d4 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -841,10 +841,10 @@ static VALUE set(VALUE self, VALUE property, VALUE value) static VALUE get(VALUE self, VALUE rattribute) { xmlNodePtr node; - const xmlChar *value = 0; + xmlChar *value = 0; VALUE rvalue; xmlChar *colon; - const xmlChar *attribute, *attr_name, *prefix; + xmlChar *attribute, *attr_name, *prefix; xmlNsPtr ns; if (NIL_P(rattribute)) return Qnil; @@ -852,7 +852,7 @@ static VALUE get(VALUE self, VALUE rattribute) Data_Get_Struct(self, xmlNode, node); attribute = xmlCharStrdup(StringValueCStr(rattribute)); - colon = (xmlChar *)xmlStrchr(attribute, (const xmlChar)':'); + colon = (xmlChar *)(uintptr_t)xmlStrchr(attribute, (const xmlChar)':'); if (colon) { /* split the attribute string into separate prefix and name by * null-terminating the prefix at the colon */ From d78c44787961dab2161c1494992d3833b3593d7b Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Wed, 14 Mar 2018 22:02:33 +0100 Subject: [PATCH 063/176] Fix one remaining warning about const qualifier xmlNewCDataBlock() takes ptr and len, so we can use RSTRING_LEN() instead of strlen(). strlen() was introduced in commit c766f6e9b2ec7 to fix a segfault, but it's enough to execute StringValuePtr() and RSTRING_LEN() in order to avoid invalid memory access. --- ext/nokogiri/xml_cdata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/nokogiri/xml_cdata.c b/ext/nokogiri/xml_cdata.c index 636e7eeaa6..dd1b196507 100644 --- a/ext/nokogiri/xml_cdata.c +++ b/ext/nokogiri/xml_cdata.c @@ -17,7 +17,7 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) VALUE content; VALUE rest; VALUE rb_node; - const xmlChar *content_str = NULL; + xmlChar *content_str = NULL; int content_str_len = 0; rb_scan_args(argc, argv, "2*", &doc, &content, &rest); @@ -25,8 +25,8 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) Data_Get_Struct(doc, xmlDoc, xml_doc); if (!NIL_P(content)) { - content_str = (const xmlChar *)StringValueCStr(content); - content_str_len = strlen((char *)content_str); + content_str = (xmlChar *)StringValuePtr(content); + content_str_len = RSTRING_LEN(content); } node = xmlNewCDataBlock(xml_doc->doc, content_str, content_str_len); From 17befc25bc8389c983457546c56eb36434d6671b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 15 Mar 2018 16:41:06 -0400 Subject: [PATCH 064/176] SECURITY.md to publicize vuln reporting process [skip ci] --- README.md | 7 ++++++- SECURITY.md | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 SECURITY.md diff --git a/README.md b/README.md index bb3b321a0a..7c5f7657b8 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,11 @@ There are open-source tutorials (to which we invite contributions!) here: http:/ * The IRC channel is #nokogiri on freenode. +## Security and Vulnerability Reporting + +See [`SECURITY.md`](SECURITY.md) + + ## Synopsis Nokogiri is a large library, but here is example usage for parsing and examining a document: @@ -170,4 +175,4 @@ explicitly setting the encoding to EUC-JP on the parser: ## License -MIT. See the `LICENSE.md` file. +MIT. See [`LICENSE.md`](LICENSE.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..9b4616b00a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security and Vulnerability Reporting + +The Nokogiri Core Contributors take security very seriously and investigate all reported vulnerabilities. + +If you would like to report a vulnerablity or have a security concern regarding Nokogiri or how Nokogiri is using any of its underlying platform-specific libraries (such as libxml2 or xerces), please [report it via HackerOne](https://hackerone.com/nokogiri/reports/new). + +Your report will be acknowledged within 24 hours, and you'll receive a more detailed response within 72 hours indicating next steps in handling your report. + +If you have not received a reply to your submission within 48 hours, there are a few steps you can take: +* Contact the current security coordinator (Mike Dalessio ) +* Contact the core contributor mailing list (nokogiri-core@googlegroups.com) +* Join the [nokogiri-talk group](https://groups.google.com/d/forum/nokogiri-talk) + +Please note, the nokogiri-talk list is a public area. When escalating in that venue, please do not discuss your issue. Simply say that you're trying to get a hold of someone from the core team. + +The information you share with the Nokogiri Core Contributors as part of this process will be kept confidential within the team, unless or until we need to share information upstream with our dependent libraries' core teams, at which point we will notify you. + +If a vulnerability is first reported by you, we will credit you with the discovery in the public disclosure. From 7ffd1171c80a2278b43c89823a26f5ecabbbb24c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 15 Mar 2018 17:01:38 -0400 Subject: [PATCH 065/176] tweak SECURITY.md formatting so it renders well on nokogiri.org [skip ci] --- SECURITY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SECURITY.md b/SECURITY.md index 9b4616b00a..6a4b608d1d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,6 +7,7 @@ If you would like to report a vulnerablity or have a security concern regarding Your report will be acknowledged within 24 hours, and you'll receive a more detailed response within 72 hours indicating next steps in handling your report. If you have not received a reply to your submission within 48 hours, there are a few steps you can take: + * Contact the current security coordinator (Mike Dalessio ) * Contact the core contributor mailing list (nokogiri-core@googlegroups.com) * Join the [nokogiri-talk group](https://groups.google.com/d/forum/nokogiri-talk) From e3ffa8ffbff73eda3c0183642b4b47dff61216e9 Mon Sep 17 00:00:00 2001 From: Michael Genereux Date: Tue, 20 Mar 2018 11:25:37 -0700 Subject: [PATCH 066/176] Close unclosed tag Could I be wrong about this? --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7c5f7657b8..1974fc5964 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ best bet is to explicitly set the encoding. Here is an example of explicitly setting the encoding to EUC-JP on the parser: ```ruby - doc = Nokogiri.XML('', nil, 'EUC-JP') + doc = Nokogiri.XML('', nil, 'EUC-JP') ``` ## Development From 80205c49f9c10ddc78488352c4e98d5409a71547 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 21 Mar 2018 00:03:17 -0400 Subject: [PATCH 067/176] [JRuby] Node#replace supports Comment and CDATA Note that I deleted the offending line; this is because the calling method `adoptAs` always calls `relink_namespace`. I've also deleted the unused `post_add_child` function. --- CHANGELOG.md | 1 + ext/java/nokogiri/XmlNode.java | 7 ------- test/xml/test_node_reparenting.rb | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220233b638..94fc3e4f01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Bug fixes * CSS attribute selectors now gracefully handle queries using integers. [#711] +* [JRuby] Allow Node#replace to insert Comment and CDATA nodes. [#1666] # 1.8.2 / 2018-01-29 diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 508da09eb8..5e126817fc 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -437,9 +437,6 @@ protected String getAttribute(String key) { return value.length() == 0 ? null : value; } - public void post_add_child(ThreadContext context, XmlNode current, XmlNode child) { - } - /** * This method should be called after a node has been adopted in a new * document. This method will ensure that the node is renamed with the @@ -1591,7 +1588,6 @@ protected IRubyObject adoptAs(ThreadContext context, AdoptScheme scheme, } other.relink_namespace(context); - // post_add_child(context, this, other); return nodeOrTags; } @@ -1691,9 +1687,6 @@ protected void adoptAsReplacement(ThreadContext context, try { parentNode.replaceChild(otherNode, thisNode); - if (otherNode.getNodeType() != Node.TEXT_NODE) { - NokogiriHelpers.renameNode(otherNode, thisNode.getNamespaceURI(), otherNode.getNodeName()); - } } catch (Exception e) { String prefix = "could not replace child: "; throw context.getRuntime().newRuntimeError(prefix + e.toString()); diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index c67f87e5ad..02fbe56cc5 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -459,6 +459,24 @@ class TestNodeReparenting < Nokogiri::TestCase end end + it "can replace with a comment node" do + doc = Nokogiri::XML %Q{text} + replacee = doc.at_css("child") + replacer = doc.create_comment("text") + replacee.replace replacer + assert_equal 1, doc.root.children.length + assert_equal replacer, doc.root.children.first + end + + it "can replace with a CDATA node" do + doc = Nokogiri::XML %Q{text} + replacee = doc.at_css("child") + replacer = doc.create_cdata("text") + replacee.replace replacer + assert_equal 1, doc.root.children.length + assert_equal replacer, doc.root.children.first + end + describe "when a document has a default namespace" do before do @fruits = Nokogiri::XML(<<-eoxml) From b28c5f47385a72a48599d1d11288a7fd637da978 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 22 Mar 2018 11:19:46 -0400 Subject: [PATCH 068/176] update libxml2 dep from 2.9.7 to 2.9.8 --- dependencies.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dependencies.yml b/dependencies.yml index f6ab5430a5..fbf5e249d5 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -1,10 +1,10 @@ libxml2: - version: "2.9.7" - sha256: "f63c5e7d30362ed28b38bfa1ac6313f9a80230720b7fb6c80575eeab3ff5900c" + version: "2.9.8" + sha256: "0b74e51595654f958148759cfef0993114ddccccbb6f31aee018f3558e8e2732" # manually verified checksum: # - # $ gpg --verify libxml2-2.9.7.tar.gz.asc libxml2-2.9.7.tar.gz - # gpg: Signature made Thu 02 Nov 2017 04:17:54 PM EDT using RSA key ID 596BEA5D + # $ gpg --verify libxml2-2.9.8.tar.gz.asc ./ports/archives/libxml2-2.9.8.tar.gz + # gpg: Signature made Mon 05 Mar 2018 11:07:45 AM EST using RSA key ID 596BEA5D # gpg: Good signature from "Daniel Veillard (Red Hat work email) " # gpg: aka "Daniel Veillard " # gpg: WARNING: This key is not certified with a trusted signature! @@ -15,13 +15,13 @@ libxml2: # using this pgp signature: # -----BEGIN PGP SIGNATURE----- # - # iQEcBAABAgAGBQJZ+31yAAoJEBVYiyZZa+pd+MMH/RTsPCo8CegAHsSUlNCae2Ay - # HpM6J7sNWs0b2xwaYRtwhewJ5z/rsCcM5nn7MeGiU8dX7W5MKF69uGXUywufRxzO - # GFoQSxO0a1z5mtGu7jC/W6DTYHFBeOJcEfMa3zUZjZ0RXqrENRhX55okse4pJPmG - # dWQphbu9G3qoCuWD7QpyI7Mjhjemmyi4Ai/4vJPO8WtB7VDfdtpuZFVCRLG2cp0X - # 90SZde+0oWJcN8oIG3FaTd7O4OuJPAceqNhTvF90dLvqSqRBd0RqZNnjYNYZ6uRy - # FQSlQBVCxdLY0AI7Yooq79TJD+0vcqiQNwQwH7L+hBWgvPos4DKN1M9LaJc/RTk= - # =5Qzo + # iQEcBAABAgAGBQJanWtRAAoJEBVYiyZZa+pdV7oIAJWdFahwt+reN/Zt2RPmjjcr + # eSsY7UV1RXjScnNjTzJT1h2hJ7SnUjCkqjR6VdtKDUIzpuX+S2U83joafJH6mxUb + # yw2nO4RfjYTPxpz5JkvqT7jmgEIaD81BuwcMehqpMpIfiKa2NgO1DSfZxgs8a9E2 + # +ehc/kZWuI5gmNGrd84EEWUqpYW/Xx7jy02osioJuU5IMPjzZKNR3maXp9oAKeBc + # S2QNa1ID/pUk3K3M/5nlwNgAtQ7lxQrqhrSma2dsKt/IpL6VXomxuD4Bh1r2MZhX + # uZ456X/xJN8UmPewLZWGBU1MK9wqu3Zx5Qwz64H6UdlYIzXZ2jXj2YWZa6xkxPA= + # =69xn # -----END PGP SIGNATURE----- # From 36a0151d651b189a85b4d71df28335f6c499ca36 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 22 Mar 2018 11:22:56 -0400 Subject: [PATCH 069/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94fc3e4f01..650db95b00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # unreleased +## Dependencies + +* [MRI] libxml2 is updated from 2.9.7 to 2.9.8 + + ## Bug fixes * CSS attribute selectors now gracefully handle queries using integers. [#711] From ba616e44ca42b70a4bf4682b9edbacab1b6726d7 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 22 Mar 2018 11:26:49 -0400 Subject: [PATCH 070/176] Filters out PRs that have `[ci skip]` message [skip ci] --- concourse/nokogiri.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 0e0da712ea..f088ae58c7 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -71,6 +71,7 @@ resources: access_token: {{github-repo-status-access-token}} ignore_paths: - concourse/** + ci_skip: true jobs: # From 308d70cd853f0254a8693e793c0e23dda7a1d702 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 22 Mar 2018 13:36:49 -0400 Subject: [PATCH 071/176] [concourse] removing jruby-1.7 support - remove job from PR pipeline - move master job into "allow-failure" group [partly addresses #1741] --- concourse/nokogiri.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index f088ae58c7..8beefc45cd 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -11,7 +11,7 @@ groups: - "ruby-libxmlruby-vendored" - "ruby-libxmlruby-valgrind" <% end %> - <% for jruby_version in RUBIES[:jruby] %> + <% for jruby_version in RUBIES[:jruby].last(1) %> - "jruby-<%= jruby_version %>" <% end %> <% for rbx_version in RUBIES[:rbx] %> @@ -32,7 +32,6 @@ groups: - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr - - jruby-<%= RUBIES[:jruby].first %>-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - pr-success @@ -42,6 +41,7 @@ groups: <% RUBIES[:windows].last(2).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> + - "jruby-<%= RUBIES[:jruby].first %>" resource_types: @@ -71,7 +71,6 @@ resources: access_token: {{github-repo-status-access-token}} ignore_paths: - concourse/** - ci_skip: true jobs: # @@ -384,7 +383,7 @@ jobs: params: {path: nokogiri-pr, status: failure} <% end %> - <% [RUBIES[:jruby].first, RUBIES[:jruby].last].each do |jruby_version| %> +% jruby_version = RUBIES[:jruby].last - name: jruby-<%= jruby_version %>-pr public: true max_in_flight: 1 @@ -411,7 +410,6 @@ jobs: on_failure: put: nokogiri-pr params: {path: nokogiri-pr, status: failure} - <% end %> % rbx_version = RUBIES[:rbx].last - name: rbx-<%= rbx_version %>-pr @@ -456,7 +454,6 @@ jobs: - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr - - jruby-<%= RUBIES[:jruby].first %>-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - put: nokogiri-pr From 2e89378806d5b3590e1a9bb44c900a0474b21c0a Mon Sep 17 00:00:00 2001 From: John Shahid Date: Sun, 25 Mar 2018 10:18:34 -0400 Subject: [PATCH 072/176] remove monkey patch introduced in #1251 this is an ugly change whose only purpose is to mask the difference between libxml and nekohtml. we agreed to stop doing that a while ago and just accept that different libraries will behave different. furthermore, it caused a stack overflow while parding documents with a TD element that doesn't have any parents in #1501 fixes #1501 --- ext/java/nokogiri/NokogiriService.java | 19 ------------ test/css/test_nthiness.rb | 42 +++++++++++++------------- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/ext/java/nokogiri/NokogiriService.java b/ext/java/nokogiri/NokogiriService.java index 068429a148..6b40e61260 100644 --- a/ext/java/nokogiri/NokogiriService.java +++ b/ext/java/nokogiri/NokogiriService.java @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Map; -import org.cyberneko.html.HTMLElements; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; @@ -54,24 +53,6 @@ * @author Yoko Harada */ public class NokogiriService implements BasicLibraryService { - - // nekohtml from version 1.9.13 they autocomplete tbody around - // tr tags of a table - http://sourceforge.net/p/nekohtml/code/241/ - // this monkey patch undoes this autocompletion - static class MonkeyPatchHTMLElements extends HTMLElements { - static void patchIt() { - Element[] array = ELEMENTS_ARRAY['T'-'A']; - for(int i = 0; i < array.length; i++) { - if (array[i].name.equals("TR")) { - array[i] = new Element(TR, "TR", Element.BLOCK, TABLE, new short[]{TD,TH,TR,COLGROUP,DIV}); - } - } - } - } - static { - MonkeyPatchHTMLElements.patchIt(); - } - public boolean basicLoad(Ruby ruby) { init(ruby); return true; diff --git a/test/css/test_nthiness.rb b/test/css/test_nthiness.rb index ef403aece0..7625c1c0d8 100644 --- a/test/css/test_nthiness.rb +++ b/test/css/test_nthiness.rb @@ -71,83 +71,83 @@ def setup def test_even - assert_result_rows [2,4,6,8,10,12,14], @parser.search("table/tr:nth(even)") + assert_result_rows [2,4,6,8,10,12,14], @parser.search("table//tr:nth(even)") end def test_odd - assert_result_rows [1,3,5,7,9,11,13], @parser.search("table/tr:nth(odd)") + assert_result_rows [1,3,5,7,9,11,13], @parser.search("table//tr:nth(odd)") end def test_n - assert_result_rows((1..14).to_a, @parser.search("table/tr:nth(n)")) + assert_result_rows((1..14).to_a, @parser.search("table//tr:nth(n)")) end def test_2n - assert_equal @parser.search("table/tr:nth(even)").inner_text, @parser.search("table/tr:nth(2n)").inner_text + assert_equal @parser.search("table//tr:nth(even)").inner_text, @parser.search("table//tr:nth(2n)").inner_text end def test_2np1 - assert_equal @parser.search("table/tr:nth(odd)").inner_text, @parser.search("table/tr:nth(2n+1)").inner_text + assert_equal @parser.search("table//tr:nth(odd)").inner_text, @parser.search("table//tr:nth(2n+1)").inner_text end def test_4np3 - assert_result_rows [3,7,11], @parser.search("table/tr:nth(4n+3)") + assert_result_rows [3,7,11], @parser.search("table//tr:nth(4n+3)") end def test_3np4 - assert_result_rows [4,7,10,13], @parser.search("table/tr:nth(3n+4)") + assert_result_rows [4,7,10,13], @parser.search("table//tr:nth(3n+4)") end def test_mnp3 - assert_result_rows [1,2,3], @parser.search("table/tr:nth(-n+3)") + assert_result_rows [1,2,3], @parser.search("table//tr:nth(-n+3)") end def test_4nm1 - assert_result_rows [3,7,11], @parser.search("table/tr:nth(4n-1)") + assert_result_rows [3,7,11], @parser.search("table//tr:nth(4n-1)") end def test_np3 - assert_result_rows [3,4,5,6,7,8,9,10,11,12,13,14], @parser.search("table/tr:nth(n+3)") + assert_result_rows [3,4,5,6,7,8,9,10,11,12,13,14], @parser.search("table//tr:nth(n+3)") end def test_first - assert_result_rows [1], @parser.search("table/tr:first") - assert_result_rows [1], @parser.search("table/tr:first()") + assert_result_rows [1], @parser.search("table//tr:first") + assert_result_rows [1], @parser.search("table//tr:first()") end def test_last - assert_result_rows [14], @parser.search("table/tr:last") - assert_result_rows [14], @parser.search("table/tr:last()") + assert_result_rows [14], @parser.search("table//tr:last") + assert_result_rows [14], @parser.search("table//tr:last()") end def test_first_child assert_result_rows [1], @parser.search("div/b:first-child"), "bold" - assert_result_rows [1], @parser.search("table/tr:first-child") + assert_result_rows [1], @parser.search("table//tr:first-child") assert_result_rows [2,4], @parser.search("div/h1.c:first-child"), "header" end def test_last_child assert_result_rows [3], @parser.search("div/b:last-child"), "bold" - assert_result_rows [14], @parser.search("table/tr:last-child") + assert_result_rows [14], @parser.search("table//tr:last-child") assert_result_rows [3,4], @parser.search("div/h1.c:last-child"), "header" end def test_nth_child assert_result_rows [2], @parser.search("div/b:nth-child(3)"), "bold" - assert_result_rows [5], @parser.search("table/tr:nth-child(5)") + assert_result_rows [5], @parser.search("table//tr:nth-child(5)") assert_result_rows [1,3], @parser.search("div/h1.c:nth-child(2)"), "header" assert_result_rows [3,4], @parser.search("div/i.b:nth-child(2n+1)"), "italic" end def test_first_of_type - assert_result_rows [1], @parser.search("table/tr:first-of-type") + assert_result_rows [1], @parser.search("table//tr:first-of-type") assert_result_rows [1], @parser.search("div/b:first-of-type"), "bold" assert_result_rows [2], @parser.search("div/b.a:first-of-type"), "bold" assert_result_rows [3], @parser.search("div/i.b:first-of-type"), "italic" end def test_last_of_type - assert_result_rows [14], @parser.search("table/tr:last-of-type") + assert_result_rows [14], @parser.search("table//tr:last-of-type") assert_result_rows [3], @parser.search("div/b:last-of-type"), "bold" assert_result_rows [2,7], @parser.search("div/i:last-of-type"), "italic" assert_result_rows [2,6,7], @parser.search("div i:last-of-type"), "italic" @@ -165,8 +165,8 @@ def test_nth_of_type end def test_nth_last_of_type - assert_result_rows [14], @parser.search("table/tr:nth-last-of-type(1)") - assert_result_rows [12], @parser.search("table/tr:nth-last-of-type(3)") + assert_result_rows [14], @parser.search("table//tr:nth-last-of-type(1)") + assert_result_rows [12], @parser.search("table//tr:nth-last-of-type(3)") assert_result_rows [2,6,7], @parser.search("div i:nth-last-of-type(1)"), "italic" assert_result_rows [1,5], @parser.search("div i:nth-last-of-type(2)"), "italic" assert_result_rows [4], @parser.search("div/i.b:nth-last-of-type(1)"), "italic" From fdae6a3ad3e4f982d21f399153b279ddf833657c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 27 Mar 2018 21:50:43 -0400 Subject: [PATCH 073/176] jruby 1.7 is passing now not sure what was going on there --- concourse/nokogiri.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 8beefc45cd..d66aaca4f0 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -11,7 +11,7 @@ groups: - "ruby-libxmlruby-vendored" - "ruby-libxmlruby-valgrind" <% end %> - <% for jruby_version in RUBIES[:jruby].last(1) %> + <% for jruby_version in RUBIES[:jruby] %> - "jruby-<%= jruby_version %>" <% end %> <% for rbx_version in RUBIES[:rbx] %> @@ -41,7 +41,6 @@ groups: <% RUBIES[:windows].last(2).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> - - "jruby-<%= RUBIES[:jruby].first %>" resource_types: From e4455409700f182d5f9cac9e78946d602657aa1d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 27 Mar 2018 22:53:47 -0400 Subject: [PATCH 074/176] concourse: irc notifications [skip ci] --- concourse/nokogiri.yml | 69 ++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index d66aaca4f0..f573d742cd 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -6,7 +6,7 @@ groups: - "ruby-<%= ruby_version %>-vendored" - "ruby-<%= ruby_version %>-valgrind" <% end %> - <% for ruby_version in RUBIES[:mri][-1,1] %> + <% for ruby_version in RUBIES[:mri].last(1) %> - "ruby-libxmlruby-system" - "ruby-libxmlruby-vendored" - "ruby-libxmlruby-valgrind" @@ -21,6 +21,7 @@ groups: <% RUBIES[:windows].first(1).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> + - build-success - name: PRs @@ -48,6 +49,10 @@ resource_types: type: docker-image source: repository: jtarchie/pr +- name: irc-notification + type: docker-image + source: + repository: flavorjones/irc-notification-resource resources: - name: ci @@ -70,6 +75,22 @@ resources: access_token: {{github-repo-status-access-token}} ignore_paths: - concourse/** + - name: nokogiri-irc + type: irc-notification + source: + server: chat.freenode.net + port: 7070 + channel: "#nokogiri" + user: {{nokobot-irc-username}} + password: {{nokobot-irc-password}} + +anchors: + notify_failure_to_irc: ¬ify_failure_to_irc + put: nokogiri-irc + params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build failed ($BUILD_URL)"} + notify_failure_to_pr: ¬ify_failure_to_pr + put: nokogiri-pr + params: {path: nokogiri-pr, status: failure} jobs: # @@ -95,6 +116,7 @@ jobs: NOKOGIRI_USE_SYSTEM_LIBRARIES: t run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc - name: ruby-<%= ruby_version %>-vendored public: true @@ -114,6 +136,7 @@ jobs: - name: nokogiri run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc - name: ruby-<%= ruby_version %>-valgrind public: true @@ -135,6 +158,7 @@ jobs: TEST_WITH_VALGRIND: t run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc <% end %> % ruby_version = RUBIES[:mri].last @@ -158,6 +182,7 @@ jobs: NOKOGIRI_USE_SYSTEM_LIBRARIES: t run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc - name: ruby-libxmlruby-vendored public: true @@ -179,6 +204,7 @@ jobs: BUNDLE_GEMFILE: "Gemfile-libxml-ruby" run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc - name: ruby-libxmlruby-valgrind public: true @@ -201,6 +227,7 @@ jobs: TEST_WITH_VALGRIND: t run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc <% for jruby_version in RUBIES[:jruby] %> - name: jruby-<%= jruby_version %> @@ -222,6 +249,7 @@ jobs: JAVA_OPTS: "-Dfile.encoding=UTF8" # https://github.com/docker-library/openjdk/issues/32 run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc <% end %> <% for rbx_version in RUBIES[:rbx] %> @@ -245,6 +273,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc - name: rbx-<%= rbx_version %>-vendored public: true @@ -266,6 +295,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc <% end %> <% for ruby_version in RUBIES[:windows] %> @@ -288,6 +318,23 @@ jobs: args: ["-File", "ci/concourse/tasks/rake-test/run.ps1"] <% end %> + - name: build-success + public: true +# disable_manual_trigger: true + plan: + - get: nokogiri + trigger: true + version: every + passed: + <% for ruby_version in RUBIES[:mri] %> + - "ruby-<%= ruby_version %>-valgrind" + <% end %> + <% for ruby_version in RUBIES[:mri].last(1) %> + - "ruby-libxmlruby-valgrind" + <% end %> + - put: nokogiri-irc + params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"} + # # PRs # @@ -325,9 +372,7 @@ jobs: NOKOGIRI_USE_SYSTEM_LIBRARIES: t run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: - put: nokogiri-pr - params: {path: nokogiri-pr, status: failure} + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } - name: ruby-<%= ruby_version %>-vendored-pr public: true @@ -350,9 +395,7 @@ jobs: path: nokogiri run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: - put: nokogiri-pr - params: {path: nokogiri-pr, status: failure} + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } - name: ruby-<%= ruby_version %>-valgrind-pr public: true @@ -377,9 +420,7 @@ jobs: TEST_WITH_VALGRIND: t run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: - put: nokogiri-pr - params: {path: nokogiri-pr, status: failure} + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } <% end %> % jruby_version = RUBIES[:jruby].last @@ -406,9 +447,7 @@ jobs: JAVA_OPTS: "-Dfile.encoding=UTF8" # https://github.com/docker-library/openjdk/issues/32 run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: - put: nokogiri-pr - params: {path: nokogiri-pr, status: failure} + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } % rbx_version = RUBIES[:rbx].last - name: rbx-<%= rbx_version %>-pr @@ -435,9 +474,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: - put: nokogiri-pr - params: {path: nokogiri-pr, status: failure} + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } - name: pr-success public: true From f7d92d50e0673f4d15e233157d2364e9265328fa Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 27 Mar 2018 23:14:04 -0400 Subject: [PATCH 075/176] concourse: disable manual trigger of build-success [skip ci] --- concourse/nokogiri.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index f573d742cd..ddee528388 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -320,7 +320,7 @@ jobs: - name: build-success public: true -# disable_manual_trigger: true + disable_manual_trigger: true plan: - get: nokogiri trigger: true From 943d0c6601e954308b69c1a85ba5b8442b5c777f Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 27 Mar 2018 23:14:21 -0400 Subject: [PATCH 076/176] concourse: more complete build-success [skip ci] --- concourse/nokogiri.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index ddee528388..3d02b19bcf 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -332,6 +332,15 @@ jobs: <% for ruby_version in RUBIES[:mri].last(1) %> - "ruby-libxmlruby-valgrind" <% end %> + <% for jruby_version in RUBIES[:jruby] %> + - "jruby-<%= jruby_version %>" + <% end %> + <% for rbx_version in RUBIES[:rbx] %> + - "rbx-<%= rbx_version %>-vendored" + <% end %> + <% RUBIES[:windows].first(1).each do |ruby_version| %> + - "win-ruby-<%= ruby_version %>-devkit" + <% end %> - put: nokogiri-irc params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"} From 935da041f55ed33d8ec2eda0767ff922d4f17244 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 27 Mar 2018 23:14:33 -0400 Subject: [PATCH 077/176] concourse: pr-success notifies irc [skip ci] --- concourse/nokogiri.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 3d02b19bcf..646fb4245b 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -503,3 +503,5 @@ jobs: - rbx-<%= RUBIES[:rbx].last %>-pr - put: nokogiri-pr params: {path: nokogiri-pr, status: success} + - put: nokogiri-irc + params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"} From 41c46be99a2ca0345cae3c7c819aed7db360281a Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:07:05 -0400 Subject: [PATCH 078/176] update Manifest to include SECURITY.md [skip ci] --- Manifest.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Manifest.txt b/Manifest.txt index 5c7f4f0aa3..30e45673ba 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -14,6 +14,7 @@ Manifest.txt README.md ROADMAP.md Rakefile +SECURITY.md STANDARD_RESPONSES.md Y_U_NO_GEMSPEC.md appveyor.yml From 6c58c55d0d8f8ed5ddd64acba42b7abb154783e3 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:05:09 -0400 Subject: [PATCH 079/176] add test demonstrating libxml2 XSS vulnerability libxml2 >= 2.9.2 fails to escape comments within some attributes. It wants to ensure these comments can be treated as "server-side includes", but as a result fails to ensure that serialization is well-formed, resulting in an opportunity for XSS injection of code into a final re-parsed document (presumably in a browser). the offending commit is: https://github.com/GNOME/libxml2/commit/960f0e2 we'll test this by parsing the HTML, serializing it, then re-parsing it to ensure there isn't any ambiguity in the output that might allow code injection into a browser consuming "sanitized" output. complaints have been made upstream about this behavior, notably at https://bugzilla.gnome.org/show_bug.cgi?id=769760 and multiple CVEs have been declared and fixed in downstream libraries as a result, a list is being kept up to date here: https://github.com/flavorjones/loofah/issues/144 --- Manifest.txt | 1 + test/html/test_attributes.rb | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 test/html/test_attributes.rb diff --git a/Manifest.txt b/Manifest.txt index 30e45673ba..93cc0c08d4 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -301,6 +301,7 @@ test/html/sax/test_parser.rb test/html/sax/test_parser_context.rb test/html/sax/test_parser_text.rb test/html/sax/test_push_parser.rb +test/html/test_attributes.rb test/html/test_builder.rb test/html/test_document.rb test/html/test_document_encoding.rb diff --git a/test/html/test_attributes.rb b/test/html/test_attributes.rb new file mode 100644 index 0000000000..8536f0c91b --- /dev/null +++ b/test/html/test_attributes.rb @@ -0,0 +1,83 @@ +require "helper" + +module Nokogiri + module HTML + class TestAttr < Nokogiri::TestCase + # + # libxml2 >= 2.9.2 fails to escape comments within some attributes. It + # wants to ensure these comments can be treated as "server-side includes", + # but as a result fails to ensure that serialization is well-formed, + # resulting in an opportunity for XSS injection of code into a final + # re-parsed document (presumably in a browser). + # + # the offending commit is: + # + # https://github.com/GNOME/libxml2/commit/960f0e2 + # + # we'll test this by parsing the HTML, serializing it, then + # re-parsing it to ensure there isn't any ambiguity in the output + # that might allow code injection into a browser consuming + # "sanitized" output. + # + # complaints have been made upstream about this behavior, notably at + # + # https://bugzilla.gnome.org/show_bug.cgi?id=769760 + # + # and multiple CVEs have been declared and fixed in downstream + # libraries as a result, a list is being kept up to date here: + # + # https://github.com/flavorjones/loofah/issues/144 + # + [ + # + # these tags and attributes are determined by the code at: + # + # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714 + # + {tag: "a", attr: "href"}, + {tag: "div", attr: "href"}, + {tag: "a", attr: "action"}, + {tag: "div", attr: "action"}, + {tag: "a", attr: "src"}, + {tag: "div", attr: "src"}, + {tag: "a", attr: "name"}, + # + # note that div+name is _not_ affected by the libxml2 issue. + # but we test it anyway to ensure our logic isn't modifying + # attributes that don't need modifying. + # + {tag: "div", attr: "name", unescaped: true}, + ].each do |config| + + define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do + html = %{<#{config[:tag]} #{config[:attr]}='example.com'>test} + + reparsed = HTML.fragment(HTML.fragment(html).to_html) + attributes = reparsed.at_css(config[:tag]).attribute_nodes + + assert_equal [config[:attr]], attributes.collect(&:name) + if Nokogiri::VersionInfo.instance.libxml2? + if config[:unescaped] + # + # this attribute was emitted wrapped in single-quotes, so a double quote is A-OK. + # assert that this attribute's serialization is unaffected. + # + assert_equal %{example.com}, attributes.first.value + else + # + # let's match the behavior in libxml < 2.9.2. + # test that this attribute's serialization is well-formed and sanitized. + # + assert_equal %{example.com}, attributes.first.value + end + else + # + # yay for consistency in javaland. move along, nothing to see here. + # + assert_equal %{example.com}, attributes.first.value + end + end + end + end + end +end From 38721829c1df30e93bdfbc88095cc36838e497f3 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:14:50 -0400 Subject: [PATCH 080/176] revert libxml2 commit 960f0e2 to restore original behavior around escaping html attributes related to commit 6c58c55 --- Manifest.txt | 1 + ...t-URI-escape-in-server-side-includes.patch | 78 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch diff --git a/Manifest.txt b/Manifest.txt index 93cc0c08d4..aa62f20966 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -250,6 +250,7 @@ lib/xalan.jar lib/xercesImpl.jar lib/xml-apis.jar lib/xsd/xmlparser/nokogiri.rb +patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch patches/sort-patches-by-date suppressions/README.txt suppressions/nokogiri_ruby-2.supp diff --git a/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch b/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch new file mode 100644 index 0000000000..e3ef2f2a68 --- /dev/null +++ b/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch @@ -0,0 +1,78 @@ +From c5538465c08a8ea248a370bf55bc39cd3385e4af Mon Sep 17 00:00:00 2001 +From: Mike Dalessio +Date: Thu, 29 Mar 2018 14:09:00 -0400 +Subject: [PATCH] Revert "Do not URI escape in server side includes" + +This reverts commit 960f0e275616cadc29671a218d7fb9b69eb35588. +--- + HTMLtree.c | 49 +++++++++++-------------------------------------- + 1 file changed, 11 insertions(+), 38 deletions(-) + +diff --git a/HTMLtree.c b/HTMLtree.c +index 2fd0c9c..67160c5 100644 +--- a/HTMLtree.c ++++ b/HTMLtree.c +@@ -717,49 +717,22 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, + (!xmlStrcasecmp(cur->name, BAD_CAST "src")) || + ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) && + (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) { ++ xmlChar *escaped; + xmlChar *tmp = value; +- /* xmlURIEscapeStr() escapes '"' so it can be safely used. */ +- xmlBufCCat(buf->buffer, "\""); + + while (IS_BLANK_CH(*tmp)) tmp++; + +- /* URI Escape everything, except server side includes. */ +- for ( ; ; ) { +- xmlChar *escaped; +- xmlChar endChar; +- xmlChar *end = NULL; +- xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST ""); +- if (end != NULL) { +- *start = '\0'; +- } +- } +- +- /* Escape the whole string, or until start (set to '\0'). */ +- escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+"); +- if (escaped != NULL) { +- xmlBufCat(buf->buffer, escaped); +- xmlFree(escaped); +- } else { +- xmlBufCat(buf->buffer, tmp); +- } +- +- if (end == NULL) { /* Everything has been written. */ +- break; +- } +- +- /* Do not escape anything within server side includes. */ +- *start = '<'; /* Restore the first character of "") */ +- endChar = *end; +- *end = '\0'; +- xmlBufCat(buf->buffer, start); +- *end = endChar; +- tmp = end; ++ /* ++ * the < and > have already been escaped at the entity level ++ * And doing so here breaks server side includes ++ */ ++ escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>"); ++ if (escaped != NULL) { ++ xmlBufWriteQuotedString(buf->buffer, escaped); ++ xmlFree(escaped); ++ } else { ++ xmlBufWriteQuotedString(buf->buffer, value); + } +- +- xmlBufCCat(buf->buffer, "\""); + } else { + xmlBufWriteQuotedString(buf->buffer, value); + } +-- +2.9.5 + From bb3da713848b0ff2fe09bb2349cd7cafd73f5f99 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:22:10 -0400 Subject: [PATCH 081/176] update CHANGELOG --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 650db95b00..5de2bd11ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # unreleased +## Security Notes + +[MRI] Behavior in libxml2 has been reverted which caused CVE-2018-8048 (loofah gem), CVE-2018-3740 (sanitize gem), and CVE-2018-3741 (rails-html-sanitizer gem). The commit in question is here: + +> https://github.com/GNOME/libxml2/commit/960f0e2 + +and more information is available about this commit and its impact here: + +> https://github.com/flavorjones/loofah/issues/144 + +This release simply reverts the libxml2 commit in question to protect users of Nokogiri's vendored libraries from similar vulnerabilities. + +If you're offended by what happened here, I'd kindly ask that you comment on the upstream bug report here: + +> https://bugzilla.gnome.org/show_bug.cgi?id=769760 + + ## Dependencies * [MRI] libxml2 is updated from 2.9.7 to 2.9.8 From 57ba668d24e32ab60707d0a71bcbb5e62e6bb33b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:46:48 -0400 Subject: [PATCH 082/176] skip unsafe attr tests if using system libraries because upstream has a bug which is likely in all the distros' versions as well. --- test/html/test_attributes.rb | 122 ++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/test/html/test_attributes.rb b/test/html/test_attributes.rb index 8536f0c91b..9d97c1322b 100644 --- a/test/html/test_attributes.rb +++ b/test/html/test_attributes.rb @@ -3,78 +3,80 @@ module Nokogiri module HTML class TestAttr < Nokogiri::TestCase - # - # libxml2 >= 2.9.2 fails to escape comments within some attributes. It - # wants to ensure these comments can be treated as "server-side includes", - # but as a result fails to ensure that serialization is well-formed, - # resulting in an opportunity for XSS injection of code into a final - # re-parsed document (presumably in a browser). - # - # the offending commit is: - # - # https://github.com/GNOME/libxml2/commit/960f0e2 - # - # we'll test this by parsing the HTML, serializing it, then - # re-parsing it to ensure there isn't any ambiguity in the output - # that might allow code injection into a browser consuming - # "sanitized" output. - # - # complaints have been made upstream about this behavior, notably at - # - # https://bugzilla.gnome.org/show_bug.cgi?id=769760 - # - # and multiple CVEs have been declared and fixed in downstream - # libraries as a result, a list is being kept up to date here: - # - # https://github.com/flavorjones/loofah/issues/144 - # - [ + unless Nokogiri::VersionInfo.instance.libxml2? && Nokogiri::VersionInfo.instance.libxml2_using_system? # - # these tags and attributes are determined by the code at: + # libxml2 >= 2.9.2 fails to escape comments within some attributes. It + # wants to ensure these comments can be treated as "server-side includes", + # but as a result fails to ensure that serialization is well-formed, + # resulting in an opportunity for XSS injection of code into a final + # re-parsed document (presumably in a browser). # - # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714 + # the offending commit is: # - {tag: "a", attr: "href"}, - {tag: "div", attr: "href"}, - {tag: "a", attr: "action"}, - {tag: "div", attr: "action"}, - {tag: "a", attr: "src"}, - {tag: "div", attr: "src"}, - {tag: "a", attr: "name"}, + # https://github.com/GNOME/libxml2/commit/960f0e2 # - # note that div+name is _not_ affected by the libxml2 issue. - # but we test it anyway to ensure our logic isn't modifying - # attributes that don't need modifying. + # we'll test this by parsing the HTML, serializing it, then + # re-parsing it to ensure there isn't any ambiguity in the output + # that might allow code injection into a browser consuming + # "sanitized" output. # - {tag: "div", attr: "name", unescaped: true}, - ].each do |config| + # complaints have been made upstream about this behavior, notably at + # + # https://bugzilla.gnome.org/show_bug.cgi?id=769760 + # + # and multiple CVEs have been declared and fixed in downstream + # libraries as a result, a list is being kept up to date here: + # + # https://github.com/flavorjones/loofah/issues/144 + # + [ + # + # these tags and attributes are determined by the code at: + # + # https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714 + # + {tag: "a", attr: "href"}, + {tag: "div", attr: "href"}, + {tag: "a", attr: "action"}, + {tag: "div", attr: "action"}, + {tag: "a", attr: "src"}, + {tag: "div", attr: "src"}, + {tag: "a", attr: "name"}, + # + # note that div+name is _not_ affected by the libxml2 issue. + # but we test it anyway to ensure our logic isn't modifying + # attributes that don't need modifying. + # + {tag: "div", attr: "name", unescaped: true}, + ].each do |config| - define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do - html = %{<#{config[:tag]} #{config[:attr]}='example.com'>test} + define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do + html = %{<#{config[:tag]} #{config[:attr]}='example.com'>test} - reparsed = HTML.fragment(HTML.fragment(html).to_html) - attributes = reparsed.at_css(config[:tag]).attribute_nodes + reparsed = HTML.fragment(HTML.fragment(html).to_html) + attributes = reparsed.at_css(config[:tag]).attribute_nodes - assert_equal [config[:attr]], attributes.collect(&:name) - if Nokogiri::VersionInfo.instance.libxml2? - if config[:unescaped] - # - # this attribute was emitted wrapped in single-quotes, so a double quote is A-OK. - # assert that this attribute's serialization is unaffected. - # - assert_equal %{example.com}, attributes.first.value + assert_equal [config[:attr]], attributes.collect(&:name) + if Nokogiri::VersionInfo.instance.libxml2? + if config[:unescaped] + # + # this attribute was emitted wrapped in single-quotes, so a double quote is A-OK. + # assert that this attribute's serialization is unaffected. + # + assert_equal %{example.com}, attributes.first.value + else + # + # let's match the behavior in libxml < 2.9.2. + # test that this attribute's serialization is well-formed and sanitized. + # + assert_equal %{example.com}, attributes.first.value + end else # - # let's match the behavior in libxml < 2.9.2. - # test that this attribute's serialization is well-formed and sanitized. + # yay for consistency in javaland. move along, nothing to see here. # - assert_equal %{example.com}, attributes.first.value + assert_equal %{example.com}, attributes.first.value end - else - # - # yay for consistency in javaland. move along, nothing to see here. - # - assert_equal %{example.com}, attributes.first.value end end end From a46408a780c805251c60f73d15cb47558a3b8c4e Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 14:54:49 -0400 Subject: [PATCH 083/176] address compiler warnings on libxml2 2.9.8 note that this causes compiler warnings on libxml2 < 2.9.8, which is just something we'll have to deal with. :-( --- ext/nokogiri/xml_dtd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/nokogiri/xml_dtd.c b/ext/nokogiri/xml_dtd.c index f70dcdef90..e9ca71aafc 100644 --- a/ext/nokogiri/xml_dtd.c +++ b/ext/nokogiri/xml_dtd.c @@ -1,6 +1,6 @@ #include -static void notation_copier(void *payload, void *data, xmlChar *name) +static void notation_copier(void *payload, void *data, const xmlChar *name) { VALUE hash = (VALUE)data; VALUE klass = rb_const_get(mNokogiriXml, rb_intern("Notation")); @@ -17,7 +17,7 @@ static void notation_copier(void *payload, void *data, xmlChar *name) rb_hash_aset(hash, NOKOGIRI_STR_NEW2(name),notation); } -static void element_copier(void *_payload, void *data, xmlChar *name) +static void element_copier(void *_payload, void *data, const xmlChar *name) { VALUE hash = (VALUE)data; xmlNodePtr payload = (xmlNodePtr)_payload; From 0d67971e60adf8903d6c96dbf5e31255b9ea6f38 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 29 Mar 2018 15:41:19 -0400 Subject: [PATCH 084/176] retry jruby jobs because they're brittle due to memory util on small concourse workers [skip ci] --- concourse/nokogiri.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 646fb4245b..6bad9c3cde 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -237,6 +237,7 @@ jobs: - get: nokogiri trigger: true - task: rake-test + attempts: 3 config: platform: linux image_resource: @@ -443,6 +444,7 @@ jobs: version: every passed: [pr-pending] - task: rake-test + attempts: 3 config: platform: linux image_resource: From e7ecc793e07ada35806b857ae5368b31f7bc0f03 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Thu, 29 Mar 2018 16:42:52 -0400 Subject: [PATCH 085/176] push parser shouldn't throw a NPE when it receives no input fixes #1710 --- ext/java/nokogiri/internals/NokogiriHandler.java | 2 +- test/xml/sax/test_push_parser.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/java/nokogiri/internals/NokogiriHandler.java b/ext/java/nokogiri/internals/NokogiriHandler.java index 1969a604eb..dd3228585e 100644 --- a/ext/java/nokogiri/internals/NokogiriHandler.java +++ b/ext/java/nokogiri/internals/NokogiriHandler.java @@ -87,6 +87,7 @@ public NokogiriHandler(Ruby runtime, IRubyObject object) { this.runtime = runtime; this.attrClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SAX::Parser::Attribute"); this.object = object; + charactersBuilder = new StringBuilder(); String objectName = object.getMetaClass().getName(); if ("Nokogiri::HTML::SAX::Parser".equals(objectName)) needEmptyAttrCheck = true; } @@ -104,7 +105,6 @@ public void setDocumentLocator(Locator locator) { @Override public void startDocument() { call("start_document"); - charactersBuilder = new StringBuilder(); } @Override diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb index 29204fc1cd..fccb9ffd41 100644 --- a/test/xml/sax/test_push_parser.rb +++ b/test/xml/sax/test_push_parser.rb @@ -35,6 +35,13 @@ def test_write_last_chunk assert_equal [["foo"]], @parser.document.end_elements end + def test_empty_doc + @parser.options |= XML::ParseOptions::RECOVER + @parser.write "", true + assert_nil @parser.document.start_elements + assert_nil @parser.document.end_elements + end + def test_finish_should_rethrow_last_error begin From 62d84dde029de385b45e9302366408235caf4a95 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Thu, 10 May 2018 19:11:44 +0900 Subject: [PATCH 086/176] Alias NodeSet#remove_attribute to NodeSet#remove_attr The name `remove_attr` was a loanword from Hpricot::Elements, but it is confusing when we have `Node#remove_attribute`. --- CHANGELOG.md | 4 ++++ lib/nokogiri/xml/node_set.rb | 1 + test/xml/test_node_set.rb | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5de2bd11ac..f09f5ab13f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * [MRI] libxml2 is updated from 2.9.7 to 2.9.8 +## Features + +* NodeSet#remove_attribute is a new alias for NodeSet#remove_attr. + ## Bug fixes * CSS attribute selectors now gracefully handle queries using integers. [#711] diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 4de7460d39..3bd5cae23c 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -187,6 +187,7 @@ def remove_attr name each { |el| el.delete name } self end + alias remove_attribute remove_attr ### # Iterate over each node, yielding to +block+ diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 7701c1246f..1be2e9cd56 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -51,6 +51,12 @@ def test_remove_attr @list.each { |x| assert_nil x['class'] } end + def test_remove_attribute + @list.each { |x| x['class'] = 'blah' } + assert_equal @list, @list.remove_attribute('class') + @list.each { |x| assert_nil x['class'] } + end + def test_add_class assert_equal @list, @list.add_class('bar') @list.each { |x| assert_equal 'bar', x['class'] } From bcf4a1a0837b9d5e5e588504466eb4e782384eff Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Thu, 10 May 2018 20:29:22 +0900 Subject: [PATCH 087/176] Add Node#{classes,add_class,append_class,remove_class} and NodeSet#append_class --- CHANGELOG.md | 6 +++ lib/nokogiri/xml/node.rb | 58 +++++++++++++++++++++++++ lib/nokogiri/xml/node_set.rb | 36 +++++++++------- test/xml/test_node.rb | 83 ++++++++++++++++++++++++++++++++++++ test/xml/test_node_set.rb | 11 +++++ 5 files changed, 179 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5de2bd11ac..681fa95bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,12 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * [MRI] libxml2 is updated from 2.9.7 to 2.9.8 +## Features + +* Node#classes, #add_class, #append_class, and #remove_class are added. +* NodeSet#append_class is added. + + ## Bug fixes * CSS attribute selectors now gracefully handle queries using integers. [#711] diff --git a/lib/nokogiri/xml/node.rb b/lib/nokogiri/xml/node.rb index efb0285170..ebd3e74a05 100644 --- a/lib/nokogiri/xml/node.rb +++ b/lib/nokogiri/xml/node.rb @@ -350,6 +350,64 @@ def each } end + ### + # Get the list of class names of this Node, without + # deduplication or sorting. + def classes + self['class'].to_s.scan(/\S+/) + end + + ### + # Add +name+ to the "class" attribute value of this Node and + # return self. If the value is already in the current value, it + # is not added. If no "class" attribute exists yet, one is + # created with the given value. + # + # More than one class may be added at a time, separated by a + # space. + def add_class name + names = classes + self['class'] = (names + (name.scan(/\S+/) - names)).join(' ') + self + end + + ### + # Append +name+ to the "class" attribute value of this Node and + # return self. The value is simply appended without checking if + # it is already in the current value. If no "class" attribute + # exists yet, one is created with the given value. + # + # More than one class may be appended at a time, separated by a + # space. + def append_class name + self['class'] = (classes + name.scan(/\S+/)).join(' ') + self + end + + ### + # Remove +name+ from the "class" attribute value of this Node + # and return self. If there are many occurrences of the name, + # they are all removed. + # + # More than one class may be removed at a time, separated by a + # space. + # + # If no class name is left after removal, or when +name+ is nil, + # the "class" attribute is removed from this Node. + def remove_class name = nil + if name + names = classes - name.scan(/\S+/) + if names.empty? + delete 'class' + else + self['class'] = names.join(' ') + end + else + delete "class" + end + self + end + ### # Remove the attribute named +name+ def remove_attribute name diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 4de7460d39..2a6121a5d7 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -135,31 +135,37 @@ def filter expr end ### - # Append the class attribute +name+ to all Node objects in the NodeSet. + # Add the class attribute +name+ to all Node objects in the + # NodeSet. + # + # See Nokogiri::XML::Node#add_class for more information. def add_class name each do |el| - classes = el['class'].to_s.split(/\s+/) - el['class'] = classes.push(name).uniq.join " " + el.add_class(name) + end + self + end + + ### + # Append the class attribute +name+ to all Node objects in the + # NodeSet. + # + # See Nokogiri::XML::Node#append_class for more information. + def append_class name + each do |el| + el.append_class(name) end self end ### - # Remove the class attribute +name+ from all Node objects in the NodeSet. - # If +name+ is nil, remove the class attribute from all Nodes in the + # Remove the class attribute +name+ from all Node objects in the # NodeSet. + # + # See Nokogiri::XML::Node#remove_class for more information. def remove_class name = nil each do |el| - if name - classes = el['class'].to_s.split(/\s+/) - if classes.empty? - el.delete 'class' - else - el['class'] = (classes - [name]).uniq.join " " - end - else - el.delete "class" - end + el.remove_class(name) end self end diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index c19b9a6676..7ba12046d0 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -680,6 +680,89 @@ def test_delete assert_nil address['domestic'] end + def test_classes + xml = Nokogiri::XML(<<-eoxml) +
+

test

+

test

+
+ eoxml + div = xml.at_xpath('//div') + p1, p2 = xml.xpath('//p') + + assert_equal [], div.classes + assert_equal %w[foo bar foo], p1.classes + assert_equal [], p2.classes + end + + def test_add_class + xml = Nokogiri::XML(<<-eoxml) +
+

test

+

test

+
+ eoxml + div = xml.at_xpath('//div') + p1, p2 = xml.xpath('//p') + + assert_same div, div.add_class('main') + assert_equal 'main', div['class'] + + assert_same p1, p1.add_class('baz foo') + assert_equal 'foo bar foo baz', p1['class'] + + assert_same p2, p2.add_class('foo baz foo') + assert_equal 'foo baz foo', p2['class'] + end + + def test_append_class + xml = Nokogiri::XML(<<-eoxml) +
+

test

+

test

+
+ eoxml + div = xml.at_xpath('//div') + p1, p2 = xml.xpath('//p') + + assert_same div, div.append_class('main') + assert_equal 'main', div['class'] + + assert_same p1, p1.append_class('baz foo') + assert_equal 'foo bar foo baz foo', p1['class'] + + assert_same p2, p2.append_class('foo baz foo') + assert_equal 'foo baz foo', p2['class'] + end + + def test_remove_class + xml = Nokogiri::XML(<<-eoxml) +
+

test

+

test

+

test

+

test

+
+ eoxml + div = xml.at_xpath('//div') + p1, p2, p3, p4 = xml.xpath('//p') + + assert_same div, div.remove_class('main') + assert_nil div['class'] + + assert_same p1, p1.remove_class('bar baz') + assert_equal 'foo foo', p1['class'] + + assert_same p2, p2.remove_class() + assert_nil p2['class'] + + assert_same p3, p3.remove_class('foo') + assert_nil p3['class'] + + assert_same p4, p4.remove_class('foo') + assert_nil p4['class'] + end + def test_set_content_with_symbol node = @xml.at('//name') node.content = :foo diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 7701c1246f..70739a573a 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -62,6 +62,17 @@ def test_add_class @list.each { |x| assert_equal 'bar baz', x['class'] } end + def test_append_class + assert_equal @list, @list.append_class('bar') + @list.each { |x| assert_equal 'bar', x['class'] } + + @list.append_class('bar') + @list.each { |x| assert_equal 'bar bar', x['class'] } + + @list.append_class('baz') + @list.each { |x| assert_equal 'bar bar baz', x['class'] } + end + def test_remove_class_with_no_class assert_equal @list, @list.remove_class('bar') @list.each { |e| assert_nil e['class'] } From 372ef2deaf5275888784ea17da0fc48bc5a0a019 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 22 May 2017 13:15:22 -0700 Subject: [PATCH 088/176] Unescape values in CSS attribute selectors --- lib/nokogiri/css/parser.rb | 136 ++++++++++++++++++++----------------- lib/nokogiri/css/parser.y | 14 +++- test/css/test_parser.rb | 6 ++ 3 files changed, 91 insertions(+), 65 deletions(-) diff --git a/lib/nokogiri/css/parser.rb b/lib/nokogiri/css/parser.rb index 6cdbf907b2..594584410f 100644 --- a/lib/nokogiri/css/parser.rb +++ b/lib/nokogiri/css/parser.rb @@ -17,68 +17,78 @@ class Parser < Racc::Parser def unescape_css_identifier(identifier) identifier.gsub(/\\(?:([^0-9a-fA-F])|([0-9a-fA-F]{1,6})\s?)/){ |m| $1 || [$2.hex].pack('U') } end + +def unescape_css_string(str) + str.gsub(/\\(?:([^0-9a-fA-F])|([0-9a-fA-F]{1,6})\s?)/) do |m| + if $1=="\n" + '' + else + $1 || [$2.hex].pack('U') + end + end +end ##### State transition tables begin ### racc_action_table = [ 24, 93, 56, 57, 33, 55, 94, 23, 24, 22, - 12, 93, 33, 27, 35, 52, 44, 22, -23, 25, - 45, 98, 23, 33, 26, 18, 20, 25, 27, -23, + 12, 93, 33, 27, 89, 52, 92, 22, -23, 25, + 109, 98, 23, 33, 26, 18, 20, 25, 27, -23, 23, 24, 26, 18, 20, 33, 27, 11, 39, 24, - 22, 23, 74, 33, 18, 91, 90, 27, 22, 12, - 25, 24, -23, 23, 85, 26, 18, 20, 25, 27, - 66, 23, 24, 26, 18, 20, 33, 27, 86, 88, - 51, 22, 89, 92, 24, 26, 56, 87, 95, 60, - 90, 25, 96, 46, 23, 49, 26, 18, 20, 99, - 27, 33, 33, 51, 103, 104, 56, 58, 26, 60, - 93, 106, 33, 33, 33, 109, 39, 39, 110, 23, - 23, nil, 18, 18, 20, 27, 27, 39, 39, 39, - 23, 23, 23, 18, 18, 18, 27, 27, 27, 33, - 33, 101, 100, nil, 102, 22, 56, 87, nil, 60, - 33, nil, nil, nil, 39, 39, nil, 23, 23, nil, - 18, 18, 20, 27, 27, 39, 82, 83, 23, 56, - 87, 18, 60, nil, 27, 82, 83, 78, 79, 80, - nil, 81, nil, nil, nil, 77, 78, 79, 80, nil, - 81, 4, 5, 10, 77, 4, 5, 43, nil, 56, - 87, 6, 60, 8, 7, 6, nil, 8, 7, 4, - 5, 10, nil, nil, nil, nil, nil, nil, nil, 6, - nil, 8, 7 ] + 22, 23, 95, 33, 18, 91, 90, 27, 22, 12, + 25, 90, 96, 23, 33, 26, 18, 20, 25, 27, + -23, 23, 24, 26, 18, 20, 33, 27, 74, 39, + 99, 22, 23, 45, 24, 18, 33, 103, 27, 56, + 87, 25, 60, 46, 23, 49, 26, 18, 20, 104, + 27, 39, 24, 51, 23, 93, 44, 18, 26, 33, + 27, 66, 106, 56, 58, 110, 60, 33, 85, 33, + 86, 51, 56, 87, 39, 60, 26, 23, 88, 33, + 18, 20, 39, 27, 39, 23, 35, 23, 18, 33, + 18, 27, nil, 27, 39, nil, 33, 23, nil, nil, + 18, 22, nil, 27, 39, 101, 100, 23, 102, nil, + 18, 39, nil, 27, 23, 82, 83, 18, 20, nil, + 27, nil, nil, nil, 82, 83, 78, 79, 80, nil, + 81, nil, nil, nil, 77, 78, 79, 80, nil, 81, + 4, 5, 43, 77, 4, 5, 10, nil, 56, 87, + 6, 60, 8, 7, 6, nil, 8, 7, 4, 5, + 10, 56, 87, nil, 60, nil, nil, nil, 6, nil, + 8, 7 ] racc_action_check = [ - 3, 58, 24, 24, 3, 24, 57, 15, 9, 3, - 64, 57, 9, 15, 11, 24, 18, 9, 58, 3, - 21, 64, 3, 14, 3, 3, 3, 9, 3, 22, - 9, 12, 9, 9, 9, 12, 9, 1, 14, 42, - 12, 14, 45, 42, 14, 55, 55, 14, 42, 1, - 12, 27, 46, 12, 49, 12, 12, 12, 42, 12, - 27, 42, 43, 42, 42, 42, 43, 42, 50, 53, - 27, 43, 54, 56, 23, 27, 51, 51, 59, 51, - 60, 43, 61, 23, 43, 23, 43, 43, 43, 75, - 43, 28, 25, 23, 84, 86, 25, 25, 23, 25, - 87, 91, 29, 30, 31, 94, 28, 25, 106, 28, - 25, nil, 28, 25, 25, 28, 25, 29, 30, 31, - 29, 30, 31, 29, 30, 31, 29, 30, 31, 32, - 39, 76, 76, nil, 76, 39, 90, 90, nil, 90, - 62, nil, nil, nil, 32, 39, nil, 32, 39, nil, - 32, 39, 39, 32, 39, 62, 47, 47, 62, 92, - 92, 62, 92, nil, 62, 48, 48, 47, 47, 47, - nil, 47, nil, nil, nil, 47, 48, 48, 48, nil, - 48, 0, 0, 0, 48, 17, 17, 17, nil, 93, - 93, 0, 93, 0, 0, 17, nil, 17, 17, 26, - 26, 26, nil, nil, nil, nil, nil, nil, nil, 26, - nil, 26, 26 ] + 3, 58, 24, 24, 3, 24, 57, 15, 42, 3, + 64, 57, 42, 15, 54, 24, 56, 42, 58, 3, + 94, 64, 3, 31, 3, 3, 3, 42, 3, 22, + 42, 9, 42, 42, 42, 9, 42, 1, 31, 43, + 9, 31, 59, 43, 31, 55, 55, 31, 43, 1, + 9, 60, 61, 9, 30, 9, 9, 9, 43, 9, + 46, 43, 12, 43, 43, 43, 12, 43, 45, 30, + 75, 12, 30, 21, 23, 30, 29, 84, 30, 93, + 93, 12, 93, 23, 12, 23, 12, 12, 12, 86, + 12, 29, 27, 23, 29, 87, 18, 29, 23, 25, + 29, 27, 91, 25, 25, 106, 25, 28, 49, 62, + 50, 27, 51, 51, 25, 51, 27, 25, 53, 14, + 25, 25, 28, 25, 62, 28, 11, 62, 28, 32, + 62, 28, nil, 62, 14, nil, 39, 14, nil, nil, + 14, 39, nil, 14, 32, 76, 76, 32, 76, nil, + 32, 39, nil, 32, 39, 47, 47, 39, 39, nil, + 39, nil, nil, nil, 48, 48, 47, 47, 47, nil, + 47, nil, nil, nil, 47, 48, 48, 48, nil, 48, + 17, 17, 17, 48, 0, 0, 0, nil, 90, 90, + 17, 90, 17, 17, 0, nil, 0, 0, 26, 26, + 26, 92, 92, nil, 92, nil, nil, nil, 26, nil, + 26, 26 ] racc_action_pointer = [ - 174, 37, nil, -2, nil, nil, nil, nil, nil, 6, - nil, 14, 29, nil, 17, -17, nil, 178, 5, nil, - nil, -9, 0, 72, -8, 86, 192, 49, 85, 96, - 97, 98, 123, nil, nil, nil, nil, nil, nil, 124, - nil, nil, 37, 60, nil, 31, 23, 153, 162, 29, - 39, 66, nil, 46, 49, 34, 61, -1, -11, 55, - 68, 59, 134, nil, -2, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 64, 121, nil, nil, nil, - nil, nil, nil, nil, 69, nil, 84, 88, nil, nil, - 126, 94, 149, 179, 92, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 95, nil, nil, nil, + 177, 37, nil, -2, nil, nil, nil, nil, nil, 29, + nil, 126, 60, nil, 113, -17, nil, 173, 85, nil, + nil, 44, 0, 72, -8, 93, 191, 90, 101, 70, + 48, 17, 123, nil, nil, nil, nil, nil, nil, 130, + nil, nil, 6, 37, nil, 57, 31, 152, 161, 83, + 81, 102, nil, 95, -9, 34, 4, -1, -11, 19, + 39, 29, 103, nil, -2, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, 135, nil, nil, nil, + nil, nil, nil, nil, 52, nil, 78, 83, nil, nil, + 178, 95, 191, 69, 7, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 92, nil, nil, nil, nil ] racc_action_default = [ @@ -96,26 +106,26 @@ def unescape_css_identifier(identifier) -41 ] racc_goto_table = [ - 53, 38, 13, 1, 42, 48, 62, 37, 34, 65, - 40, 36, 63, 75, 84, 67, 68, 69, 70, 71, - 62, 41, 50, 47, 54, nil, 63, nil, nil, 64, + 53, 38, 13, 1, 54, 48, 62, 42, 34, 65, + 37, 36, 63, 75, 84, 67, 68, 69, 70, 71, + 62, 40, 41, 50, 47, nil, 63, nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 72, 73, nil, nil, nil, nil, nil, nil, 97, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 105, nil, 107, 108 ] racc_goto_check = [ - 18, 12, 2, 1, 5, 9, 7, 8, 2, 9, - 10, 2, 12, 17, 17, 12, 12, 12, 12, 12, - 7, 11, 15, 16, 19, nil, 12, nil, nil, 1, + 18, 12, 2, 1, 19, 9, 7, 5, 2, 9, + 8, 2, 12, 17, 17, 12, 12, 12, 12, 12, + 7, 10, 11, 15, 16, nil, 12, nil, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2, 2, nil, nil, nil, nil, nil, nil, 12, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, 18, 18 ] racc_goto_pointer = [ - nil, 3, -1, nil, nil, -13, nil, -19, -7, -18, - -5, 6, -13, nil, nil, -1, 0, -34, -24, 0, + nil, 3, -1, nil, nil, -10, nil, -19, -4, -18, + 6, 7, -13, nil, nil, 0, 1, -34, -24, -20, nil, nil, nil, nil ] racc_goto_default = [ @@ -664,12 +674,12 @@ def _reduce_58(val, _values, result) end def _reduce_59(val, _values, result) - result = [val.first, val[1]] + result = [val.first, unescape_css_identifier(val[1])] result end def _reduce_60(val, _values, result) - result = [val.first, val[1]] + result = [val.first, unescape_css_string(val[1])] result end diff --git a/lib/nokogiri/css/parser.y b/lib/nokogiri/css/parser.y index 9195510ec1..e82b29d2dd 100644 --- a/lib/nokogiri/css/parser.y +++ b/lib/nokogiri/css/parser.y @@ -221,8 +221,8 @@ rule : HASH { result = Node.new(:ID, [unescape_css_identifier(val.first)]) } ; attrib_val_0or1 - : eql_incl_dash IDENT { result = [val.first, val[1]] } - | eql_incl_dash STRING { result = [val.first, val[1]] } + : eql_incl_dash IDENT { result = [val.first, unescape_css_identifier(val[1])] } + | eql_incl_dash STRING { result = [val.first, unescape_css_string(val[1])] } | eql_incl_dash NUMBER { result = [val.first, val[1]] } | ; @@ -260,3 +260,13 @@ require 'nokogiri/css/parser_extras' def unescape_css_identifier(identifier) identifier.gsub(/\\(?:([^0-9a-fA-F])|([0-9a-fA-F]{1,6})\s?)/){ |m| $1 || [$2.hex].pack('U') } end + +def unescape_css_string(str) + str.gsub(/\\(?:([^0-9a-fA-F])|([0-9a-fA-F]{1,6})\s?)/) do |m| + if $1=="\n" + '' + else + $1 || [$2.hex].pack('U') + end + end +end diff --git a/test/css/test_parser.rb b/test/css/test_parser.rb index 0ff9d24adb..8143a8331e 100644 --- a/test/css/test_parser.rb +++ b/test/css/test_parser.rb @@ -255,6 +255,12 @@ def test_prefixless_direct_adjacent_selector def test_attribute assert_xpath "//h1[@a = 'Tender Lovemaking']", @parser.parse("h1[a='Tender Lovemaking']") + assert_xpath "//h1[@a]", + @parser.parse("h1[a]") + assert_xpath "//h1[@a = 'gnewline\\n']", + @parser.parse("h1[a='\\gnew\\\nline\\\\n']") + assert_xpath "//h1[@a = 'test']", + @parser.parse(%q{h1[a=\te\st]}) end def test_attribute_with_number_or_string From 4ba1df8e45b9813048d201c8a4e7e56a09aa1079 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 22 May 2017 15:02:21 -0700 Subject: [PATCH 089/176] Support escaped single and double quotes in CSS strings for attribute selectors --- lib/nokogiri/css/tokenizer.rb | 2 +- lib/nokogiri/css/tokenizer.rex | 8 ++++---- lib/nokogiri/css/xpath_visitor.rb | 13 ++++++++++--- test/css/test_parser.rb | 8 +++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/nokogiri/css/tokenizer.rb b/lib/nokogiri/css/tokenizer.rb index 2fce0d4281..fcb7a29942 100644 --- a/lib/nokogiri/css/tokenizer.rb +++ b/lib/nokogiri/css/tokenizer.rb @@ -130,7 +130,7 @@ def _next_token when (text = @ss.scan(/[\s]+/)) action { [:S, text] } - when (text = @ss.scan(/"([^\n\r\f"]|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f']|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*'/)) + when (text = @ss.scan(/"([^\n\r\f"]|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*(? "/following-sibling::*[1]/self::", 'following_selector' => "/following-sibling::", @@ -208,7 +215,7 @@ def read_a_and_positive_b values end [a, b] end - + def is_of_type_pseudo_class? node if node.type==:PSEUDO_CLASS if node.value[0].is_a?(Nokogiri::CSS::Node) and node.value[0].type == :FUNCTION @@ -216,7 +223,7 @@ def is_of_type_pseudo_class? node else node.value[0] end =~ /(nth|first|last|only)-of-type(\()?/ - end + end end end end diff --git a/test/css/test_parser.rb b/test/css/test_parser.rb index 8143a8331e..4ac39a1b64 100644 --- a/test/css/test_parser.rb +++ b/test/css/test_parser.rb @@ -257,10 +257,16 @@ def test_attribute @parser.parse("h1[a='Tender Lovemaking']") assert_xpath "//h1[@a]", @parser.parse("h1[a]") - assert_xpath "//h1[@a = 'gnewline\\n']", + assert_xpath %q{//h1[@a = 'gnewline\n']}, @parser.parse("h1[a='\\gnew\\\nline\\\\n']") assert_xpath "//h1[@a = 'test']", @parser.parse(%q{h1[a=\te\st]}) + assert_xpath %q{//h1[@a = "'"]}, + @parser.parse(%q{h1[a="'"]}) + assert_xpath %q{//h1[@a = concat("'", "")]}, + @parser.parse(%q{h1[a='\\'']}) + assert_xpath %q{//h1[@a = concat("", '"', "'", "")]}, + @parser.parse(%q{h1[a='"\'']}) end def test_attribute_with_number_or_string From f1af4c698d198cbb51e78695fb7036482faa6952 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 15 May 2018 13:45:10 -0400 Subject: [PATCH 090/176] add gitter badge also reformat top section of README and remove links to Appveyor and Travis --- README.md | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1974fc5964..2e4916b69a 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,24 @@ # Nokogiri -* http://nokogiri.org -* Installation: http://nokogiri.org/tutorials/installing_nokogiri.html -* Tutorials: http://nokogiri.org -* README: https://github.com/sparklemotion/nokogiri -* Mailing List: https://groups.google.com/group/nokogiri-talk -* Bug Reports: https://github.com/sparklemotion/nokogiri/issues - - -## Status - -|System|Status| -|--|--| -| Concourse | [![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) | -| Travis | [![Travis Build Status](https://travis-ci.org/sparklemotion/nokogiri.svg?branch=master)](https://travis-ci.org/sparklemotion/nokogiri) | -| Appveyor | [![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/sparklemotion/nokogiri?branch=master&svg=true)](https://ci.appveyor.com/project/flavorjones/nokogiri?branch=master) | -| Code Climate | [![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.svg)](https://codeclimate.com/github/sparklemotion/nokogiri) | -| Version Eye | [![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri) | - - ## Description Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser. Among Nokogiri's many features is the ability to search documents via XPath or CSS3 selectors. +* http://nokogiri.org +* [Installation Help](http://nokogiri.org/tutorials/installing_nokogiri.html) +* [Tutorials](http://nokogiri.org) +* [GitHub](https://github.com/sparklemotion/nokogiri) +* [Mailing List](https://groups.google.com/group/nokogiri-talk) +* [Bug Reports](https://github.com/sparklemotion/nokogiri/issues) +* [Chat/Gitter](https://gitter.im/sparklemotion/nokogiri) + +[![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) +[![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.svg)](https://codeclimate.com/github/sparklemotion/nokogiri) +[![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri) +[![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) + ## Features From b11b0f98e9f4da04de348dd74387cc306a52e48e Mon Sep 17 00:00:00 2001 From: Nick Nicholas Date: Wed, 2 May 2018 17:16:52 +1000 Subject: [PATCH 091/176] Document NodeSet#dup behavior --- ext/nokogiri/xml_node_set.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ext/nokogiri/xml_node_set.c b/ext/nokogiri/xml_node_set.c index c38497d08a..28dc898df7 100644 --- a/ext/nokogiri/xml_node_set.c +++ b/ext/nokogiri/xml_node_set.c @@ -50,7 +50,10 @@ static VALUE allocate(VALUE klass) * call-seq: * dup * - * Duplicate this node set + * Duplicate this node set. NOTE: any changes to the duplicated node set will also + * alter the original node set, since they are contained in the same document. If you + * wish to change a duplicate of a node set, create a new document based on the + * node set instead. */ static VALUE duplicate(VALUE self) { From 96a4574d454b60b8cab489ec39107cb166f09bea Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 16 Jun 2018 11:55:41 -0400 Subject: [PATCH 092/176] clarify docstring for NodeSet#dup --- ext/nokogiri/xml_node_set.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/nokogiri/xml_node_set.c b/ext/nokogiri/xml_node_set.c index 28dc898df7..feb8ccebe6 100644 --- a/ext/nokogiri/xml_node_set.c +++ b/ext/nokogiri/xml_node_set.c @@ -50,10 +50,8 @@ static VALUE allocate(VALUE klass) * call-seq: * dup * - * Duplicate this node set. NOTE: any changes to the duplicated node set will also - * alter the original node set, since they are contained in the same document. If you - * wish to change a duplicate of a node set, create a new document based on the - * node set instead. + * Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not + * duplicated (similar to how Array and other Enumerable classes work). */ static VALUE duplicate(VALUE self) { From 75517e03aab9171a03527d315f64c258f1f0ef5d Mon Sep 17 00:00:00 2001 From: Junsuk Park Date: Sun, 27 May 2018 10:34:46 +0900 Subject: [PATCH 093/176] '#each' returns enumerator when no block given --- lib/nokogiri/xml/node_set.rb | 2 ++ test/xml/test_node_set.rb | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index c4c70c4269..83f5e825f5 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -198,6 +198,8 @@ def remove_attr name ### # Iterate over each node, yielding to +block+ def each(&block) + return to_enum unless block_given? + 0.upto(length - 1) do |x| yield self[x] end diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 501e3686bb..f7be30fc94 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -672,6 +672,11 @@ def test_include_on_empty_node_set assert ! empty_set.include?(employee) end + def test_each + employees = @xml.search("//employee") + assert_instance_of Enumerator, employees.each + end + def test_children employees = @xml.search("//employee") count = 0 From 00bafb76a82e03ce7f5042833d836f3742842e78 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 16 Jun 2018 12:08:53 -0400 Subject: [PATCH 094/176] add test coverage for NodeSet#each enum specifically we should test that it's the _right_ enumerator. :) --- test/xml/test_node_set.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index f7be30fc94..350a54a31c 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -674,7 +674,10 @@ def test_include_on_empty_node_set def test_each employees = @xml.search("//employee") - assert_instance_of Enumerator, employees.each + enum = employees.each + assert_instance_of Enumerator, enum + assert_equal enum.next, employees[0] + assert_equal enum.next, employees[1] end def test_children From be8a2405ba1667fbed0a841a4580d89ef1b52bda Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 16 Jun 2018 12:26:13 -0400 Subject: [PATCH 095/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4cac59088..a07e807b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,12 +27,17 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * Node#classes, #add_class, #append_class, and #remove_class are added. * NodeSet#append_class is added. * NodeSet#remove_attribute is a new alias for NodeSet#remove_attr. +* NodeSet#each now returns an Enumerator when no block is passed (Thanks, @park53kr!) +* [JRuby] General improvements in JRuby implementation (Thanks, @kares!) ## Bug fixes * CSS attribute selectors now gracefully handle queries using integers. [#711] +* Handle ASCII-8BIT encoding on fragment input [#553] +* Handle non-string return values within `Reader` [#898] * [JRuby] Allow Node#replace to insert Comment and CDATA nodes. [#1666] +* [JRuby] Stability and speed improvements to `Node`, `Sax::PushParser`, and the JRuby implementation [#1708, #1710, #1501] # 1.8.2 / 2018-01-29 From 20e11c3f976395ee94982fcc893950d66490222f Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 16 Jun 2018 15:15:04 -0400 Subject: [PATCH 096/176] version bump to 1.8.3 --- CHANGELOG.md | 2 +- lib/nokogiri/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a07e807b96..7a7c223502 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# unreleased +# 1.8.3 / 2018-06-16 ## Security Notes diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index de96be9b7c..580c6a2b1c 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.8.2' + VERSION = '1.8.3' class VersionInfo # :nodoc: def jruby? From 117ca2e067dbbf054bef9078c79387c8170d2156 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 16 Jun 2018 16:05:32 -0400 Subject: [PATCH 097/176] README format --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2e4916b69a..7ca39dd56b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser. Among Nokogiri's many features is the ability to search documents via XPath or CSS3 selectors. +## Links + * http://nokogiri.org * [Installation Help](http://nokogiri.org/tutorials/installing_nokogiri.html) * [Tutorials](http://nokogiri.org) From 0d26561bd7821dfe1c02b8dd0c82e8a1f510cc49 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 30 Jun 2018 17:12:57 -0400 Subject: [PATCH 098/176] fix memory leak with creating nodes with a namespace fixes #1771 --- CHANGELOG.md | 7 +++++++ ext/nokogiri/xml_node.c | 14 +++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a7c223502..53bdd044db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# unreleased + +## Bug fixes + +* [MRI] Fix memory leak when creating nodes with namespaces. [#1771] + + # 1.8.3 / 2018-06-16 ## Security Notes diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 3af6f9a4d4..0b572506de 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -30,7 +30,6 @@ typedef xmlNodePtr (*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr); /* :nodoc: */ static void relink_namespace(xmlNodePtr reparented) { - xmlChar *name, *prefix; xmlNodePtr child; xmlNsPtr ns; @@ -38,10 +37,16 @@ static void relink_namespace(xmlNodePtr reparented) reparented->type != XML_ELEMENT_NODE) { return; } if (reparented->ns == NULL || reparented->ns->prefix == NULL) { + xmlChar *name = 0, *prefix = 0; + name = xmlSplitQName2(reparented->name, &prefix); - if(reparented->type == XML_ATTRIBUTE_NODE) { - if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) { return; } + if (reparented->type == XML_ATTRIBUTE_NODE) { + if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) { + xmlFree(name); + xmlFree(prefix); + return; + } } ns = xmlSearchNs(reparented->doc, reparented, prefix); @@ -54,6 +59,9 @@ static void relink_namespace(xmlNodePtr reparented) xmlNodeSetName(reparented, name); xmlSetNs(reparented, ns); } + + xmlFree(name); + xmlFree(prefix); } /* Avoid segv when relinking against unlinked nodes. */ From 056f66df44fb274de3c950df586a71a9a74c05ae Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 30 Jun 2018 17:15:35 -0400 Subject: [PATCH 099/176] enforcing formatting in xml_node.c see C_CODING_STYLE.rdoc --- ext/nokogiri/xml_node.c | 384 +++++++++++++++++++++------------------- 1 file changed, 201 insertions(+), 183 deletions(-) diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 0b572506de..230cbaa3ed 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -79,10 +79,10 @@ static void relink_namespace(xmlNodePtr reparented) while (curr) { xmlNsPtr ns = xmlSearchNsByHref( - reparented->doc, - reparented->parent, - curr->href - ); + reparented->doc, + reparented->parent, + curr->href + ); /* If we find the namespace is already declared, remove it from this * definition list. */ if (ns && ns != curr && xmlStrEqual(ns->prefix, curr->prefix)) { @@ -151,10 +151,12 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep xmlNodePtr reparentee, pivot, reparented, next_text, new_next_text, parent ; int original_ns_prefix_is_default = 0 ; - if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) + if(!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) { rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); - if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) + } + if(rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) { rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); + } Data_Get_Struct(reparentee_obj, xmlNode, reparentee); Data_Get_Struct(pivot_obj, xmlNode, pivot); @@ -180,10 +182,10 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep case XML_PI_NODE: case XML_COMMENT_NODE: case XML_DOCUMENT_TYPE_NODE: - /* - * The DOM specification says no to adding text-like nodes - * directly to a document, but we allow it for compatibility. - */ + /* + * The DOM specification says no to adding text-like nodes + * directly to a document, but we allow it for compatibility. + */ case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: @@ -376,9 +378,9 @@ static VALUE encode_special_chars(VALUE self, VALUE string) Data_Get_Struct(self, xmlNode, node); encoded = xmlEncodeSpecialChars( - node->doc, - (const xmlChar *)StringValueCStr(string) - ); + node->doc, + (const xmlChar *)StringValueCStr(string) + ); encoded_str = NOKOGIRI_STR_NEW2(encoded); xmlFree(encoded); @@ -408,17 +410,18 @@ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, V doc = node->doc; - if(xmlGetIntSubset(doc)) + if(xmlGetIntSubset(doc)) { rb_raise(rb_eRuntimeError, "Document already has an internal subset"); + } dtd = xmlCreateIntSubset( - doc, - NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), - NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), - NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) - ); + doc, + NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), + NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), + NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) + ); - if(!dtd) return Qnil; + if(!dtd) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd); } @@ -439,17 +442,18 @@ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, V doc = node->doc; - if(doc->extSubset) + if(doc->extSubset) { rb_raise(rb_eRuntimeError, "Document already has an external subset"); + } dtd = xmlNewDtd( - doc, - NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), - NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), - NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) - ); + doc, + NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), + NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), + NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) + ); - if(!dtd) return Qnil; + if(!dtd) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd); } @@ -468,12 +472,12 @@ static VALUE external_subset(VALUE self) Data_Get_Struct(self, xmlNode, node); - if(!node->doc) return Qnil; + if(!node->doc) { return Qnil; } doc = node->doc; dtd = doc->extSubset; - if(!dtd) return Qnil; + if(!dtd) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd); } @@ -492,12 +496,12 @@ static VALUE internal_subset(VALUE self) Data_Get_Struct(self, xmlNode, node); - if(!node->doc) return Qnil; + if(!node->doc) { return Qnil; } doc = node->doc; dtd = xmlGetIntSubset(doc); - if(!dtd) return Qnil; + if(!dtd) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd); } @@ -514,13 +518,14 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self) VALUE level; xmlNodePtr node, dup; - if(rb_scan_args(argc, argv, "01", &level) == 0) + if(rb_scan_args(argc, argv, "01", &level) == 0) { level = INT2NUM((long)1); + } Data_Get_Struct(self, xmlNode, node); dup = xmlDocCopyNode(node, node->doc, (int)NUM2INT(level)); - if(dup == NULL) return Qnil; + if(dup == NULL) { return Qnil; } nokogiri_root_node(dup); @@ -567,7 +572,7 @@ static VALUE next_sibling(VALUE self) Data_Get_Struct(self, xmlNode, node); sibling = node->next; - if(!sibling) return Qnil; + if(!sibling) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, sibling) ; } @@ -584,7 +589,7 @@ static VALUE previous_sibling(VALUE self) Data_Get_Struct(self, xmlNode, node); sibling = node->prev; - if(!sibling) return Qnil; + if(!sibling) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, sibling); } @@ -601,7 +606,7 @@ static VALUE next_element(VALUE self) Data_Get_Struct(self, xmlNode, node); sibling = xmlNextElementSibling(node); - if(!sibling) return Qnil; + if(!sibling) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, sibling); } @@ -621,10 +626,11 @@ static VALUE previous_element(VALUE self) * note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7. */ sibling = node->prev; - if(!sibling) return Qnil; + if(!sibling) { return Qnil; } - while(sibling && sibling->type != XML_ELEMENT_NODE) + while(sibling && sibling->type != XML_ELEMENT_NODE) { sibling = sibling->prev; + } return sibling ? Nokogiri_wrap_xml_node(Qnil, sibling) : Qnil ; } @@ -632,13 +638,13 @@ static VALUE previous_element(VALUE self) /* :nodoc: */ static VALUE replace(VALUE self, VALUE new_node) { - VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper); + VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper); - xmlNodePtr pivot; - Data_Get_Struct(self, xmlNode, pivot); - nokogiri_root_node(pivot); + xmlNodePtr pivot; + Data_Get_Struct(self, xmlNode, pivot); + nokogiri_root_node(pivot); - return reparent; + return reparent; } /* @@ -662,7 +668,7 @@ static VALUE children(VALUE self) document = DOC_RUBY_OBJECT(node->doc); - if(!child) return Nokogiri_wrap_xml_node_set(set, document); + if(!child) { return Nokogiri_wrap_xml_node_set(set, document); } child = child->next; while(NULL != child) { @@ -701,7 +707,7 @@ static VALUE element_children(VALUE self) document = DOC_RUBY_OBJECT(node->doc); - if(!child) return Nokogiri_wrap_xml_node_set(set, document); + if(!child) { return Nokogiri_wrap_xml_node_set(set, document); } child = xmlNextElementSibling(child); while(NULL != child) { @@ -726,7 +732,7 @@ static VALUE child(VALUE self) Data_Get_Struct(self, xmlNode, node); child = node->children; - if(!child) return Qnil; + if(!child) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, child); } @@ -747,7 +753,7 @@ static VALUE first_element_child(VALUE self) Data_Get_Struct(self, xmlNode, node); child = xmlFirstElementChild(node); - if(!child) return Qnil; + if(!child) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, child); } @@ -768,7 +774,7 @@ static VALUE last_element_child(VALUE self) Data_Get_Struct(self, xmlNode, node); child = xmlLastElementChild(node); - if(!child) return Qnil; + if(!child) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, child); } @@ -783,8 +789,9 @@ static VALUE key_eh(VALUE self, VALUE attribute) { xmlNodePtr node; Data_Get_Struct(self, xmlNode, node); - if(xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) + if(xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) { return Qtrue; + } return Qfalse; } @@ -799,8 +806,9 @@ static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace) xmlNodePtr node; Data_Get_Struct(self, xmlNode, node); if(xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute), - NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) + NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) { return Qtrue; + } return Qfalse; } @@ -822,8 +830,9 @@ static VALUE set(VALUE self, VALUE property, VALUE value) * * We can avoid this by unlinking these nodes first. */ - if (node->type != XML_ELEMENT_NODE) + if (node->type != XML_ELEMENT_NODE) { return(Qnil); + } prop = xmlHasProp(node, (xmlChar *)StringValueCStr(property)); if (prop && prop->children) { for (cur = prop->children; cur; cur = cur->next) { @@ -835,7 +844,7 @@ static VALUE set(VALUE self, VALUE property, VALUE value) } xmlSetProp(node, (xmlChar *)StringValueCStr(property), - (xmlChar *)StringValueCStr(value)); + (xmlChar *)StringValueCStr(value)); return value; } @@ -855,7 +864,7 @@ static VALUE get(VALUE self, VALUE rattribute) xmlChar *attribute, *attr_name, *prefix; xmlNsPtr ns; - if (NIL_P(rattribute)) return Qnil; + if (NIL_P(rattribute)) { return Qnil; } Data_Get_Struct(self, xmlNode, node); attribute = xmlCharStrdup(StringValueCStr(rattribute)); @@ -879,7 +888,7 @@ static VALUE get(VALUE self, VALUE rattribute) } xmlFree((void *)attribute); - if (!value) return Qnil; + if (!value) { return Qnil; } rvalue = NOKOGIRI_STR_NEW2(value); xmlFree((void *)value); @@ -900,8 +909,9 @@ static VALUE set_namespace(VALUE self, VALUE namespace) Data_Get_Struct(self, xmlNode, node); - if(!NIL_P(namespace)) + if(!NIL_P(namespace)) { Data_Get_Struct(namespace, xmlNs, ns); + } xmlSetNs(node, ns); @@ -921,7 +931,7 @@ static VALUE attr(VALUE self, VALUE name) Data_Get_Struct(self, xmlNode, node); prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name)); - if(! prop) return Qnil; + if(! prop) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop); } @@ -937,9 +947,9 @@ static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace) xmlAttrPtr prop; Data_Get_Struct(self, xmlNode, node); prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name), - NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace)); + NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace)); - if(! prop) return Qnil; + if(! prop) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop); } @@ -951,16 +961,16 @@ static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace) */ static VALUE attribute_nodes(VALUE self) { - /* this code in the mode of xmlHasProp() */ - xmlNodePtr node; - VALUE attr; + /* this code in the mode of xmlHasProp() */ + xmlNodePtr node; + VALUE attr; - Data_Get_Struct(self, xmlNode, node); + Data_Get_Struct(self, xmlNode, node); - attr = rb_ary_new(); - Nokogiri_xml_node_properties(node, attr); + attr = rb_ary_new(); + Nokogiri_xml_node_properties(node, attr); - return attr ; + return attr ; } @@ -973,13 +983,14 @@ static VALUE attribute_nodes(VALUE self) */ static VALUE namespace(VALUE self) { - xmlNodePtr node ; - Data_Get_Struct(self, xmlNode, node); +xmlNodePtr node ; +Data_Get_Struct(self, xmlNode, node); - if (node->ns) - return Nokogiri_wrap_xml_namespace(node->doc, node->ns); +if (node->ns) { + return Nokogiri_wrap_xml_namespace(node->doc, node->ns); +} - return Qnil ; +return Qnil ; } /* @@ -1001,7 +1012,7 @@ static VALUE namespace_definitions(VALUE self) ns = node->nsDef; - if(!ns) return list; + if(!ns) { return list; } while(NULL != ns) { rb_ary_push(list, Nokogiri_wrap_xml_namespace(node->doc, ns)); @@ -1032,7 +1043,7 @@ static VALUE namespace_scopes(VALUE self) list = rb_ary_new(); ns_list = xmlGetNsList(node->doc, node); - if(!ns_list) return list; + if(!ns_list) { return list; } for (j = 0 ; ns_list[j] != NULL ; ++j) { rb_ary_push(list, Nokogiri_wrap_xml_namespace(node->doc, ns_list[j])); @@ -1162,7 +1173,7 @@ static VALUE get_parent(VALUE self) Data_Get_Struct(self, xmlNode, node); parent = node->parent; - if(!parent) return Qnil; + if(!parent) { return Qnil; } return Nokogiri_wrap_xml_node(Qnil, parent) ; } @@ -1191,8 +1202,9 @@ static VALUE get_name(VALUE self) { xmlNodePtr node; Data_Get_Struct(self, xmlNode, node); - if(node->name) + if(node->name) { return NOKOGIRI_STR_NEW2(node->name); + } return Qnil; } @@ -1235,12 +1247,13 @@ static VALUE add_previous_sibling(VALUE self, VALUE new_sibling) * Write this Node to +io+ with +encoding+ and +options+ */ static VALUE native_write_to( - VALUE self, - VALUE io, - VALUE encoding, - VALUE indent_string, - VALUE options -) { + VALUE self, + VALUE io, + VALUE encoding, + VALUE indent_string, + VALUE options +) +{ xmlNodePtr node; const char * before_indent; xmlSaveCtxtPtr savectx; @@ -1254,12 +1267,12 @@ static VALUE native_write_to( xmlTreeIndentString = StringValueCStr(indent_string); savectx = xmlSaveToIO( - (xmlOutputWriteCallback)io_write_callback, - (xmlOutputCloseCallback)io_close_callback, - (void *)io, - RTEST(encoding) ? StringValueCStr(encoding) : NULL, - (int)NUM2INT(options) - ); + (xmlOutputWriteCallback)io_write_callback, + (xmlOutputCloseCallback)io_close_callback, + (void *)io, + RTEST(encoding) ? StringValueCStr(encoding) : NULL, + (int)NUM2INT(options) + ); xmlSaveTree(savectx, node); xmlSaveClose(savectx); @@ -1302,25 +1315,25 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href) namespacee = node ; ns = xmlSearchNs( - node->doc, - node, - (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix)) - ); + node->doc, + node, + (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix)) + ); if(!ns) { if (node->type != XML_ELEMENT_NODE) { namespacee = node->parent; } ns = xmlNewNs( - namespacee, - (const xmlChar *)StringValueCStr(href), - (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix)) - ); + namespacee, + (const xmlChar *)StringValueCStr(href), + (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix)) + ); } - if (!ns) return Qnil ; + if (!ns) { return Qnil ; } - if(NIL_P(prefix) || node != namespacee) xmlSetNs(node, ns); + if(NIL_P(prefix) || node != namespacee) { xmlSetNs(node, ns); } return Nokogiri_wrap_xml_namespace(node->doc, ns); } @@ -1349,12 +1362,12 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) nokogiri_root_node(node); rb_node = Nokogiri_wrap_xml_node( - klass == cNokogiriXmlNode ? (VALUE)NULL : klass, - node - ); + klass == cNokogiriXmlNode ? (VALUE)NULL : klass, + node + ); rb_obj_call_init(rb_node, argc, argv); - if(rb_block_given_p()) rb_yield(rb_node); + if(rb_block_given_p()) { rb_yield(rb_node); } return rb_node; } @@ -1419,10 +1432,11 @@ static VALUE process_xincludes(VALUE self, VALUE options) xmlErrorPtr error; error = xmlGetLastError(); - if(error) + if(error) { rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error)); - else + } else { rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution"); + } } return self; @@ -1432,101 +1446,104 @@ static VALUE process_xincludes(VALUE self, VALUE options) /* TODO: DOCUMENT ME */ static VALUE in_context(VALUE self, VALUE _str, VALUE _options) { - xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children; - xmlNodeSetPtr set; - xmlParserErrors error; - VALUE doc, err; - int doc_is_empty; + xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children; + xmlNodeSetPtr set; + xmlParserErrors error; + VALUE doc, err; + int doc_is_empty; - Data_Get_Struct(self, xmlNode, node); + Data_Get_Struct(self, xmlNode, node); - doc = DOC_RUBY_OBJECT(node->doc); - err = rb_iv_get(doc, "@errors"); - doc_is_empty = (node->doc->children == NULL) ? 1 : 0; - node_children = node->children; - doc_children = node->doc->children; + doc = DOC_RUBY_OBJECT(node->doc); + err = rb_iv_get(doc, "@errors"); + doc_is_empty = (node->doc->children == NULL) ? 1 : 0; + node_children = node->children; + doc_children = node->doc->children; - xmlSetStructuredErrorFunc((void *)err, Nokogiri_error_array_pusher); + xmlSetStructuredErrorFunc((void *)err, Nokogiri_error_array_pusher); - /* Twiddle global variable because of a bug in libxml2. - * http://git.gnome.org/browse/libxml2/commit/?id=e20fb5a72c83cbfc8e4a8aa3943c6be8febadab7 - */ + /* Twiddle global variable because of a bug in libxml2. + * http://git.gnome.org/browse/libxml2/commit/?id=e20fb5a72c83cbfc8e4a8aa3943c6be8febadab7 + */ #ifndef HTML_PARSE_NOIMPLIED - htmlHandleOmittedElem(0); + htmlHandleOmittedElem(0); #endif - /* This function adds a fake node to the child of +node+. If the parser - * does not exit cleanly with XML_ERR_OK, the list is freed. This can - * leave the child pointers in a bad state if they were originally empty. - * - * http://git.gnome.org/browse/libxml2/tree/parser.c#n13177 - * */ - error = xmlParseInNodeContext(node, StringValuePtr(_str), - (int)RSTRING_LEN(_str), - (int)NUM2INT(_options), &list); - - /* xmlParseInNodeContext should not mutate the original document or node, - * so reassigning these pointers should be OK. The reason we're reassigning - * is because if there were errors, it's possible for the child pointers - * to be manipulated. */ - if (error != XML_ERR_OK) { - node->doc->children = doc_children; - node->children = node_children; - } + /* This function adds a fake node to the child of +node+. If the parser + * does not exit cleanly with XML_ERR_OK, the list is freed. This can + * leave the child pointers in a bad state if they were originally empty. + * + * http://git.gnome.org/browse/libxml2/tree/parser.c#n13177 + * */ + error = xmlParseInNodeContext(node, StringValuePtr(_str), + (int)RSTRING_LEN(_str), + (int)NUM2INT(_options), &list); + + /* xmlParseInNodeContext should not mutate the original document or node, + * so reassigning these pointers should be OK. The reason we're reassigning + * is because if there were errors, it's possible for the child pointers + * to be manipulated. */ + if (error != XML_ERR_OK) { + node->doc->children = doc_children; + node->children = node_children; + } - /* make sure parent/child pointers are coherent so an unlink will work - * properly (#331) - */ - child_iter = node->doc->children ; - while (child_iter) { - if (child_iter->parent != (xmlNodePtr)node->doc) - child_iter->parent = (xmlNodePtr)node->doc; - child_iter = child_iter->next; + /* make sure parent/child pointers are coherent so an unlink will work + * properly (#331) + */ + child_iter = node->doc->children ; + while (child_iter) { + if (child_iter->parent != (xmlNodePtr)node->doc) { + child_iter->parent = (xmlNodePtr)node->doc; } + child_iter = child_iter->next; + } #ifndef HTML_PARSE_NOIMPLIED - htmlHandleOmittedElem(1); + htmlHandleOmittedElem(1); #endif - xmlSetStructuredErrorFunc(NULL, NULL); - - /* Workaround for a libxml2 bug where a parsing error may leave a broken - * node reference in node->doc->children. - * This workaround is limited to when a parse error occurs, the document - * went from having no children to having children, and the context node is - * part of a document fragment. - * https://bugzilla.gnome.org/show_bug.cgi?id=668155 - */ - if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) { - child_iter = node; - while (child_iter->parent) - child_iter = child_iter->parent; + xmlSetStructuredErrorFunc(NULL, NULL); - if (child_iter->type == XML_DOCUMENT_FRAG_NODE) - node->doc->children = NULL; + /* Workaround for a libxml2 bug where a parsing error may leave a broken + * node reference in node->doc->children. + * This workaround is limited to when a parse error occurs, the document + * went from having no children to having children, and the context node is + * part of a document fragment. + * https://bugzilla.gnome.org/show_bug.cgi?id=668155 + */ + if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) { + child_iter = node; + while (child_iter->parent) { + child_iter = child_iter->parent; } - /* FIXME: This probably needs to handle more constants... */ - switch (error) { - case XML_ERR_INTERNAL_ERROR: - case XML_ERR_NO_MEMORY: - rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error); - break; - default: - break; + if (child_iter->type == XML_DOCUMENT_FRAG_NODE) { + node->doc->children = NULL; } + } - set = xmlXPathNodeSetCreate(NULL); + /* FIXME: This probably needs to handle more constants... */ + switch (error) { + case XML_ERR_INTERNAL_ERROR: + case XML_ERR_NO_MEMORY: + rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error); + break; + default: + break; + } - while (list) { - tmp = list->next; - list->next = NULL; - xmlXPathNodeSetAddUnique(set, list); - nokogiri_root_node(list); - list = tmp; - } + set = xmlXPathNodeSetCreate(NULL); + + while (list) { + tmp = list->next; + list->next = NULL; + xmlXPathNodeSetAddUnique(set, list); + nokogiri_root_node(list); + list = tmp; + } - return Nokogiri_wrap_xml_node_set(set, doc); + return Nokogiri_wrap_xml_node_set(set, doc); } @@ -1541,22 +1558,23 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node) assert(node); - if(node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE) - return DOC_RUBY_OBJECT(node->doc); + if(node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE) { + return DOC_RUBY_OBJECT(node->doc); + } /* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */ /* see https://github.com/sparklemotion/nokogiri/issues/95 */ /* and https://github.com/sparklemotion/nokogiri/issues/439 */ doc = node->doc; - if (doc->type == XML_DOCUMENT_FRAG_NODE) doc = doc->doc; + if (doc->type == XML_DOCUMENT_FRAG_NODE) { doc = doc->doc; } node_has_a_document = DOC_RUBY_OBJECT_TEST(doc); - if(node->_private && node_has_a_document) + if(node->_private && node_has_a_document) { return (VALUE)node->_private; + } if(!RTEST(klass)) { - switch(node->type) - { + switch(node->type) { case XML_ELEMENT_NODE: klass = cNokogiriXmlElement; break; From 254f3414811b6d2fff8b0630efe4ce8d29778fb6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 3 Jul 2018 08:55:20 -0400 Subject: [PATCH 100/176] version bump to v1.8.4 --- CHANGELOG.md | 4 ++-- lib/nokogiri/version.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53bdd044db..f995fc5aee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ -# unreleased +# 1.8.4 / 2018-07-03 ## Bug fixes -* [MRI] Fix memory leak when creating nodes with namespaces. [#1771] +* [MRI] Fix memory leak when creating nodes with namespaces. (Introduced in v1.5.7) [#1771] # 1.8.3 / 2018-06-16 diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index 580c6a2b1c..bca70d53d8 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.8.3' + VERSION = '1.8.4' class VersionInfo # :nodoc: def jruby? From 91a63d55eb92ef0bcb141b6c094a28ef026eaf16 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 15 Aug 2018 09:43:40 -0400 Subject: [PATCH 101/176] add tests for pkg-config failure scenario due to conflicting gcc CFLAGS, details in #1772 and #1731. added to both master and PR pipelines. --- concourse/nokogiri.yml | 53 ++++++++++++++++++++++++++++++++ concourse/tasks/rake-test/run.sh | 27 +++++++++------- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 6bad9c3cde..f0c65067a7 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -6,6 +6,7 @@ groups: - "ruby-<%= ruby_version %>-vendored" - "ruby-<%= ruby_version %>-valgrind" <% end %> + - "ruby-vanilla-system" <% for ruby_version in RUBIES[:mri].last(1) %> - "ruby-libxmlruby-system" - "ruby-libxmlruby-vendored" @@ -33,6 +34,7 @@ groups: - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - pr-success @@ -162,6 +164,29 @@ jobs: <% end %> % ruby_version = RUBIES[:mri].last + - name: ruby-vanilla-system + public: true + plan: + - get: ci + - get: nokogiri + trigger: true + passed: ["ruby-<%= ruby_version %>-system"] + - task: rake-test + config: + platform: linux + image_resource: + type: docker-image + source: {repository: ubuntu, tag: xenial} + inputs: + - name: ci + - name: nokogiri + params: + NOKOGIRI_USE_SYSTEM_LIBRARIES: t + TEST_WITH_APT_REPO_RUBY: t + run: + path: ci/concourse/tasks/rake-test/run.sh + on_failure: *notify_failure_to_irc + - name: ruby-libxmlruby-system public: true plan: @@ -433,6 +458,33 @@ jobs: on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } <% end %> +% ruby_version = RUBIES[:mri].last + - name: ruby-vanilla-system-pr + public: true + max_in_flight: 1 + plan: + - get: ci + - get: nokogiri-pr + trigger: true + version: every + passed: ["ruby-<%= ruby_version %>-system-pr"] + - task: rake-test + config: + platform: linux + image_resource: + type: docker-image + source: {repository: ubuntu, tag: xenial} + inputs: + - name: ci + - name: nokogiri-pr + path: nokogiri + params: + NOKOGIRI_USE_SYSTEM_LIBRARIES: t + TEST_WITH_APT_REPO_RUBY: t + run: + path: ci/concourse/tasks/rake-test/run.sh + on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } + % jruby_version = RUBIES[:jruby].last - name: jruby-<%= jruby_version %>-pr public: true @@ -501,6 +553,7 @@ jobs: - ruby-<%= RUBIES[:mri].last %>-system-pr - ruby-<%= RUBIES[:mri].last %>-vendored-pr - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr - rbx-<%= RUBIES[:rbx].last %>-pr - put: nokogiri-pr diff --git a/concourse/tasks/rake-test/run.sh b/concourse/tasks/rake-test/run.sh index f6ef466f09..d4db0e9c5a 100755 --- a/concourse/tasks/rake-test/run.sh +++ b/concourse/tasks/rake-test/run.sh @@ -2,12 +2,26 @@ set -e -x -u +APT_UPDATED=false + +function ensure-apt-update { + if [[ $APT_UPDATED != "false" ]] ; then + return + fi + + apt-get update + APT_UPDATED=true +} + +if [[ ${TEST_WITH_APT_REPO_RUBY:-} != "" ]] ; then + ensure-apt-update + apt-get install -y ruby ruby-dev bundler libxslt-dev libxml2-dev pkg-config +fi + VERSION_INFO=$(ruby -v) RUBY_ENGINE=$(cut -d" " -f1 <<< "${VERSION_INFO}") RUBY_VERSION=$(cut -d" " -f2 <<< "${VERSION_INFO}") -APT_UPDATED=false - FROZEN_STRING_REF="53f9b66" function mri-24-or-greater { @@ -36,15 +50,6 @@ function rbx-engine { return 1 } -function ensure-apt-update { - if [[ $APT_UPDATED != "false" ]] ; then - return - fi - - apt-get update - APT_UPDATED=true -} - pushd nokogiri if rbx-engine ; then From b3750eb71e101287aa0e7a231232222c7213b3f3 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 15 Aug 2018 09:48:50 -0400 Subject: [PATCH 102/176] remove `-Wextra` CFLAG fixes #1772 which was a regression from 77be60c --- ext/nokogiri/extconf.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index 1b0ca4ede6..cfcda83118 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -434,7 +434,7 @@ def using_system_libraries? if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/] - $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wextra -Wmissing-noreturn -Winline" + $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wmissing-noreturn -Winline" end case From 862b88f39264b7b5e223a63e3d4d0eeade4db9ff Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 15 Aug 2018 10:10:03 -0400 Subject: [PATCH 103/176] changelog [skip ci] --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f995fc5aee..933b794134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.8.5 / unreleased + +## Bug fixes + +* [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.4.) [#1722] + + # 1.8.4 / 2018-07-03 ## Bug fixes From c232226448a44bb81220d3750a6453a0aef88fb1 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 15 Aug 2018 10:13:23 -0400 Subject: [PATCH 104/176] changelog [skip ci] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933b794134..8f8fb27be1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Bug fixes -* [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.4.) [#1722] +* [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.3.) [#1722] # 1.8.4 / 2018-07-03 From 5bff4bb3f1692069c617f4333b2ccc5570f0f414 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 15 Aug 2018 10:51:46 -0400 Subject: [PATCH 105/176] pull in upstream libxml2 patches based on USN-3739-1 and -2. see related #1785. --- CHANGELOG.md | 5 ++ Manifest.txt | 2 + ...x-nullptr-deref-with-XPath-logic-ops.patch | 54 +++++++++++++++++++ ...-infinite-loop-in-LZMA-decompression.patch | 50 +++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch create mode 100644 patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f8fb27be1..a06371373d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # 1.8.5 / unreleased +## Security Notes + +[MRI] Pulled in upstream patches from libxml2 that address CVE-2018-14404 and CVE-2018-14567. Full details are available in #1785. Note that these patches are not yet (as of 2018-08-15) in an upstream release of libxml2. + + ## Bug fixes * [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.3.) [#1722] diff --git a/Manifest.txt b/Manifest.txt index aa62f20966..7e8b83ef7c 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -251,6 +251,8 @@ lib/xercesImpl.jar lib/xml-apis.jar lib/xsd/xmlparser/nokogiri.rb patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch +patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch patches/sort-patches-by-date suppressions/README.txt suppressions/nokogiri_ruby-2.supp diff --git a/patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch b/patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch new file mode 100644 index 0000000000..1345c0c8ce --- /dev/null +++ b/patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch @@ -0,0 +1,54 @@ +From a436374994c47b12d5de1b8b1d191a098fa23594 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Mon, 30 Jul 2018 12:54:38 +0200 +Subject: [PATCH] Fix nullptr deref with XPath logic ops + +If the XPath stack is corrupted, for example by a misbehaving extension +function, the "and" and "or" XPath operators could dereference NULL +pointers. Check that the XPath stack isn't empty and optimize the +logic operators slightly. + +Closes: https://gitlab.gnome.org/GNOME/libxml2/issues/5 + +Also see +https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901817 +https://bugzilla.redhat.com/show_bug.cgi?id=1595985 + +This is CVE-2018-14404. + +Thanks to Guy Inbar for the report. +--- + xpath.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/xpath.c b/xpath.c +index 3fae0bf..5e3bb9f 100644 +--- a/xpath.c ++++ b/xpath.c +@@ -13234,9 +13234,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) + return(0); + } + xmlXPathBooleanFunction(ctxt, 1); +- arg1 = valuePop(ctxt); +- arg1->boolval &= arg2->boolval; +- valuePush(ctxt, arg1); ++ if (ctxt->value != NULL) ++ ctxt->value->boolval &= arg2->boolval; + xmlXPathReleaseObject(ctxt->context, arg2); + return (total); + case XPATH_OP_OR: +@@ -13252,9 +13251,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) + return(0); + } + xmlXPathBooleanFunction(ctxt, 1); +- arg1 = valuePop(ctxt); +- arg1->boolval |= arg2->boolval; +- valuePush(ctxt, arg1); ++ if (ctxt->value != NULL) ++ ctxt->value->boolval |= arg2->boolval; + xmlXPathReleaseObject(ctxt->context, arg2); + return (total); + case XPATH_OP_EQUAL: +-- +2.17.1 + diff --git a/patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch b/patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch new file mode 100644 index 0000000000..e5a4ce8b7e --- /dev/null +++ b/patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch @@ -0,0 +1,50 @@ +From 2240fbf5912054af025fb6e01e26375100275e74 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Mon, 30 Jul 2018 13:14:11 +0200 +Subject: [PATCH] Fix infinite loop in LZMA decompression +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check the liblzma error code more thoroughly to avoid infinite loops. + +Closes: https://gitlab.gnome.org/GNOME/libxml2/issues/13 +Closes: https://bugzilla.gnome.org/show_bug.cgi?id=794914 + +This is CVE-2018-9251 and CVE-2018-14567. + +Thanks to Dongliang Mu and Simon Wörner for the reports. +--- + xzlib.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/xzlib.c b/xzlib.c +index a839169..0ba88cf 100644 +--- a/xzlib.c ++++ b/xzlib.c +@@ -562,6 +562,10 @@ xz_decomp(xz_statep state) + "internal error: inflate stream corrupt"); + return -1; + } ++ /* ++ * FIXME: Remapping a couple of error codes and falling through ++ * to the LZMA error handling looks fragile. ++ */ + if (ret == Z_MEM_ERROR) + ret = LZMA_MEM_ERROR; + if (ret == Z_DATA_ERROR) +@@ -587,6 +591,11 @@ xz_decomp(xz_statep state) + xz_error(state, LZMA_PROG_ERROR, "compression error"); + return -1; + } ++ if ((state->how != GZIP) && ++ (ret != LZMA_OK) && (ret != LZMA_STREAM_END)) { ++ xz_error(state, ret, "lzma error"); ++ return -1; ++ } + } while (strm->avail_out && ret != LZMA_STREAM_END); + + /* update available output and crc check value */ +-- +2.17.1 + From 169744261c5c023dff40de0811a826ad4d1fcc05 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Fri, 6 Jul 2018 15:38:47 -0400 Subject: [PATCH 106/176] Allow reparenting nodes to be a child of an empty document. Fixes #1773 --- ext/java/nokogiri/XmlNode.java | 4 ++++ test/xml/test_node_reparenting.rb | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 5e126817fc..24439bab9e 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -1542,6 +1542,10 @@ protected IRubyObject adoptAs(ThreadContext context, AdoptScheme scheme, try { Document prev = otherNode.getOwnerDocument(); Document doc = thisNode.getOwnerDocument(); + if (doc == null && thisNode instanceof Document) { + // we are adding the new node to a new empty document + doc = (Document) thisNode; + } clearXpathContext(prev); clearXpathContext(doc); if (doc != null && doc != otherNode.getOwnerDocument()) { diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index 02fbe56cc5..2375035c20 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -197,6 +197,17 @@ class TestNodeReparenting < Nokogiri::TestCase end end + describe "given the new document is empty" do + it "adds the node to the new document" do + doc1 = Nokogiri::XML.parse("3") + doc2 = Nokogiri::XML::Document.new + node = doc1.at_xpath("//value") + node.remove + doc2.add_child(node) + assert_match /3<\/value>/, doc2.to_xml + end + end + describe "given a parent node with a default namespace" do before do @doc = Nokogiri::XML(<<-eoxml) From 7cc6cf6a74bd718b46182f0e646b63ff0a00f728 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Fri, 6 Jul 2018 15:47:50 -0400 Subject: [PATCH 107/176] Organize imports in XmlNode.java. --- ext/java/nokogiri/XmlNode.java | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 24439bab9e..81f614f10a 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -33,7 +33,16 @@ package nokogiri; import static java.lang.Math.max; -import static nokogiri.internals.NokogiriHelpers.*; +import static nokogiri.internals.NokogiriHelpers.clearXpathContext; +import static nokogiri.internals.NokogiriHelpers.convertEncoding; +import static nokogiri.internals.NokogiriHelpers.convertString; +import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate; +import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; +import static nokogiri.internals.NokogiriHelpers.isBlank; +import static nokogiri.internals.NokogiriHelpers.nodeArrayToRubyArray; +import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil; +import static nokogiri.internals.NokogiriHelpers.rubyStringToString; +import static nokogiri.internals.NokogiriHelpers.stringOrNil; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -43,18 +52,12 @@ import java.util.Iterator; import java.util.List; -import nokogiri.internals.HtmlDomParserContext; -import nokogiri.internals.NokogiriHelpers; -import nokogiri.internals.NokogiriNamespaceCache; -import nokogiri.internals.SaveContextVisitor; -import nokogiri.internals.XmlDomParserContext; - import org.apache.xerces.dom.CoreDocumentImpl; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; -import org.jruby.RubyInteger; import org.jruby.RubyFixnum; +import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; @@ -76,6 +79,12 @@ import org.w3c.dom.NodeList; import org.w3c.dom.Text; +import nokogiri.internals.HtmlDomParserContext; +import nokogiri.internals.NokogiriHelpers; +import nokogiri.internals.NokogiriNamespaceCache; +import nokogiri.internals.SaveContextVisitor; +import nokogiri.internals.XmlDomParserContext; + /** * Class for Nokogiri::XML::Node * From 712edef8a8c7fa593e09517891d336758af42cba Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 4 Oct 2018 20:00:17 -0400 Subject: [PATCH 108/176] update changelog [skip ci] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a73a9087..75cadc8731 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Security Notes -[MRI] Pulled in upstream patches from libxml2 that address CVE-2018-14404 and CVE-2018-14567. Full details are available in #1785. Note that these patches are not yet (as of 2018-08-15) in an upstream release of libxml2. +[MRI] Pulled in upstream patches from libxml2 that address CVE-2018-14404 and CVE-2018-14567. Full details are available in [#1785](https://github.com/sparklemotion/nokogiri/issues/1785). Note that these patches are not yet (as of 2018-10-04) in an upstream release of libxml2. ## Bug fixes From e28fa4bb2ed6844c3c63f58062d034e7b99fc90c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 4 Oct 2018 20:02:06 -0400 Subject: [PATCH 109/176] version bump to v1.8.5 --- CHANGELOG.md | 2 +- lib/nokogiri/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75cadc8731..0c82741d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.8.5 / unreleased +# 1.8.5 / 2018-10-04 ## Security Notes diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index bca70d53d8..f00a62d87d 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.8.4' + VERSION = '1.8.5' class VersionInfo # :nodoc: def jruby? From 859845b9bd226014292db94c8c00fcb635e66cb4 Mon Sep 17 00:00:00 2001 From: Seiei Miyagi Date: Fri, 2 Nov 2018 14:49:33 +0900 Subject: [PATCH 110/176] Remove Version Eye badge Added at https://github.com/sparklemotion/nokogiri/pull/1031 Version Eye was shut down. https://blog.versioneye.com/2017/10/19/versioneye-sunset-process/ --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7ca39dd56b..4a65ac5333 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ or CSS3 selectors. [![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) [![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.svg)](https://codeclimate.com/github/sparklemotion/nokogiri) -[![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri) [![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) From 801eacb44863c06645adc7f1a6152d0ffa855ea0 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Nov 2018 09:39:02 -0400 Subject: [PATCH 111/176] update to latest hoe-debugging so we can generate a suppression file to eliminate the false positives we're seeing in CI with ruby 2.5 [skip ci] --- Gemfile | 2 +- Rakefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 38861dc002..6df4c68029 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ source "https://rubygems.org/" gem "mini_portile2", "~>2.3.0" gem "hoe-bundler", "~>1.2", :group => [:development, :test] -gem "hoe-debugging", "~>1.4", :group => [:development, :test] +gem "hoe-debugging", "~>1.5", :group => [:development, :test] gem "hoe-gemspec", "~>1.0", :group => [:development, :test] gem "hoe-git", "~>1.6", :group => [:development, :test] gem "minitest", "~>5.8.4", :group => [:development, :test] diff --git a/Rakefile b/Rakefile index 86a75cdb87..0018d219dc 100644 --- a/Rakefile +++ b/Rakefile @@ -133,7 +133,7 @@ HOE = Hoe.spec 'nokogiri' do self.extra_dev_deps += [ ["hoe-bundler", "~> 1.2"], - ["hoe-debugging", "~> 1.4"], + ["hoe-debugging", "~> 1.5"], ["hoe-gemspec", "~> 1.0"], ["hoe-git", "~> 1.6"], ["minitest", "~> 5.8.4"], From 0618ccec3245778460d3a59d6ce828d940a70dcd Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Nov 2018 10:06:51 -0400 Subject: [PATCH 112/176] concourse: valgrind builds have TESTOPTS=-v for helping narrow down where valgrind warnings are coming from --- concourse/tasks/rake-test/run.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/concourse/tasks/rake-test/run.sh b/concourse/tasks/rake-test/run.sh index d4db0e9c5a..0391937ddb 100755 --- a/concourse/tasks/rake-test/run.sh +++ b/concourse/tasks/rake-test/run.sh @@ -52,15 +52,14 @@ function rbx-engine { pushd nokogiri + RAKE_TASK="test" + if rbx-engine ; then ensure-apt-update apt-get install -y ca-certificates gcc pkg-config libxml2-dev libxslt-dev patch fi - RAKE_TASK="test" - if [[ ${TEST_WITH_VALGRIND:-} != "" ]] ; then - RAKE_TASK="test:valgrind" # override ensure-apt-update apt-get install -y valgrind fi @@ -72,6 +71,11 @@ pushd nokogiri export RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal" fi + if [[ ${TEST_WITH_VALGRIND:-} != "" ]] ; then + RAKE_TASK="test:valgrind" # override + export TESTOPTS="-v" # see more verbose output to help narrow down warnings + fi + bundle exec rake ${RAKE_TASK} popd From ec52483c4c5230b9e3e47b991cc302bcb9b992bb Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Nov 2018 10:12:58 -0400 Subject: [PATCH 113/176] valgrind suppression file for false positives seeing false positives when CI is running *not* under load. (i.e., seen rarely when main pipeline is running, seen more often when PR pipeline is running) for examples of two classes of ruby_cleanup errors: - https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri/jobs/ruby-2.5-valgrind-pr/builds/66 - https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri/jobs/ruby-2.5-valgrind-pr/builds/67 and here's the build I cribbed this suppression file from: - https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri/jobs/ruby-libxmlruby-valgrind/builds/73 [skip ci] --- suppressions/nokogiri_ruby-2_5.supp | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 suppressions/nokogiri_ruby-2_5.supp diff --git a/suppressions/nokogiri_ruby-2_5.supp b/suppressions/nokogiri_ruby-2_5.supp new file mode 100644 index 0000000000..44508b08a7 --- /dev/null +++ b/suppressions/nokogiri_ruby-2_5.supp @@ -0,0 +1,30 @@ +{ + + Memcheck:Addr8 + fun:mark_locations_array + fun:gc_mark_locations + fun:rb_gc_mark_locations + fun:gc_mark_stacked_objects + fun:gc_mark_stacked_objects_incremental + fun:gc_marks_rest + ... + fun:ruby_finalize_? + fun:ruby_cleanup + fun:ruby_run_node + fun:main +} +{ + + Memcheck:Addr8 + fun:mark_locations_array + fun:gc_mark_locations + fun:rb_gc_mark_locations + fun:gc_marks_wb_unprotected_objects + fun:gc_marks_finish + fun:gc_marks_rest + ... + fun:ruby_finalize_? + fun:ruby_cleanup + fun:ruby_run_node + fun:main +} From 48dfc502c007df26e7ccaa9a01fac2cf84a48df3 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 15 May 2018 19:35:34 -0400 Subject: [PATCH 114/176] allow rbx to fail for now --- concourse/nokogiri.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index f0c65067a7..05edffca76 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -15,10 +15,6 @@ groups: <% for jruby_version in RUBIES[:jruby] %> - "jruby-<%= jruby_version %>" <% end %> - <% for rbx_version in RUBIES[:rbx] %> - - "rbx-<%= rbx_version %>-system" - - "rbx-<%= rbx_version %>-vendored" - <% end %> <% RUBIES[:windows].first(1).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> @@ -36,7 +32,6 @@ groups: - ruby-<%= RUBIES[:mri].last %>-valgrind-pr - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr - - rbx-<%= RUBIES[:rbx].last %>-pr - pr-success - name: allow-failure @@ -44,6 +39,11 @@ groups: <% RUBIES[:windows].last(2).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> + <% for rbx_version in RUBIES[:rbx] %> + - "rbx-<%= rbx_version %>-system" + - "rbx-<%= rbx_version %>-vendored" + <% end %> + - rbx-<%= RUBIES[:rbx].last %>-pr resource_types: @@ -299,7 +299,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: *notify_failure_to_irc +# on_failure: *notify_failure_to_irc - name: rbx-<%= rbx_version %>-vendored public: true @@ -321,7 +321,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: *notify_failure_to_irc +# on_failure: *notify_failure_to_irc <% end %> <% for ruby_version in RUBIES[:windows] %> @@ -361,9 +361,9 @@ jobs: <% for jruby_version in RUBIES[:jruby] %> - "jruby-<%= jruby_version %>" <% end %> - <% for rbx_version in RUBIES[:rbx] %> - - "rbx-<%= rbx_version %>-vendored" - <% end %> + # <% for rbx_version in RUBIES[:rbx] %> + # - "rbx-<%= rbx_version %>-vendored" + # <% end %> <% RUBIES[:windows].first(1).each do |ruby_version| %> - "win-ruby-<%= ruby_version %>-devkit" <% end %> @@ -537,7 +537,7 @@ jobs: TMPDIR: /scratch run: path: ci/concourse/tasks/rake-test/run.sh - on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } +# on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } - name: pr-success public: true @@ -555,7 +555,7 @@ jobs: - ruby-<%= RUBIES[:mri].last %>-valgrind-pr - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr - - rbx-<%= RUBIES[:rbx].last %>-pr +# - rbx-<%= RUBIES[:rbx].last %>-pr - put: nokogiri-pr params: {path: nokogiri-pr, status: success} - put: nokogiri-irc From 9498d433b75b1726b5dc6aad212b4efcd8cc3399 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Nov 2018 10:34:21 -0400 Subject: [PATCH 115/176] concourse: use valgrind suppressions from the ci resource and not from the code under test --- concourse/nokogiri.yml | 2 ++ concourse/tasks/rake-test/run.sh | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 05edffca76..70e0768aab 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -70,6 +70,7 @@ resources: branch: master ignore_paths: - concourse/** + - suppressions/** - name: nokogiri-pr type: pull-request source: @@ -77,6 +78,7 @@ resources: access_token: {{github-repo-status-access-token}} ignore_paths: - concourse/** + - suppressions/** - name: nokogiri-irc type: irc-notification source: diff --git a/concourse/tasks/rake-test/run.sh b/concourse/tasks/rake-test/run.sh index 0391937ddb..4ce83a9659 100755 --- a/concourse/tasks/rake-test/run.sh +++ b/concourse/tasks/rake-test/run.sh @@ -74,6 +74,12 @@ pushd nokogiri if [[ ${TEST_WITH_VALGRIND:-} != "" ]] ; then RAKE_TASK="test:valgrind" # override export TESTOPTS="-v" # see more verbose output to help narrow down warnings + + # always use the CI suppressions if they exist + if [[ -d ../ci/suppressions ]] ; then + rm -rf suppressions + cp -var ../ci/suppressions . + fi fi bundle exec rake ${RAKE_TASK} From dd1496d3186112657df1f1d1352bed951910b2d8 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 2 Nov 2018 10:42:08 -0400 Subject: [PATCH 116/176] concourse:valgrind: fix naming of supression file --- suppressions/{nokogiri_ruby-2_5.supp => nokogiri_ruby-2.5.supp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename suppressions/{nokogiri_ruby-2_5.supp => nokogiri_ruby-2.5.supp} (100%) diff --git a/suppressions/nokogiri_ruby-2_5.supp b/suppressions/nokogiri_ruby-2.5.supp similarity index 100% rename from suppressions/nokogiri_ruby-2_5.supp rename to suppressions/nokogiri_ruby-2.5.supp From d13284abbd8e3aa77ab899e7b9ca514b84bdd7dd Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Nov 2018 13:59:10 -0400 Subject: [PATCH 117/176] xml_namespace.c: avoid multiple calls to Data_Wrap_Struct --- ext/nokogiri/xml_namespace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/nokogiri/xml_namespace.c b/ext/nokogiri/xml_namespace.c index 773fe919bb..7aea6ce1ac 100644 --- a/ext/nokogiri/xml_namespace.c +++ b/ext/nokogiri/xml_namespace.c @@ -63,7 +63,7 @@ static int part_of_an_xpath_node_set_eh(xmlNsPtr node) VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) { - VALUE ns, document, node_cache; + VALUE ns = 0, document, node_cache; assert(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE); @@ -71,8 +71,6 @@ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) if (doc->type == XML_DOCUMENT_FRAG_NODE) doc = doc->doc; - ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node); - if (DOC_RUBY_OBJECT_TEST(doc)) { document = DOC_RUBY_OBJECT(doc); @@ -91,6 +89,8 @@ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) } rb_iv_set(ns, "@document", document); + } else { + ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node); } node->_private = (void *)ns; From c771f312cf558488a4ed943ff242ec5d7af022c1 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 3 Nov 2018 14:01:08 -0400 Subject: [PATCH 118/176] xml_node.c: fix variable spelling --- ext/nokogiri/xml_node.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 230cbaa3ed..c04ae03c65 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -1308,11 +1308,11 @@ static VALUE line(VALUE self) */ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href) { - xmlNodePtr node, namespacee; + xmlNodePtr node, namespace; xmlNsPtr ns; Data_Get_Struct(self, xmlNode, node); - namespacee = node ; + namespace = node ; ns = xmlSearchNs( node->doc, @@ -1322,10 +1322,10 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href) if(!ns) { if (node->type != XML_ELEMENT_NODE) { - namespacee = node->parent; + namespace = node->parent; } ns = xmlNewNs( - namespacee, + namespace, (const xmlChar *)StringValueCStr(href), (const xmlChar *)(NIL_P(prefix) ? NULL : StringValueCStr(prefix)) ); @@ -1333,7 +1333,7 @@ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href) if (!ns) { return Qnil ; } - if(NIL_P(prefix) || node != namespacee) { xmlSetNs(node, ns); } + if(NIL_P(prefix) || node != namespace) { xmlSetNs(node, ns); } return Nokogiri_wrap_xml_namespace(node->doc, ns); } From 0039f2e0878656e85ae4c8efd94c12f4a3f60100 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 08:45:25 -0500 Subject: [PATCH 119/176] xml_namespace.h: remove deprecated function declaration --- ext/nokogiri/xml_namespace.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/nokogiri/xml_namespace.h b/ext/nokogiri/xml_namespace.h index 3ffd5343cc..4b09a03f6b 100644 --- a/ext/nokogiri/xml_namespace.h +++ b/ext/nokogiri/xml_namespace.h @@ -7,8 +7,7 @@ void init_xml_namespace(); extern VALUE cNokogiriXmlNamespace ; -VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) ; -VALUE Nokogiri_wrap_xml_namespace2(VALUE document, xmlNsPtr node) ; +VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node); #define NOKOGIRI_NAMESPACE_EH(node) ((node)->type == XML_NAMESPACE_DECL) From 3e75d0a3975dc059d8b21a694bb3f2c80f499a97 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 08:47:53 -0500 Subject: [PATCH 120/176] xml_node.c: minor cleanup - properly scope variable - prefer NULL to 0 --- ext/nokogiri/xml_node.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index c04ae03c65..7c33d306b8 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -31,13 +31,13 @@ typedef xmlNodePtr (*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr); static void relink_namespace(xmlNodePtr reparented) { xmlNodePtr child; - xmlNsPtr ns; if (reparented->type != XML_ATTRIBUTE_NODE && reparented->type != XML_ELEMENT_NODE) { return; } if (reparented->ns == NULL || reparented->ns->prefix == NULL) { - xmlChar *name = 0, *prefix = 0; + xmlNsPtr ns = NULL; + xmlChar *name = NULL, *prefix = NULL; name = xmlSplitQName2(reparented->name, &prefix); From af99c52770ffdcd35e67ac5a5b67e0966d9c9be2 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 08:49:08 -0500 Subject: [PATCH 121/176] tests for memory leak in issue #1810 --- test/test_memory_leak.rb | 63 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/test/test_memory_leak.rb b/test/test_memory_leak.rb index f2505ca01d..8e6fc1d82b 100644 --- a/test/test_memory_leak.rb +++ b/test/test_memory_leak.rb @@ -13,6 +13,22 @@ def setup EOF end + # + # this suite is turned off unless the env var NOKOGIRI_GC is non-nil + # + # to run any of these tests, do something like this on the commandline: + # + # $ NOKOGIRI_GC=t ruby -Ilib:test \ + # test/test_memory_leak.rb \ + # -n /test_leaking_namespace_node_strings/ + # + # also see: + # + # https://github.com/sparklemotion/nokogiri/issues/1603 + # + # which is an open issue to resurrect these tests and run them as + # part of the CI pipeline. + # if ENV['NOKOGIRI_GC'] # turning these off by default for now def test_dont_hurt_em_why content = File.open("#{File.dirname(__FILE__)}/files/dont_hurt_em_why.xml").read @@ -126,7 +142,7 @@ def test_jumping_sax_handler end def test_in_context_parser_leak - loop do + loop do doc = Nokogiri::XML::Document.new fragment1 = Nokogiri::XML::DocumentFragment.new(doc, '') node = fragment1.children[0] @@ -144,8 +160,53 @@ def test_leak_on_xpath_string_function doc.xpath('name(//node())') end end + + def test_leaking_namespace_node_strings + # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report + ns = {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'} + 20.times do + 10_000.times do + Nokogiri::XML::Builder.new do |xml| + xml.send 'Envelope', ns do + xml.send 'Foobar', ns + end + end + end + puts MemInfo.rss + end + end + + def test_leaking_namespace_node_strings_with_prefix + # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report + ns = {'xmlns:foo' => 'http://schemas.xmlsoap.org/soap/envelope/'} + 20.times do + 10_000.times do + Nokogiri::XML::Builder.new do |xml| + xml.send 'Envelope', ns do + xml.send 'Foobar', ns + end + end + end + puts MemInfo.rss + end + end end # if NOKOGIRI_GC + module MemInfo + # from https://stackoverflow.com/questions/7220896/get-current-ruby-process-memory-usage + # this is only going to work on linux + PAGE_SIZE = `getconf PAGESIZE`.chomp.to_i rescue 4096 + STATM_PATH = "/proc/#{Process.pid}/statm" + STATM_FOUND = File.exist?(STATM_PATH) + + def self.rss + if STATM_FOUND + return (File.read(STATM_PATH).split(' ')[1].to_i * PAGE_SIZE) / 1024 + end + return 0 + end + end + private def count_object_space_documents From 96e3c64dc37f445dc36fc1947604f5c5d66bb712 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 09:39:35 -0500 Subject: [PATCH 122/176] fix for memory leak in issue #1810 --- ext/nokogiri/xml_document.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/nokogiri/xml_document.c b/ext/nokogiri/xml_document.c index ca48ffac99..1850849251 100644 --- a/ext/nokogiri/xml_document.c +++ b/ext/nokogiri/xml_document.c @@ -7,7 +7,7 @@ static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc) xmlFreePropList((xmlAttrPtr)node); break; case XML_NAMESPACE_DECL: - xmlFree(node); + xmlFreeNs((xmlNsPtr)node); break; default: if(node->parent == NULL) { From 5021cb1cbddef1ff11d9aca407ff2d704fd4538e Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 13:30:30 -0500 Subject: [PATCH 123/176] ensure that, after reparenting, we re-use existing ns defs previously, it was possible for a node's `ns` pointer to be referencing an nsDef that had been removed after reparenting an orphan node with a namespace (that removed nsDef would be rooted in the doc's `unlinkedNodes` hash, and not referenced from the doc). this is unrelated to the ns memory leak addressed in the previous commits, but is something I spotted along the way. --- ext/nokogiri/xml_node.c | 19 +++++++++++++++++++ test/xml/test_builder.rb | 12 ++++++++++++ test/xml/test_node.rb | 9 ++++++++- test/xml/test_node_reparenting.rb | 15 +++++++++------ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 7c33d306b8..f93cdf0faa 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -99,6 +99,25 @@ static void relink_namespace(xmlNodePtr reparented) } } + /* + * Search our parents for an existing definition of current namespace, + * because the definition it's pointing to may have just been removed nsDef. + * + * And although that would technically probably be OK, I'd feel better if we + * referred to a namespace that's still present in a node's nsDef somewhere + * in the doc. + */ + if (reparented->ns) { + xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix); + if (ns + && ns != reparented->ns + && xmlStrEqual(ns->prefix, reparented->ns->prefix) + && xmlStrEqual(ns->href, reparented->ns->href) + ) { + xmlSetNs(reparented, ns); + } + } + /* Only walk all children if there actually is a namespace we need to */ /* reparent. */ if (NULL == reparented->ns) { return; } diff --git a/test/xml/test_builder.rb b/test/xml/test_builder.rb index 83e2e1ec2e..f755d4c7b8 100644 --- a/test/xml/test_builder.rb +++ b/test/xml/test_builder.rb @@ -331,6 +331,18 @@ def test_builder_can_handle_namespace_override assert_nil doc.at_xpath("//*[local-name() = 'products']").namespace end + def test_builder_reuses_namespaces + # see https://github.com/sparklemotion/nokogiri/issues/1810 for memory leak report + builder = Nokogiri::XML::Builder.new + builder.send "envelope", {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'} do + builder.send "package", {'xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/'} + end + envelope = builder.doc.at_css("envelope") + package = builder.doc.at_css("package") + assert_equal envelope.namespace, package.namespace + assert_equal envelope.namespace.object_id, package.namespace.object_id + end + private def namespaces_defined_on(node) diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index 7ba12046d0..07cba2cef0 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -415,12 +415,19 @@ def test_add_namespace_twice assert_equal ns, ns2 end - def test_add_default_ns + def test_add_default_namespace node = @xml.at('address') node.add_namespace(nil, 'http://tenderlovemaking.com') assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns'] end + def test_add_default_namespace_twice + node = @xml.at('address') + ns = node.add_namespace(nil, 'http://tenderlovemaking.com') + ns2 = node.add_namespace(nil, 'http://tenderlovemaking.com') + assert_equal ns.object_id, ns2.object_id + end + def test_add_multiple_namespaces node = @xml.at('address') diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index 2375035c20..301536e1bf 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -204,7 +204,7 @@ class TestNodeReparenting < Nokogiri::TestCase node = doc1.at_xpath("//value") node.remove doc2.add_child(node) - assert_match /3<\/value>/, doc2.to_xml + assert_match(/3<\/value>/, doc2.to_xml) end end @@ -249,7 +249,7 @@ class TestNodeReparenting < Nokogiri::TestCase @node.add_child(@child) assert reparented = @doc.at('//bar:second', "bar" => "http://tenderlovemaking.com/") assert reparented.namespace_definitions.empty? - assert_equal @ns, reparented.namespace + assert_equal @doc.root.namespace, reparented.namespace assert_equal( { "xmlns" => "http://tenderlovemaking.com/", @@ -282,17 +282,20 @@ class TestNodeReparenting < Nokogiri::TestCase end describe "and a child with a namespace matching the parent's non-default namespace" do + before do + @root_ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" } + end + describe "set by #namespace=" do before do - @ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" } - @child.namespace = @ns + @child.namespace = @root_ns end it "inserts a node that inherits the matching parent namespace" do @node.add_child(@child) assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/") assert reparented.namespace_definitions.empty? - assert_equal @ns, reparented.namespace + assert_equal @root_ns, reparented.namespace assert_equal( { "xmlns" => "http://tenderlovemaking.com/", @@ -312,7 +315,7 @@ class TestNodeReparenting < Nokogiri::TestCase @node.add_child(@child) assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/") assert reparented.namespace_definitions.empty? - assert_equal @ns, reparented.namespace + assert_equal @root_ns, reparented.namespace assert_equal( { "xmlns" => "http://tenderlovemaking.com/", From 271308351f5d00dedee2883f8dbbf7f3ed44d9e4 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 4 Nov 2018 14:57:49 -0500 Subject: [PATCH 124/176] bump dep: hoe-debugging to `~> 2.0` for better suppression file handling. --- Gemfile | 2 +- Rakefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 6df4c68029..80b8736423 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ source "https://rubygems.org/" gem "mini_portile2", "~>2.3.0" gem "hoe-bundler", "~>1.2", :group => [:development, :test] -gem "hoe-debugging", "~>1.5", :group => [:development, :test] +gem "hoe-debugging", "~>2.0", :group => [:development, :test] gem "hoe-gemspec", "~>1.0", :group => [:development, :test] gem "hoe-git", "~>1.6", :group => [:development, :test] gem "minitest", "~>5.8.4", :group => [:development, :test] diff --git a/Rakefile b/Rakefile index 0018d219dc..e2462cf123 100644 --- a/Rakefile +++ b/Rakefile @@ -133,7 +133,7 @@ HOE = Hoe.spec 'nokogiri' do self.extra_dev_deps += [ ["hoe-bundler", "~> 1.2"], - ["hoe-debugging", "~> 1.5"], + ["hoe-debugging", "~> 2.0"], ["hoe-gemspec", "~> 1.0"], ["hoe-git", "~> 1.6"], ["minitest", "~> 5.8.4"], From 38a28fe2188a325fc26d302a08bdb6ee6caf4284 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 5 Nov 2018 14:19:55 -0500 Subject: [PATCH 125/176] add test demonstrating why relink_namespace can't call xmlFreeNs ... on nsDefs that are removed from the reparented node. It's possible for a ruby object reference to remain after we've freed the underlying struct. Potentially we could add some more complex code to manage this edge case but honestly I don't think it's worth the effort. --- test/xml/test_node_reparenting.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index 301536e1bf..b3b549738b 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -553,6 +553,19 @@ class TestNodeReparenting < Nokogiri::TestCase end end + describe "reparenting and preserving a reference to the original ns" do + it "should not cause illegal memory access" do + # this test will only cause a failure in valgrind. it + # drives out the reason why we can't call xmlFreeNs in + # relink_namespace and instead have to root the nsdef. + doc = Nokogiri::XML '' + elem = doc.create_element "package", {"xmlns" => "http://flavorjon.es/"} + ns = elem.namespace_definitions + doc.at_css("envelope").add_child elem + ns.inspect + end + end + describe "reparenting into another document" do it "correctly sets default namespace of a reparented node" do # issue described in #391 From 9feda6ca6a64da33ed882700ad97d8f77296288f Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 5 Nov 2018 14:27:02 -0500 Subject: [PATCH 126/176] xml_node.c: free a string to avoid a small memory leak when reparenting nodes which have a default namespace matching a new parent's default namespace. see libxml2 tree.c function `xmlNewReconciliedNs` for details (and xmlNewNs which strdups the prefix). --- ext/nokogiri/xml_node.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index f93cdf0faa..91e0351e86 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -301,7 +301,11 @@ static VALUE reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_rep } if (original_ns_prefix_is_default && reparentee->ns != NULL && reparentee->ns->prefix != NULL) { - /* issue #391, where new node's prefix may become the string "default" */ + /* + * issue #391, where new node's prefix may become the string "default" + * see libxml2 tree.c xmlNewReconciliedNs which implements this behavior. + */ + xmlFree(reparentee->ns->prefix); reparentee->ns->prefix = NULL; } } From 6a51de171349f6620cc20c1fa205c8ac0e7bf572 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 5 Nov 2018 15:11:46 -0500 Subject: [PATCH 127/176] generalize 2.5 suppression stack see https://ci.nokogiri.org/builds/5050 for the example used --- suppressions/nokogiri_ruby-2.5.supp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suppressions/nokogiri_ruby-2.5.supp b/suppressions/nokogiri_ruby-2.5.supp index 44508b08a7..1934d0fd75 100644 --- a/suppressions/nokogiri_ruby-2.5.supp +++ b/suppressions/nokogiri_ruby-2.5.supp @@ -5,7 +5,7 @@ fun:gc_mark_locations fun:rb_gc_mark_locations fun:gc_mark_stacked_objects - fun:gc_mark_stacked_objects_incremental + fun:gc_mark_stacked_objects_* fun:gc_marks_rest ... fun:ruby_finalize_? From 9ba9da88fa0b3ed26ed98b69ee30c1f31f70e64a Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 5 Nov 2018 17:22:17 -0500 Subject: [PATCH 128/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c82741d70..d690088bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# unreleased + +## Bug fixes + +* [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] + + # 1.8.5 / 2018-10-04 ## Security Notes From c14073fbcb23ee43c2f3e93001878b3c6192a303 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 9 Nov 2018 21:33:07 -0500 Subject: [PATCH 129/176] concourse: update to concourse gem v0.20.0 and include coverage for ruby 2.6-rc --- concourse/nokogiri.yml | 52 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 70e0768aab..8bf7bef26b 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -1,13 +1,13 @@ groups: - name: master jobs: - <% for ruby_version in RUBIES[:mri] %> + <% Concourse.production_rubies.each do |ruby_version| %> - "ruby-<%= ruby_version %>-system" - "ruby-<%= ruby_version %>-vendored" - "ruby-<%= ruby_version %>-valgrind" <% end %> - "ruby-vanilla-system" - <% for ruby_version in RUBIES[:mri].last(1) %> + <% Concourse.production_rubies.last(1).each do |ruby_version| %> - "ruby-libxmlruby-system" - "ruby-libxmlruby-vendored" - "ruby-libxmlruby-valgrind" @@ -24,12 +24,12 @@ groups: - name: PRs jobs: - pr-pending - - ruby-<%= RUBIES[:mri].first %>-system-pr - - ruby-<%= RUBIES[:mri].first %>-vendored-pr - - ruby-<%= RUBIES[:mri].first %>-valgrind-pr - - ruby-<%= RUBIES[:mri].last %>-system-pr - - ruby-<%= RUBIES[:mri].last %>-vendored-pr - - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - ruby-<%= Concourse.production_rubies.first %>-system-pr + - ruby-<%= Concourse.production_rubies.first %>-vendored-pr + - ruby-<%= Concourse.production_rubies.first %>-valgrind-pr + - ruby-<%= Concourse.production_rubies.last %>-system-pr + - ruby-<%= Concourse.production_rubies.last %>-vendored-pr + - ruby-<%= Concourse.production_rubies.last %>-valgrind-pr - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr - pr-success @@ -44,7 +44,11 @@ groups: - "rbx-<%= rbx_version %>-vendored" <% end %> - rbx-<%= RUBIES[:rbx].last %>-pr - + <% Concourse.rc_rubies.each do |ruby_version| %> + - "ruby-<%= ruby_version %>-system" + - "ruby-<%= ruby_version %>-vendored" + - "ruby-<%= ruby_version %>-valgrind" + <% end %> resource_types: - name: pull-request @@ -100,7 +104,7 @@ jobs: # # master # - <% for ruby_version in RUBIES[:mri] %> + <% RUBIES[:mri].each do |ruby_version| %> - name: ruby-<%= ruby_version %>-system public: true plan: @@ -120,7 +124,9 @@ jobs: NOKOGIRI_USE_SYSTEM_LIBRARIES: t run: path: ci/concourse/tasks/rake-test/run.sh +% if Concourse.production_rubies.include? ruby_version on_failure: *notify_failure_to_irc +% end - name: ruby-<%= ruby_version %>-vendored public: true @@ -140,7 +146,9 @@ jobs: - name: nokogiri run: path: ci/concourse/tasks/rake-test/run.sh +% if Concourse.production_rubies.include? ruby_version on_failure: *notify_failure_to_irc +% end - name: ruby-<%= ruby_version %>-valgrind public: true @@ -162,10 +170,12 @@ jobs: TEST_WITH_VALGRIND: t run: path: ci/concourse/tasks/rake-test/run.sh +% if Concourse.production_rubies.include? ruby_version on_failure: *notify_failure_to_irc +% end <% end %> -% ruby_version = RUBIES[:mri].last +% ruby_version = Concourse.production_rubies.last - name: ruby-vanilla-system public: true plan: @@ -354,10 +364,10 @@ jobs: trigger: true version: every passed: - <% for ruby_version in RUBIES[:mri] %> + <% Concourse.production_rubies.each do |ruby_version| %> - "ruby-<%= ruby_version %>-valgrind" <% end %> - <% for ruby_version in RUBIES[:mri].last(1) %> + <% Concourse.production_rubies.last(1).each do |ruby_version| %> - "ruby-libxmlruby-valgrind" <% end %> <% for jruby_version in RUBIES[:jruby] %> @@ -385,7 +395,7 @@ jobs: - put: nokogiri-pr params: {path: nokogiri-pr, status: pending} - <% [RUBIES[:mri].first, RUBIES[:mri].last].each do |ruby_version| %> + <% [Concourse.production_rubies.first, Concourse.production_rubies.last].each do |ruby_version| %> - name: ruby-<%= ruby_version %>-system-pr public: true max_in_flight: 1 @@ -460,7 +470,7 @@ jobs: on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] } <% end %> -% ruby_version = RUBIES[:mri].last +% ruby_version = Concourse.production_rubies.last - name: ruby-vanilla-system-pr public: true max_in_flight: 1 @@ -549,12 +559,12 @@ jobs: trigger: true version: every passed: - - ruby-<%= RUBIES[:mri].first %>-system-pr - - ruby-<%= RUBIES[:mri].first %>-vendored-pr - - ruby-<%= RUBIES[:mri].first %>-valgrind-pr - - ruby-<%= RUBIES[:mri].last %>-system-pr - - ruby-<%= RUBIES[:mri].last %>-vendored-pr - - ruby-<%= RUBIES[:mri].last %>-valgrind-pr + - ruby-<%= Concourse.production_rubies.first %>-system-pr + - ruby-<%= Concourse.production_rubies.first %>-vendored-pr + - ruby-<%= Concourse.production_rubies.first %>-valgrind-pr + - ruby-<%= Concourse.production_rubies.last %>-system-pr + - ruby-<%= Concourse.production_rubies.last %>-vendored-pr + - ruby-<%= Concourse.production_rubies.last %>-valgrind-pr - ruby-vanilla-system-pr - jruby-<%= RUBIES[:jruby].last %>-pr # - rbx-<%= RUBIES[:rbx].last %>-pr From 464717b2da5b6d443a3784039880ecd86b0b8579 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Mon, 12 Nov 2018 11:20:14 -0500 Subject: [PATCH 130/176] Fix tests on JRuby 9.2 This appears a result of commit jruby/jruby#8e631ca1d2f302a642d28b8b96427cd5e29ea222 which introduced RubyException.toJava. It overrides the behavior of RubyBasicObject.toJava and returns the null throwable instead of returning the RubyException itself. I don't understand the reason for the change in JRuby or why we used get() instead of entry(). I think `entry' is the right method to call since it just return the RubyObject. [fixes #1818] --- CHANGELOG.md | 2 +- ext/java/nokogiri/XmlNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d690088bac..74022e31e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Bug fixes * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] - +* [JRuby] Fix failing tests on JRuby 9.2.x # 1.8.5 / 2018-10-04 diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 81f614f10a..c5ab80c839 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -839,7 +839,7 @@ public IRubyObject in_context(ThreadContext context, RubyArray docErrors = getErrorArray(doc); if (isErrorIncreased(documentErrors, docErrors)) { for (int i = 0; i < docErrors.getLength(); i++) { - documentErrors.add(docErrors.get(i)); + documentErrors.add(docErrors.entry(i)); } document.setInstanceVariable("@errors", documentErrors); XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, RubyArray.newArray(runtime)); From bf41ba04903b93e0c6a29fe0f2ace3a2944baf3c Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 17 Nov 2018 14:22:30 +0900 Subject: [PATCH 131/176] Fix misuse of `MAKEFILE_CONFIG` As the values of `RbConfig::MAKEFILE_CONFIG` are intended to use in Makefile and may contain make macros, so a path in it may not match /gcc/, nor cannot execute directly. Use `RbConfig::CONFIG`, whose values are expanded, for such porpose instead. --- ext/nokogiri/extconf.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index cfcda83118..2abe4690ac 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -400,9 +400,11 @@ def using_system_libraries? ENV['CFLAGS'] = "#{ENV['CFLAGS']} -I /usr/local/include" end -RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] +if ENV['CC'] + RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] +end # use same c compiler for libxml and libxslt -ENV['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] +ENV['CC'] = RbConfig::CONFIG['CC'] $LIBS << " #{ENV["LIBS"]}" @@ -432,7 +434,7 @@ def using_system_libraries? $CPPFLAGS << ' "-Idummypath"' end -if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ +if RbConfig::CONFIG['CC'] =~ /gcc/ $CFLAGS << " -O3" unless $CFLAGS[/-O\d/] $CFLAGS << " -Wall -Wcast-qual -Wwrite-strings -Wmissing-noreturn -Winline" end From 2b2f60b7a3e77255a9d308bcb04b4c45f3329f8f Mon Sep 17 00:00:00 2001 From: Gregory Pakosz Date: Fri, 2 Nov 2018 10:53:30 +0100 Subject: [PATCH 132/176] On Darwin, for the use of /usr/bin/ar and /usr/bin/ranlib. Fixes #1812 --- ext/nokogiri/extconf.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index cfcda83118..b865e8b569 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -560,7 +560,8 @@ def install *(libiconv_recipe ? "--with-iconv=#{libiconv_recipe.path}" : iconv_configure_flags), "--with-c14n", "--with-debug", - "--with-threads" + "--with-threads", + *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "") ] end @@ -573,7 +574,8 @@ def install "--without-python", "--without-crypto", "--with-debug", - "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}" + "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}", + *(darwin? ? ["RANLIB=/usr/bin/ranlib", "AR=/usr/bin/ar"] : "") ] end From a6ecfc0305363dee4c1fcf7c7575a21d582e2265 Mon Sep 17 00:00:00 2001 From: Oleh Feilo Date: Fri, 30 Nov 2018 18:49:02 +0200 Subject: [PATCH 133/176] return self in the env of each --- lib/nokogiri/xml/node_set.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 83f5e825f5..1e52613bb7 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -203,6 +203,7 @@ def each(&block) 0.upto(length - 1) do |x| yield self[x] end + self end ### From e3ade9a0da2ed59658bfb0184b8416e0417edcbd Mon Sep 17 00:00:00 2001 From: Oleh Feilo Date: Fri, 30 Nov 2018 19:03:53 +0200 Subject: [PATCH 134/176] add test --- test/xml/test_node_set.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index 350a54a31c..d934952fae 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -804,6 +804,12 @@ def awesome! ; end assert_equal node_set.document, new_set.document assert new_set.respond_to?(:awesome!) end + + def test_each_should_return_self + node_set1 = @xml.css("address") + node_set2 = node_set1.each {} + assert_equal node_set1, node_set2 + end end end end From e2e3e9c5c10ec7b8307b8b8f1603f574c67bad12 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 1 Dec 2018 09:17:06 -0500 Subject: [PATCH 135/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74022e31e3..6a6464d35b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,16 @@ # unreleased +## Features + +* [MRI] Address installation challenges on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) + + ## Bug fixes * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] * [JRuby] Fix failing tests on JRuby 9.2.x + # 1.8.5 / 2018-10-04 ## Security Notes From 543968d97768ba0bbb797df3e5ea77e2078d17d6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 1 Dec 2018 11:49:14 -0500 Subject: [PATCH 136/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a6464d35b..d6600293e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ## Bug fixes +* `NodeSet#each` now returns `self` instead of zero. [#1822] (Thanks, @olehif!) * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] * [JRuby] Fix failing tests on JRuby 9.2.x From 5476f201980427b96aeaa1a058793f29d714560f Mon Sep 17 00:00:00 2001 From: Stephen Checkoway Date: Tue, 4 Sep 2018 23:25:07 -0400 Subject: [PATCH 137/176] Free DTD nodes DTD nodes added to a document are not freed when the document is freed. Fixes #1784 --- ext/nokogiri/xml_document.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/nokogiri/xml_document.c b/ext/nokogiri/xml_document.c index 1850849251..1d2119c80f 100644 --- a/ext/nokogiri/xml_document.c +++ b/ext/nokogiri/xml_document.c @@ -9,6 +9,9 @@ static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc) case XML_NAMESPACE_DECL: xmlFreeNs((xmlNsPtr)node); break; + case XML_DTD_NODE: + xmlFreeDtd((xmlDtdPtr)node); + break; default: if(node->parent == NULL) { xmlAddChild((xmlNodePtr)doc, node); From a4c217c7b2abd28a2a89743bb4fb5102d678a6fd Mon Sep 17 00:00:00 2001 From: John Shahid Date: Sat, 14 Jul 2018 21:33:40 -0400 Subject: [PATCH 138/176] Add namespace attributes when necessary * ext/java/nokogiri/XmlNode.java (relink_namespace): Add a namespace attribute to the new adopted node, if the current scope namespace URI or prefix don't match the new node's namespace. Fixes #1774 --- ext/java/nokogiri/XmlNode.java | 23 +++++++++++++- test/xml/test_node_reparenting.rb | 53 +++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index c5ab80c839..9ca43e18d2 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -472,10 +472,31 @@ public void relink_namespace(ThreadContext context) { String nsURI = e.lookupNamespaceURI(prefix); this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName()); - if (nsURI == null || nsURI.isEmpty()) { + if (nsURI == null || nsURI == "") { return; } + String currentPrefix = e.getParentNode().lookupPrefix(nsURI); + String currentURI = e.getParentNode().lookupNamespaceURI(prefix); + boolean isDefault = e.getParentNode().isDefaultNamespace(nsURI); + + // add xmlns attribute if this is a new root node or if the node's + // namespace isn't a default namespace in the new document + if (e.getParentNode().getNodeType() == Node.DOCUMENT_NODE) { + // this is the root node, so we must set the namespaces attributes + // anyway + e.setAttribute(prefix == null ? "xmlns":"xmlns:"+prefix, nsURI); + } else if (prefix == null) { + if (!isDefault) + // this is a default namespace but isn't the default where this + // node is being added + e.setAttribute("xmlns", nsURI); + } else if (currentPrefix != prefix || currentURI != nsURI) { + // this is a prefixed namespace but doens't have the same prefix or + // the prefix is set to a diffent URI + e.setAttribute("xmlns:"+prefix, nsURI); + } + if (e.hasAttributes()) { NamedNodeMap attrs = e.getAttributes(); diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index b3b549738b..f155a36bbf 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -224,6 +224,59 @@ class TestNodeReparenting < Nokogiri::TestCase node.add_child(child) assert @doc.at('//xmlns:second') end + + describe "and a child node was added to a new doc with the a different namespace using the same prefix" do + before do + @doc = Nokogiri::XML %Q{} + new_doc = Nokogiri::XML %Q{} + assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/") + new_doc.root.add_child node + @doc = new_doc + end + + it "serializes the doc with the proper default namespace" do + assert_match //, @doc.to_xml + end + end + + describe "and a child node was added to a new doc with the same default namespaces" do + before do + new_doc = Nokogiri::XML %Q{} + assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/") + new_doc.root.add_child node + @doc = new_doc + end + + it "serializes the doc with the proper default namespace" do + assert_match //, @doc.to_xml + end + end + + describe "and a child node was added to a new doc without any default namespaces" do + before do + new_doc = Nokogiri::XML "" + assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/") + new_doc.root.add_child node + @doc = new_doc + end + + it "serializes the doc with the proper default namespace" do + assert_match //, @doc.to_xml + end + end + + describe "and a child node became the root of a new doc" do + before do + new_doc = Nokogiri::XML::Document.new + assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/") + new_doc.root = node + @doc = new_doc + end + + it "serializes the doc with the proper default namespace" do + assert_match //, @doc.to_xml + end + end end describe "given a parent node with a default and non-default namespace" do From 5ed7aff4d5347fe54724656035d67ed57874a7fa Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 1 Dec 2018 13:56:21 -0500 Subject: [PATCH 139/176] dev: avoid running racc or rex under jruby not sure why `rake generate` is trying to do so in CI, but I'm assuming it has to do with non-deterministic file timestamps and so am punting and simply skipping it under jruby with a warning. --- Rakefile | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index e2462cf123..ea11d13973 100644 --- a/Rakefile +++ b/Rakefile @@ -266,11 +266,21 @@ task 'bundler:gemfile' do end file GENERATED_PARSER => "lib/nokogiri/css/parser.y" do |t| - sh "racc -l -o #{t.name} #{t.prerequisites.first}" + if java? + warn "WARNING: #{GENERATED_PARSER} may be out of date:" + sh "ls -lt #{t.name} #{t.prerequisites.first}" + else + sh "racc -l -o #{t.name} #{t.prerequisites.first}" + end end file GENERATED_TOKENIZER => "lib/nokogiri/css/tokenizer.rex" do |t| - sh "rex --independent -o #{t.name} #{t.prerequisites.first}" + if java? + warn "WARNING: #{GENERATED_TOKENIZER} may be out of date:" + sh "ls -lt #{t.name} #{t.prerequisites.first}" + else + sh "rex --independent -o #{t.name} #{t.prerequisites.first}" + end end [:compile, :check_manifest].each do |task_name| From dfc19d8adf1076275b25dc10abd85f8880b07e94 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 4 Sep 2018 23:41:42 -0400 Subject: [PATCH 140/176] Replace DOM2DTM with DOM2DTMExt the patched version of DOM2DTM Looks like we replaced DOM2DTM with DOM2DTMExt when we fixed https://github.com/sparklemotion/nokogiri/pull/1320 but forgot to replace it in the DOM2DTM manager fixes #1749 --- ext/java/nokogiri/internals/XalanDTMManagerPatch.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java index c95bd33a8e..7b0d206c47 100644 --- a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +++ b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java @@ -19,6 +19,8 @@ */ package nokogiri.internals; +import javax.xml.transform.dom.DOMSource; + import org.apache.xml.dtm.DTM; import org.apache.xml.dtm.DTMWSFilter; import org.apache.xml.dtm.ref.dom2dtm.DOM2DTMExt; @@ -26,8 +28,6 @@ import org.apache.xml.res.XMLMessages; import org.w3c.dom.Node; -import javax.xml.transform.dom.DOMSource; - /** * @author kares */ @@ -75,8 +75,8 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage // Have each DTM cache last DOM node search? for(int i = 0; i < m_dtms.length; i++) { DTM thisDTM = m_dtms[i]; - if (thisDTM instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTM) { - int handle = ((org.apache.xml.dtm.ref.dom2dtm.DOM2DTM) thisDTM).getHandleOfNode(node); + if (thisDTM instanceof DOM2DTMExt) { + int handle = ((DOM2DTMExt) thisDTM).getHandleOfNode(node); if (handle != DTM.NULL) { return handle; } From c113f4e6fc74aed66763e5ed69d9ceccc3e613e8 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Fri, 14 Sep 2018 12:47:40 -0400 Subject: [PATCH 141/176] Rewrite XmlNodeSet The current implementation suffers from having poor performance. More specifically, `op_or' is order of magnitude slower than the MRI version slows down XMLNodeSet::xpath and XMLNodeSet::css significantly. This commit rewrites the class to manage its own internal array, similar to what libxml does. fixes #1795 --- ext/java/nokogiri/XmlDtd.java | 36 +- ext/java/nokogiri/XmlElement.java | 12 +- ext/java/nokogiri/XmlNode.java | 13 +- ext/java/nokogiri/XmlNodeSet.java | 335 ++++++++++++++---- ext/java/nokogiri/XmlXpathContext.java | 22 +- .../nokogiri/internals/NokogiriHelpers.java | 48 +-- .../internals/NokogiriXPathFunction.java | 10 +- 7 files changed, 330 insertions(+), 146 deletions(-) diff --git a/ext/java/nokogiri/XmlDtd.java b/ext/java/nokogiri/XmlDtd.java index f37498140d..6083454bd5 100644 --- a/ext/java/nokogiri/XmlDtd.java +++ b/ext/java/nokogiri/XmlDtd.java @@ -35,9 +35,11 @@ import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil; import static nokogiri.internals.NokogiriHelpers.stringOrNil; -import static org.jruby.javasupport.util.RuntimeHelpers.invoke; -import nokogiri.internals.NokogiriHelpers; -import nokogiri.internals.SaveContextVisitor; +import static org.jruby.runtime.Helpers.invoke; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.apache.xerces.xni.QName; import org.cyberneko.dtd.DTDConfiguration; @@ -54,6 +56,9 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; +import nokogiri.internals.NokogiriHelpers; +import nokogiri.internals.SaveContextVisitor; + /** * Class for Nokogiri::XML::DTD * @@ -64,8 +69,6 @@ @JRubyClass(name="Nokogiri::XML::DTD", parent="Nokogiri::XML::Node") public class XmlDtd extends XmlNode { - protected RubyArray allDecls = null; - /** cache of children, Nokogiri::XML::NodeSet */ protected IRubyObject children = null; @@ -369,7 +372,6 @@ protected void extractDecls(ThreadContext context) { Ruby runtime = context.getRuntime(); // initialize data structures - allDecls = RubyArray.newArray(runtime); attributes = RubyHash.newHash(runtime); elements = RubyHash.newHash(runtime); entities = RubyHash.newHash(runtime); @@ -379,10 +381,9 @@ protected void extractDecls(ThreadContext context) { // recursively extract decls if (node == null) return; // leave all the decl hash's empty - extractDecls(context, node.getFirstChild()); // convert allDecls to a NodeSet - children = XmlNodeSet.newXmlNodeSet(context, allDecls); + children = XmlNodeSet.newXmlNodeSet(context, extractDecls(context, node.getFirstChild())); // add attribute decls as attributes to the matching element decl RubyArray keys = attributes.keys(); @@ -425,25 +426,26 @@ protected void extractDecls(ThreadContext context) { * subset it extracts everything and assumess node * and all children are part of the external subset. */ - protected void extractDecls(ThreadContext context, Node node) { + protected IRubyObject[] extractDecls(ThreadContext context, Node node) { + List decls = new ArrayList(); while (node != null) { if (isExternalSubset(node)) { - return; + break; } else if (isAttributeDecl(node)) { XmlAttributeDecl decl = (XmlAttributeDecl) XmlAttributeDecl.create(context, node); attributes.op_aset(context, decl.attribute_name(context), decl); - allDecls.append(decl); + decls.add(decl); } else if (isElementDecl(node)) { XmlElementDecl decl = (XmlElementDecl) XmlElementDecl.create(context, node); elements.op_aset(context, decl.element_name(context), decl); - allDecls.append(decl); + decls.add(decl); } else if (isEntityDecl(node)) { XmlEntityDecl decl = (XmlEntityDecl) XmlEntityDecl.create(context, node); entities.op_aset(context, decl.node_name(context), decl); - allDecls.append(decl); + decls.add(decl); } else if (isNotationDecl(node)) { XmlNode tmp = (XmlNode) NokogiriHelpers.constructNode(context.getRuntime(), node); @@ -453,7 +455,7 @@ protected void extractDecls(ThreadContext context, Node node) { tmp.getAttribute(context, "sysid")); notations.op_aset(context, tmp.getAttribute(context, "name"), decl); - allDecls.append(decl); + decls.add(decl); } else if (isContentModel(node)) { XmlElementContent cm = new XmlElementContent(context.getRuntime(), @@ -462,13 +464,15 @@ protected void extractDecls(ThreadContext context, Node node) { contentModels.op_aset(context, cm.element_name(context), cm); } else { // recurse - extractDecls(context, node.getFirstChild()); + decls.addAll(Arrays.asList(extractDecls(context, node.getFirstChild()))); } node = node.getNextSibling(); } + + return decls.toArray(new IRubyObject[decls.size()]); } - + @Override public void accept(ThreadContext context, SaveContextVisitor visitor) { // since we use nekoDTD to parse dtd, node might be ElementImpl type diff --git a/ext/java/nokogiri/XmlElement.java b/ext/java/nokogiri/XmlElement.java index 275d87e999..d300af60cb 100644 --- a/ext/java/nokogiri/XmlElement.java +++ b/ext/java/nokogiri/XmlElement.java @@ -32,16 +32,16 @@ package nokogiri; -import nokogiri.internals.SaveContextVisitor; - import org.jruby.Ruby; -import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.anno.JRubyClass; import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; import org.w3c.dom.Element; import org.w3c.dom.Node; +import nokogiri.internals.SaveContextVisitor; + /** * Class for Nokogiri::XML::Element * @@ -71,9 +71,9 @@ public void accept(ThreadContext context, SaveContextVisitor visitor) { visitor.enter((Element) node); XmlNodeSet xmlNodeSet = (XmlNodeSet) children(context); if (xmlNodeSet.length() > 0) { - RubyArray nodes = xmlNodeSet.nodes; - for( int i = 0; i < nodes.size(); i++ ) { - Object item = nodes.eltInternal(i); + IRubyObject[] nodes = XmlNodeSet.getNodes(context, xmlNodeSet); + for( int i = 0; i < nodes.length; i++ ) { + Object item = nodes[i]; if (item instanceof XmlNode) { ((XmlNode) item).accept(context, visitor); } diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index c5ab80c839..55fd4305a4 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -704,7 +704,7 @@ public IRubyObject child(ThreadContext context) { @JRubyMethod public IRubyObject children(ThreadContext context) { - XmlNodeSet xmlNodeSet = XmlNodeSet.create(context.runtime); + XmlNodeSet xmlNodeSet = XmlNodeSet.newEmptyNodeSet(context); NodeList nodeList = node.getChildNodes(); if (nodeList.getLength() > 0) { @@ -737,8 +737,8 @@ public IRubyObject last_element_child(ThreadContext context) { public IRubyObject element_children(ThreadContext context) { List elementNodes = new ArrayList(); addElements(node, elementNodes, false); - if (elementNodes.size() == 0) return XmlNodeSet.newEmptyNodeSet(context); - RubyArray array = NokogiriHelpers.nodeArrayToRubyArray(context.getRuntime(), elementNodes.toArray(new Node[0])); + IRubyObject[] array = NokogiriHelpers.nodeArrayToArray(context.runtime, + elementNodes.toArray(new Node[0])); XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, array); return xmlNodeSet; } @@ -842,7 +842,7 @@ public IRubyObject in_context(ThreadContext context, documentErrors.add(docErrors.entry(i)); } document.setInstanceVariable("@errors", documentErrors); - XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, RubyArray.newArray(runtime)); + XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, new IRubyObject[0]); return xmlNodeSet; } @@ -854,10 +854,9 @@ public IRubyObject in_context(ThreadContext context, } else { first = doc.node.getFirstChild(); } - RubyArray nodeArray = RubyArray.newArray(runtime); - nodeArray.add(NokogiriHelpers.getCachedNodeOrCreate(runtime, first)); - XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, nodeArray); + IRubyObject[] nodes = new IRubyObject[]{NokogiriHelpers.getCachedNodeOrCreate(runtime, first)}; + XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, nodes); return xmlNodeSet; } diff --git a/ext/java/nokogiri/XmlNodeSet.java b/ext/java/nokogiri/XmlNodeSet.java index 08d0711f2e..831e3af183 100644 --- a/ext/java/nokogiri/XmlNodeSet.java +++ b/ext/java/nokogiri/XmlNodeSet.java @@ -17,10 +17,10 @@ * 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: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -36,12 +36,13 @@ import static nokogiri.internals.NokogiriHelpers.getNokogiriClass; import static nokogiri.internals.NokogiriHelpers.nodeListToRubyArray; -import java.util.List; +import java.util.Arrays; import org.jruby.Ruby; -import org.jruby.RubyArray; import org.jruby.RubyClass; +import org.jruby.RubyFixnum; import org.jruby.RubyObject; +import org.jruby.RubyRange; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.Block; @@ -59,30 +60,38 @@ @JRubyClass(name="Nokogiri::XML::NodeSet") public class XmlNodeSet extends RubyObject implements NodeList { - RubyArray nodes; - + private IRubyObject[] nodes; + + @JRubyMethod(name = "new", meta = true, rest = true) + public static IRubyObject rbNew(ThreadContext context, IRubyObject cls, + IRubyObject[] args, Block block) { + RubyClass klass = (RubyClass) cls; + XmlNodeSet set = (XmlNodeSet) klass.allocate(); + set.setNodes(new IRubyObject[0]); + set.callInit(args, block); + return set; + } + public XmlNodeSet(Ruby ruby, RubyClass klazz) { super(ruby, klazz); } - public static XmlNodeSet create(final Ruby runtime) { + private static XmlNodeSet create(final Ruby runtime) { return (XmlNodeSet) NokogiriService.XML_NODESET_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::NodeSet")); } public static XmlNodeSet newEmptyNodeSet(ThreadContext context) { - return create(context.getRuntime()); + XmlNodeSet set = create(context.getRuntime()); + set.nodes = new IRubyObject[0]; + return set; } - public static XmlNodeSet newXmlNodeSet(final Ruby runtime, RubyArray nodes) { - XmlNodeSet xmlNodeSet = create(runtime); + public static XmlNodeSet newXmlNodeSet(ThreadContext context, IRubyObject[] nodes) { + XmlNodeSet xmlNodeSet = create(context.runtime); xmlNodeSet.setNodes(nodes); return xmlNodeSet; } - static XmlNodeSet newXmlNodeSet(ThreadContext context, RubyArray nodes) { - return newXmlNodeSet(context.getRuntime(), nodes); - } - /** * Create and return a copy of this object. * @@ -93,19 +102,18 @@ public Object clone() throws CloneNotSupportedException { return super.clone(); } - void setNodes(RubyArray array) { + void setNodes(IRubyObject[] array) { this.nodes = array; - IRubyObject first = array.first(); - initialize(array.getRuntime(), first); + IRubyObject first = array.length > 0 ? array[0] : null; + initialize(getRuntime(), first); } private void setReference(XmlNodeSet reference) { - this.nodes = null; - IRubyObject first = reference.nodes.first(); - initialize(reference.getRuntime(), first); + IRubyObject first = reference.nodes.length > 0 ? reference.nodes[0] : null; + initialize(getRuntime(), first); } - + public void setNodeList(NodeList nodeList) { setNodes(nodeListToRubyArray(getRuntime(), nodeList)); } @@ -118,106 +126,280 @@ final void initialize(Ruby runtime, IRubyObject refNode) { } public int length() { - if (nodes == null) return 0; - return nodes.size(); + return nodes == null ? 0 : nodes.length; } public void relink_namespace(ThreadContext context) { - List n = nodes.getList(); - - for (int i = 0; i < n.size(); i++) { - if (n.get(i) instanceof XmlNode) { - ((XmlNode) n.get(i)).relink_namespace(context); + for (int i = 0; i < nodes.length; i++) { + if (nodes[i] instanceof XmlNode) { + ((XmlNode) nodes[i]).relink_namespace(context); } } } @JRubyMethod(name="&") - public IRubyObject and(ThreadContext context, IRubyObject nodeSet) { - if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime())); - return newXmlNodeSet(context, (RubyArray) nodes.op_and(getNodes(context, nodeSet))); + public IRubyObject op_and(ThreadContext context, IRubyObject nodeSet) { + IRubyObject[] otherNodes = getNodes(context, nodeSet); + + if (otherNodes == null || otherNodes.length == 0) { + return newEmptyNodeSet(context); + } + + if (nodes == null || nodes.length == 0) { + return newEmptyNodeSet(context); + } + + IRubyObject[] curr = nodes; + IRubyObject[] other = getNodes(context, nodeSet); + IRubyObject[] result = new IRubyObject[nodes.length]; + + int last = 0; +outer: + for (int i = 0; i < curr.length; i++) { + IRubyObject n = curr[i]; + + for (int j = 0; j < other.length; j++) { + if (other[j] == n) { + result[last++] = n; + continue outer; + } + } + } + + XmlNodeSet newSet = newXmlNodeSet(context, Arrays.copyOf(result, last)); + newSet.setReference(this); + return newSet; } @JRubyMethod public IRubyObject delete(ThreadContext context, IRubyObject node_or_namespace) { - if (nodes == null) return context.getRuntime().getNil(); - if (node_or_namespace instanceof XmlNamespace) { - ((XmlNamespace) node_or_namespace).deleteHref(); + IRubyObject nodeOrNamespace = asXmlNodeOrNamespace(context, node_or_namespace); + + if (nodes.length == 0) { + return context.nil; + } + + IRubyObject[] orig = nodes; + IRubyObject[] result = new IRubyObject[nodes.length]; + + int last = 0; + + for (int i = 0; i < orig.length; i++) { + IRubyObject n = orig[i]; + + if (n == nodeOrNamespace) { + continue; + } + + result[last++] = n; } - return nodes.delete(context, asXmlNodeOrNamespace(context, node_or_namespace), Block.NULL_BLOCK); + + if (nodeOrNamespace instanceof XmlNamespace) { + ((XmlNamespace) nodeOrNamespace).deleteHref(); + } + + nodes = Arrays.copyOf(result, last); + + if (nodes.length < orig.length) { + // if we found the node return it + return nodeOrNamespace; + } + + return context.nil; } @JRubyMethod - public IRubyObject dup(ThreadContext context){ - if (nodes == null) return newEmptyNodeSet(context); - return newXmlNodeSet(context, nodes.aryDup()); + public IRubyObject dup(ThreadContext context) { + return newXmlNodeSet(context, nodes); } @JRubyMethod(name = "include?") public IRubyObject include_p(ThreadContext context, IRubyObject node_or_namespace) { - node_or_namespace = asXmlNodeOrNamespace(context, node_or_namespace); - if (nodes == null) return context.getRuntime().getFalse(); - return nodes.include_p(context, node_or_namespace); + for (int i = 0; i < nodes.length; i++) { + if (nodes[i] == node_or_namespace) { + return context.tru; + } + } + + return context.runtime.getFalse(); } @JRubyMethod(name = {"length", "size"}) public IRubyObject length(ThreadContext context) { - return nodes != null ? nodes.length() : context.getRuntime().newFixnum(0); + return context.getRuntime().newFixnum(nodes.length); } @JRubyMethod(name="-") public IRubyObject op_diff(ThreadContext context, IRubyObject nodeSet) { - XmlNodeSet xmlNodeSet = newXmlNodeSet(context, this); - if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime())); - xmlNodeSet.setNodes((RubyArray) nodes.op_diff(getNodes(context, nodeSet))); - return xmlNodeSet; + IRubyObject[] otherNodes = getNodes(context, nodeSet); + + if (otherNodes.length == 0) { + return dup(context); + } + + if (nodes.length == 0) { + return newEmptyNodeSet(context); + } + + IRubyObject[] curr = nodes; + IRubyObject[] other = getNodes(context, nodeSet); + IRubyObject[] result = new IRubyObject[nodes.length]; + + int last = 0; +outer: + for (int i = 0; i < curr.length; i++) { + IRubyObject n = curr[i]; + + for (int j = 0; j < other.length; j++) { + if (other[j] == n) { + continue outer; + } + } + + result[last++] = n; + } + + XmlNodeSet newSet = newXmlNodeSet(context, Arrays.copyOf(result, last)); + newSet.setReference(this); + return newSet; } @JRubyMethod(name={"|", "+"}) public IRubyObject op_or(ThreadContext context, IRubyObject nodeSet) { - if (nodes == null) setNodes(RubyArray.newEmptyArray(context.getRuntime())); - return newXmlNodeSet(context, (RubyArray) nodes.op_or(getNodes(context, nodeSet))); + IRubyObject[] otherNodes = getNodes(context, nodeSet); + + if (nodes.length == 0) { + return ((XmlNodeSet) nodeSet).dup(context); + } + + if (otherNodes.length == 0) { + return dup(context); + } + + IRubyObject[] curr = nodes; + IRubyObject[] other = getNodes(context, nodeSet); + IRubyObject[] result = Arrays.copyOf(curr, curr.length + other.length); + + int last = curr.length; +outer: + for (int i = 0; i < other.length; i++) { + IRubyObject n = other[i]; + + for (int j = 0; j < curr.length; j++) { + if (curr[j] == n) { + continue outer; + } + } + + result[last++] = n; + } + + XmlNodeSet newSet = newXmlNodeSet(context, Arrays.copyOf(result, last)); + newSet.setReference(this); + return newSet; } @JRubyMethod(name = {"push", "<<"}) public IRubyObject push(ThreadContext context, IRubyObject node_or_namespace) { - if (nodes == null) setNodes(RubyArray.newArray(context.getRuntime())); - nodes.append(asXmlNodeOrNamespace(context, node_or_namespace)); + nodes = Arrays.copyOf(nodes, nodes.length+1); + nodes[nodes.length-1] = node_or_namespace; return this; } + // replace with + // https://github.com/jruby/jruby/blame/13a3ec76d883a162b9d46c374c6e9eeea27b3261/core/src/main/java/org/jruby/RubyRange.java#L974 + // once we upgraded the min JRuby version to >= 9.2 + private static IRubyObject rangeBeginLength(ThreadContext context, IRubyObject rangeMaybe, int len, int[] begLen) { + RubyRange range = (RubyRange) rangeMaybe; + int min = range.begin(context).convertToInteger().getIntValue(); + int max = range.end(context).convertToInteger().getIntValue(); + + if (min < 0) { + min += len; + if (min < 0) { + throw context.runtime.newRangeError(min + ".." + (range.isExcludeEnd() ? "." : "") + max + " out of range"); + } + } + + if (max < 0) { + max += len; + } + + if (!range.isExcludeEnd()) { + max++; + } + + begLen[0] = min; + begLen[1] = max; + return context.tru; + } + + @JRubyMethod(name={"[]", "slice"}) - public IRubyObject slice(ThreadContext context, IRubyObject indexOrRange){ - if (nodes == null) return context.getRuntime().getNil(); - IRubyObject result = nodes.aref19(indexOrRange); - if (result instanceof RubyArray) { - return newXmlNodeSet(context, (RubyArray) result); + public IRubyObject slice(ThreadContext context, IRubyObject indexOrRange) { + if (indexOrRange instanceof RubyFixnum) { + int idx = ((RubyFixnum)indexOrRange).getIntValue(); + + if (idx < 0) { + idx += nodes.length; + } + + if (idx >= nodes.length || idx < 0) { + return context.nil; + } + + return nodes[idx]; } - return result; + + int[] begLen = new int[2]; + rangeBeginLength(context, indexOrRange, nodes.length, begLen); + int min = begLen[0]; + int max = begLen[1]; + return subseq(context, min, max - min); } @JRubyMethod(name={"[]", "slice"}) - public IRubyObject slice(ThreadContext context, IRubyObject start, IRubyObject length){ - if (nodes == null) return context.getRuntime().getNil(); - IRubyObject result = nodes.aref19(start, length); - if (result instanceof RubyArray) { - return newXmlNodeSet(context, (RubyArray) result); + public IRubyObject slice(ThreadContext context, IRubyObject start, IRubyObject length) { + int s = ((RubyFixnum) start).getIntValue(); + int l = ((RubyFixnum) length).getIntValue(); + + if (s < 0) { + s += nodes.length; } - return context.getRuntime().getNil(); + + return subseq(context, s, l); + } + + public IRubyObject subseq(ThreadContext context, int start, int length) { + if (start > nodes.length) { + return context.nil; + } + + if (start < 0 || length < 0) { + return context.nil; + } + + if (start + length > nodes.length) { + length = nodes.length - start; + } + + int to = start + length; + + IRubyObject[] newNodes = Arrays.copyOfRange(nodes, start, to); + + return newXmlNodeSet(context, newNodes); } @JRubyMethod(name = {"to_a", "to_ary"}) public IRubyObject to_a(ThreadContext context) { - return nodes; + return context.runtime.newArrayNoCopy(nodes); } @JRubyMethod(name = {"unlink", "remove"}) - public IRubyObject unlink(ThreadContext context){ - if (nodes == null) return this; - IRubyObject[] arr = nodes.toJavaArrayUnsafe(); - for (int i = 0; i < arr.length; i++) { - if (arr[i] instanceof XmlNode) { - ((XmlNode) arr[i] ).unlink(context); + public IRubyObject unlink(ThreadContext context) { + for (int i = 0; i < nodes.length; i++) { + if (nodes[i] instanceof XmlNode) { + ((XmlNode) nodes[i] ).unlink(context); } } return this; @@ -226,6 +408,7 @@ public IRubyObject unlink(ThreadContext context){ private static XmlNodeSet newXmlNodeSet(ThreadContext context, XmlNodeSet reference) { XmlNodeSet xmlNodeSet = create(context.getRuntime()); xmlNodeSet.setReference(reference); + xmlNodeSet.nodes = new IRubyObject[0]; return xmlNodeSet; } @@ -236,21 +419,19 @@ private static IRubyObject asXmlNodeOrNamespace(ThreadContext context, IRubyObje throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace"); } - private static RubyArray getNodes(ThreadContext context, IRubyObject possibleNodeSet) { + static IRubyObject[] getNodes(ThreadContext context, IRubyObject possibleNodeSet) { if (possibleNodeSet instanceof XmlNodeSet) { - RubyArray nodes = ((XmlNodeSet) possibleNodeSet).nodes; - return nodes == null ? RubyArray.newEmptyArray(context.getRuntime()) : nodes; + return ((XmlNodeSet) possibleNodeSet).nodes; } throw context.getRuntime().newArgumentError("node must be a Nokogiri::XML::NodeSet"); } - + public int getLength() { - return nodes == null ? 0 : nodes.size(); + return nodes.length; } - + public Node item(int index) { - if (nodes == null) return null; - Object n = nodes.get(index); + Object n = nodes[index]; if (n instanceof XmlNode) return ((XmlNode)n).node; if (n instanceof XmlNamespace) return ((XmlNamespace)n).getNode(); return null; diff --git a/ext/java/nokogiri/XmlXpathContext.java b/ext/java/nokogiri/XmlXpathContext.java index 0b04acb84e..f142b4eaf4 100644 --- a/ext/java/nokogiri/XmlXpathContext.java +++ b/ext/java/nokogiri/XmlXpathContext.java @@ -36,10 +36,12 @@ import javax.xml.transform.TransformerException; -import nokogiri.internals.NokogiriNamespaceContext; -import nokogiri.internals.NokogiriXPathFunctionResolver; -import nokogiri.internals.NokogiriXPathVariableResolver; - +import org.apache.xml.dtm.DTM; +import org.apache.xpath.XPath; +import org.apache.xpath.XPathContext; +import org.apache.xpath.jaxp.JAXPPrefixResolver; +import org.apache.xpath.jaxp.JAXPVariableStack; +import org.apache.xpath.objects.XObject; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyObject; @@ -51,13 +53,9 @@ import org.jruby.util.SafePropertyAccessor; import org.w3c.dom.Node; -import org.apache.xml.dtm.DTM; -import org.apache.xpath.XPath; -import org.apache.xpath.XPathContext; -import org.apache.xpath.jaxp.JAXPExtensionsProvider; -import org.apache.xpath.jaxp.JAXPPrefixResolver; -import org.apache.xpath.jaxp.JAXPVariableStack; -import org.apache.xpath.objects.XObject; +import nokogiri.internals.NokogiriNamespaceContext; +import nokogiri.internals.NokogiriXPathFunctionResolver; +import nokogiri.internals.NokogiriXPathVariableResolver; /** * Class for Nokogiri::XML::XpathContext @@ -186,7 +184,7 @@ private IRubyObject tryGetNodeSet(ThreadContext context, String expr, NokogiriXP case XObject.CLASS_BOOLEAN : return context.getRuntime().newBoolean(xobj.bool()); case XObject.CLASS_NUMBER : return context.getRuntime().newFloat(xobj.num()); case XObject.CLASS_NODESET : - XmlNodeSet xmlNodeSet = XmlNodeSet.create(context.getRuntime()); + XmlNodeSet xmlNodeSet = XmlNodeSet.newEmptyNodeSet(context); xmlNodeSet.setNodeList(xobj.nodelist()); xmlNodeSet.initialize(context.getRuntime(), this.context); return xmlNodeSet; diff --git a/ext/java/nokogiri/internals/NokogiriHelpers.java b/ext/java/nokogiri/internals/NokogiriHelpers.java index 5487d40843..88b4150054 100644 --- a/ext/java/nokogiri/internals/NokogiriHelpers.java +++ b/ext/java/nokogiri/internals/NokogiriHelpers.java @@ -34,7 +34,6 @@ import java.io.ByteArrayInputStream; import java.io.File; -import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.ByteBuffer; @@ -44,6 +43,20 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jruby.Ruby; +import org.jruby.RubyArray; +import org.jruby.RubyClass; +import org.jruby.RubyString; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ByteList; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import nokogiri.HtmlDocument; import nokogiri.NokogiriService; import nokogiri.XmlAttr; @@ -59,21 +72,6 @@ import nokogiri.XmlText; import nokogiri.XmlXpathContext; -import org.jruby.Ruby; -import org.jruby.RubyArray; -import org.jruby.RubyClass; -import org.jruby.RubyEncoding; -import org.jruby.RubyString; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.util.ByteList; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.DOMException; - /** * A class for various utility methods. * @@ -627,16 +625,20 @@ public static String newQName(String newPrefix, Node node) { return newPrefix + ':' + tagName; } - public static RubyArray nodeListToRubyArray(Ruby ruby, NodeList nodes) { - RubyArray array = RubyArray.newArray(ruby, nodes.getLength()); - return nodeListToRubyArray(ruby, nodes, array); + public static IRubyObject[] nodeListToRubyArray(Ruby ruby, NodeList nodes) { + IRubyObject[] array = new IRubyObject[nodes.getLength()]; + for (int i = 0; i < nodes.getLength(); i++) { + array[i] = NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.item(i)); + } + return array; } - public static RubyArray nodeListToRubyArray(Ruby ruby, NodeList nodes, RubyArray array) { - for(int i = 0; i < nodes.getLength(); i++) { - array.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.item(i))); + public static IRubyObject[] nodeArrayToArray(Ruby ruby, Node[] nodes) { + IRubyObject[] result = new IRubyObject[nodes.length]; + for(int i = 0; i < nodes.length; i++) { + result[i] = NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes[i]); } - return array; + return result; } public static RubyArray nodeArrayToRubyArray(Ruby ruby, Node[] nodes) { diff --git a/ext/java/nokogiri/internals/NokogiriXPathFunction.java b/ext/java/nokogiri/internals/NokogiriXPathFunction.java index 7e12668ca3..022c7741f1 100644 --- a/ext/java/nokogiri/internals/NokogiriXPathFunction.java +++ b/ext/java/nokogiri/internals/NokogiriXPathFunction.java @@ -37,9 +37,6 @@ import javax.xml.xpath.XPathFunction; import javax.xml.xpath.XPathFunctionException; -import nokogiri.XmlNode; -import nokogiri.XmlNodeSet; - import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; @@ -53,6 +50,9 @@ import org.jruby.runtime.builtin.IRubyObject; import org.w3c.dom.NodeList; +import nokogiri.XmlNode; +import nokogiri.XmlNodeSet; + /** * Xpath function handler. * @@ -99,7 +99,7 @@ private static IRubyObject[] fromObjectToRubyArgs(final Ruby runtime, List args) private static IRubyObject fromObjectToRuby(final Ruby runtime, Object obj) { // argument object type is one of NodeList, String, Boolean, or Double. if (obj instanceof NodeList) { - XmlNodeSet xmlNodeSet = XmlNodeSet.create(runtime); + XmlNodeSet xmlNodeSet = XmlNodeSet.newEmptyNodeSet(runtime.getCurrentContext()); xmlNodeSet.setNodeList((NodeList) obj); return xmlNodeSet; } @@ -116,7 +116,7 @@ private static Object fromRubyToObject(final Ruby runtime, IRubyObject obj) { } if (obj instanceof XmlNodeSet) return obj; if (obj instanceof RubyArray) { - return XmlNodeSet.newXmlNodeSet(runtime, (RubyArray) obj); + return XmlNodeSet.newXmlNodeSet(runtime.getCurrentContext(), ((RubyArray) obj).toJavaArray()); } /*if (o instanceof XmlNode)*/ return ((XmlNode) obj).getNode(); } From 602d2ef751fe680a6cde08e9a56891db5807bad6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sat, 1 Dec 2018 21:28:39 -0500 Subject: [PATCH 142/176] add test coverage for fix addressing #1784 which is GCing removed DTD nodes. --- test/html/test_document.rb | 10 ++++++++++ test/test_memory_leak.rb | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/test/html/test_document.rb b/test/html/test_document.rb index 1a88080a6a..c8c68ff44b 100644 --- a/test/html/test_document.rb +++ b/test/html/test_document.rb @@ -707,6 +707,16 @@ def test_silencing_nonparse_errors_during_attribute_insertion_1262 assert_equal 'ISO-8859-1', html.encoding.name end + def test_leaking_dtd_nodes_after_internal_subset_removal + # see https://github.com/sparklemotion/nokogiri/issues/1784 + # + # just checking that this doesn't raise a valgrind error. we + # don't otherwise have any test coverage for removing DTDs. + # + 100.times do |i| + Nokogiri::HTML::Document.new.internal_subset.remove + end + end end end end diff --git a/test/test_memory_leak.rb b/test/test_memory_leak.rb index 8e6fc1d82b..a778ed43e6 100644 --- a/test/test_memory_leak.rb +++ b/test/test_memory_leak.rb @@ -190,6 +190,15 @@ def test_leaking_namespace_node_strings_with_prefix puts MemInfo.rss end end + + def test_leaking_dtd_nodes_after_internal_subset_removal + # see https://github.com/sparklemotion/nokogiri/issues/1784 + 100_000.times do |i| + doc = Nokogiri::HTML::Document.new + doc.internal_subset.remove + puts MemInfo.rss if (i % 1000 == 0) + end + end end # if NOKOGIRI_GC module MemInfo From 45d8c681df745f729c30d6512507e43f5c356e50 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 00:08:19 -0500 Subject: [PATCH 143/176] update CHANGELOG --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6600293e9..a301aee500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,19 @@ -# unreleased +# next / unreleased ## Features -* [MRI] Address installation challenges on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) +* [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) +* [JRuby] NodeSet has been rewritten to improve performance! [#1795] ## Bug fixes * `NodeSet#each` now returns `self` instead of zero. [#1822] (Thanks, @olehif!) * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] +* [MRI] Address a memory leak when unparenting a DTD. [#1784] (Thanks, @stevecheckoway!) +* [MRI] Decrease large memory usage when making nested XPath queries. [#1749] * [JRuby] Fix failing tests on JRuby 9.2.x +* [JRuby] Fix default namespaces in nodes reparented into a different document [#1774] # 1.8.5 / 2018-10-04 From 01664a1644d6151072b5a011ef98b8e7398f92d6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 00:14:55 -0500 Subject: [PATCH 144/176] clean up syntax warnings in test suite --- test/helper.rb | 2 +- test/xml/test_node_reparenting.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index e7b6442ecf..bf25f056b8 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -213,7 +213,7 @@ def initialize .each do |name| define_method name do |*arguments| @items << [name, *arguments] - super *arguments + super(*arguments) end end diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb index f155a36bbf..26ccddeef9 100644 --- a/test/xml/test_node_reparenting.rb +++ b/test/xml/test_node_reparenting.rb @@ -235,7 +235,7 @@ class TestNodeReparenting < Nokogiri::TestCase end it "serializes the doc with the proper default namespace" do - assert_match //, @doc.to_xml + assert_match(//, @doc.to_xml) end end @@ -248,7 +248,7 @@ class TestNodeReparenting < Nokogiri::TestCase end it "serializes the doc with the proper default namespace" do - assert_match //, @doc.to_xml + assert_match(//, @doc.to_xml) end end @@ -261,7 +261,7 @@ class TestNodeReparenting < Nokogiri::TestCase end it "serializes the doc with the proper default namespace" do - assert_match //, @doc.to_xml + assert_match(//, @doc.to_xml) end end @@ -274,7 +274,7 @@ class TestNodeReparenting < Nokogiri::TestCase end it "serializes the doc with the proper default namespace" do - assert_match //, @doc.to_xml + assert_match(//, @doc.to_xml) end end end From 3c5847ed157b34ee2d8b10de9aff5c8128a51c63 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 01:40:32 -0500 Subject: [PATCH 145/176] setting attribute value to blank in HTML doc now renders as blank previously was rendered as a boolean attribute. also allow for boolean attributes by setting value to `nil`. Fixes #1800. --- ext/java/nokogiri/XmlAttr.java | 4 ++- ext/nokogiri/xml_attr.c | 46 ++++++++++++++++++---------------- test/xml/test_attr.rb | 24 +++++++++++++++++- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/ext/java/nokogiri/XmlAttr.java b/ext/java/nokogiri/XmlAttr.java index 945bec51b3..06235d930d 100644 --- a/ext/java/nokogiri/XmlAttr.java +++ b/ext/java/nokogiri/XmlAttr.java @@ -130,7 +130,9 @@ public IRubyObject content(ThreadContext context) { @JRubyMethod(name = {"value=", "content="}) public IRubyObject value_set(ThreadContext context, IRubyObject content){ Attr attr = (Attr) node; - attr.setValue(rubyStringToString(XmlNode.encode_special_chars(context, content))); + if (content != null && !content.isNil()) { + attr.setValue(rubyStringToString(XmlNode.encode_special_chars(context, content))); + } setContent(content); return content; } diff --git a/ext/nokogiri/xml_attr.c b/ext/nokogiri/xml_attr.c index 1e1e1de325..9d6d7b702e 100644 --- a/ext/nokogiri/xml_attr.c +++ b/ext/nokogiri/xml_attr.c @@ -4,37 +4,39 @@ * call-seq: * value=(content) * - * Set the value for this Attr to +content+ + * Set the value for this Attr to +content+. Use `nil` to remove the value + * (e.g., a HTML boolean attribute). */ static VALUE set_value(VALUE self, VALUE content) { xmlAttrPtr attr; - Data_Get_Struct(self, xmlAttr, attr); + xmlChar *value; - if (attr->children) { xmlFreeNodeList(attr->children); } + Data_Get_Struct(self, xmlAttr, attr); + if (attr->children) { + xmlFreeNodeList(attr->children); + } attr->children = attr->last = NULL; - if (content) { - xmlChar *buffer; - xmlNode *tmp; - - /* Encode our content */ - buffer = xmlEncodeEntitiesReentrant(attr->doc, (unsigned char *)StringValueCStr(content)); + if (content == Qnil) { + return content; + } - attr->children = xmlStringGetNodeList(attr->doc, buffer); - attr->last = NULL; - tmp = attr->children; + value = xmlEncodeEntitiesReentrant(attr->doc, (unsigned char *)StringValueCStr(content)); + if (xmlStrlen(value) == 0) { + attr->children = xmlNewDocText(attr->doc, value); + } else { + attr->children = xmlStringGetNodeList(attr->doc, value); + } + xmlFree(value); - /* Loop through the children */ - for(tmp = attr->children; tmp; tmp = tmp->next) { - tmp->parent = (xmlNode *)attr; - tmp->doc = attr->doc; - if (tmp->next == NULL) { attr->last = tmp; } + for (xmlNode *cur = attr->children; cur; cur = cur->next) { + cur->parent = (xmlNode *)attr; + cur->doc = attr->doc; + if (cur->next == NULL) { + attr->last = cur; } - - /* Free up memory */ - xmlFree(buffer); } return content; @@ -74,7 +76,9 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) rb_node = Nokogiri_wrap_xml_node(klass, (xmlNodePtr)node); rb_obj_call_init(rb_node, argc, argv); - if (rb_block_given_p()) { rb_yield(rb_node); } + if (rb_block_given_p()) { + rb_yield(rb_node); + } return rb_node; } diff --git a/test/xml/test_attr.rb b/test/xml/test_attr.rb index 12082a357c..82595eb417 100644 --- a/test/xml/test_attr.rb +++ b/test/xml/test_attr.rb @@ -26,12 +26,34 @@ def test_content= assert_equal "Y&ent1;", street.value end - def test_value= + def test_set_value xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE) address = xml.xpath('//address')[3] street = address.attributes['street'] street.value = "Y&ent1;" assert_equal "Y&ent1;", street.value + assert_includes %Q{ street="Y&ent1;"}, street.to_xml + end + + def test_set_value_with_entity_string_in_html_file + html = Nokogiri::HTML("
") + foo = html.at_css("div").attributes["foo"] + foo.value = "Y&ent1;" + assert_includes %Q{ foo="Y&ent1;"}, foo.to_html + end + + def test_set_value_with_blank_string_in_html_file + html = Nokogiri::HTML("
") + foo = html.at_css("div").attributes["foo"] + foo.value = "" + assert_includes %Q{ foo=""}, foo.to_html + end + + def test_set_value_of_boolean_attr_with_nil_in_html_file + html = Nokogiri::HTML("
") + disabled = html.at_css("div").attributes["disabled"] + disabled.value = nil + assert_includes %Q{ disabled}, disabled.to_html end def test_unlink # aliased as :remove From 9978e3f37008513cf7404385daba534370cf62e8 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 02:05:22 -0500 Subject: [PATCH 146/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a301aee500..3bab6002e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) * [JRuby] NodeSet has been rewritten to improve performance! [#1795] +* `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] ## Bug fixes From cdf7fd8a44d1ca4e48668eb8eae5a23908698932 Mon Sep 17 00:00:00 2001 From: ethiraj Date: Thu, 15 Sep 2016 00:42:54 +0530 Subject: [PATCH 147/176] Add method #wrap to Nokogiri::XML::Element --- Manifest.txt | 2 ++ lib/nokogiri/xml.rb | 1 + lib/nokogiri/xml/element.rb | 13 +++++++++++++ test/xml/test_element.rb | 28 ++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 lib/nokogiri/xml/element.rb create mode 100644 test/xml/test_element.rb diff --git a/Manifest.txt b/Manifest.txt index 7e8b83ef7c..9a2764c83c 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -215,6 +215,7 @@ lib/nokogiri/xml/character_data.rb lib/nokogiri/xml/document.rb lib/nokogiri/xml/document_fragment.rb lib/nokogiri/xml/dtd.rb +lib/nokogiri/xml/element.rb lib/nokogiri/xml/element_content.rb lib/nokogiri/xml/element_decl.rb lib/nokogiri/xml/entity_decl.rb @@ -344,6 +345,7 @@ test/xml/test_document_encoding.rb test/xml/test_document_fragment.rb test/xml/test_dtd.rb test/xml/test_dtd_encoding.rb +test/xml/test_element.rb test/xml/test_element_content.rb test/xml/test_element_decl.rb test/xml/test_entity_decl.rb diff --git a/lib/nokogiri/xml.rb b/lib/nokogiri/xml.rb index bbb8c81b88..2f6afd48d9 100644 --- a/lib/nokogiri/xml.rb +++ b/lib/nokogiri/xml.rb @@ -4,6 +4,7 @@ require 'nokogiri/xml/searchable' require 'nokogiri/xml/node' require 'nokogiri/xml/attribute_decl' +require 'nokogiri/xml/element' require 'nokogiri/xml/element_decl' require 'nokogiri/xml/element_content' require 'nokogiri/xml/character_data' diff --git a/lib/nokogiri/xml/element.rb b/lib/nokogiri/xml/element.rb new file mode 100644 index 0000000000..1223ae4154 --- /dev/null +++ b/lib/nokogiri/xml/element.rb @@ -0,0 +1,13 @@ +module Nokogiri + module XML + class Element + + def wrap(html) + new_parent = document.parse(html).first + add_next_sibling(new_parent) + new_parent.add_child(self) + self + end + end + end +end \ No newline at end of file diff --git a/test/xml/test_element.rb b/test/xml/test_element.rb new file mode 100644 index 0000000000..567ef44537 --- /dev/null +++ b/test/xml/test_element.rb @@ -0,0 +1,28 @@ +require "helper" + +module Nokogiri + module XML + class TestElementContent < Nokogiri::TestCase + + def test_wrap + xml = ' + +
important thing
+
+ +
stuff
+
+ +

more stuff

+ + ' + document = Nokogiri::XML(xml) + things = document.xpath(".//thing") + things[0].wrap("") + assert_equal 'wrapper', things[0].parent.name + assert_equal 'thing', document.search("//wrapper").first.children[0].name + end + + end + end +end From a52bbb296446937d3b0e80d418f94e5d72c56bee Mon Sep 17 00:00:00 2001 From: ethiraj Date: Thu, 19 Jan 2017 00:48:31 +0800 Subject: [PATCH 148/176] move wrap to XML::Node --- Manifest.txt | 1 - lib/nokogiri/xml.rb | 1 - lib/nokogiri/xml/element.rb | 13 ------------- lib/nokogiri/xml/node.rb | 12 ++++++++++++ lib/nokogiri/xml/node_set.rb | 11 +++-------- 5 files changed, 15 insertions(+), 23 deletions(-) delete mode 100644 lib/nokogiri/xml/element.rb diff --git a/Manifest.txt b/Manifest.txt index 9a2764c83c..fc2490b98f 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -215,7 +215,6 @@ lib/nokogiri/xml/character_data.rb lib/nokogiri/xml/document.rb lib/nokogiri/xml/document_fragment.rb lib/nokogiri/xml/dtd.rb -lib/nokogiri/xml/element.rb lib/nokogiri/xml/element_content.rb lib/nokogiri/xml/element_decl.rb lib/nokogiri/xml/entity_decl.rb diff --git a/lib/nokogiri/xml.rb b/lib/nokogiri/xml.rb index 2f6afd48d9..bbb8c81b88 100644 --- a/lib/nokogiri/xml.rb +++ b/lib/nokogiri/xml.rb @@ -4,7 +4,6 @@ require 'nokogiri/xml/searchable' require 'nokogiri/xml/node' require 'nokogiri/xml/attribute_decl' -require 'nokogiri/xml/element' require 'nokogiri/xml/element_decl' require 'nokogiri/xml/element_content' require 'nokogiri/xml/character_data' diff --git a/lib/nokogiri/xml/element.rb b/lib/nokogiri/xml/element.rb deleted file mode 100644 index 1223ae4154..0000000000 --- a/lib/nokogiri/xml/element.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Nokogiri - module XML - class Element - - def wrap(html) - new_parent = document.parse(html).first - add_next_sibling(new_parent) - new_parent.add_child(self) - self - end - end - end -end \ No newline at end of file diff --git a/lib/nokogiri/xml/node.rb b/lib/nokogiri/xml/node.rb index ebd3e74a05..225481acf5 100644 --- a/lib/nokogiri/xml/node.rb +++ b/lib/nokogiri/xml/node.rb @@ -161,6 +161,18 @@ def prepend_child node_or_tags end end + + ### + # Add html around this node + # + # Returns self + def wrap(html) + new_parent = document.parse(html).first + add_next_sibling(new_parent) + new_parent.add_child(self) + self + end + ### # Add +node_or_tags+ as a child of this Node. # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup. diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb index 1e52613bb7..68479d684f 100644 --- a/lib/nokogiri/xml/node_set.rb +++ b/lib/nokogiri/xml/node_set.rb @@ -231,14 +231,9 @@ def inner_html *args end ### - # Wrap this NodeSet with +html+ or the results of the builder in +blk+ - def wrap(html, &blk) - each do |j| - new_parent = document.parse(html).first - j.add_next_sibling(new_parent) - new_parent.add_child(j) - end - self + # Wrap this NodeSet with +html+ + def wrap html + map { |node| node.wrap html } end ### From ba53dee5266d764e141ffad5856d14619c208a58 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 02:41:07 -0500 Subject: [PATCH 149/176] move Node#wrap tests out of test_element.rb and put them in: - test_node.rb - test_text.rb also added test coverage for this in - test_node_set.rb this is a follow-on commit to #1531 by @ethirajsrinivasan --- Manifest.txt | 1 - test/xml/test_element.rb | 28 ---------------------------- test/xml/test_node.rb | 9 +++++++++ test/xml/test_node_set.rb | 13 +++++++++++++ test/xml/test_text.rb | 9 +++++++++ 5 files changed, 31 insertions(+), 29 deletions(-) delete mode 100644 test/xml/test_element.rb diff --git a/Manifest.txt b/Manifest.txt index fc2490b98f..7e8b83ef7c 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -344,7 +344,6 @@ test/xml/test_document_encoding.rb test/xml/test_document_fragment.rb test/xml/test_dtd.rb test/xml/test_dtd_encoding.rb -test/xml/test_element.rb test/xml/test_element_content.rb test/xml/test_element_decl.rb test/xml/test_entity_decl.rb diff --git a/test/xml/test_element.rb b/test/xml/test_element.rb deleted file mode 100644 index 567ef44537..0000000000 --- a/test/xml/test_element.rb +++ /dev/null @@ -1,28 +0,0 @@ -require "helper" - -module Nokogiri - module XML - class TestElementContent < Nokogiri::TestCase - - def test_wrap - xml = ' - -
important thing
-
- -
stuff
-
- -

more stuff

- - ' - document = Nokogiri::XML(xml) - things = document.xpath(".//thing") - things[0].wrap("") - assert_equal 'wrapper', things[0].parent.name - assert_equal 'thing', document.search("//wrapper").first.children[0].name - end - - end - end -end diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index 07cba2cef0..107fc5d7cc 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -1327,6 +1327,15 @@ def test_text_node_robustness_gh1426 node.add_next_sibling(Nokogiri::XML::Text.new('after', node.document)) end end + + def test_wrap + xml = '
important thing
' + doc = Nokogiri::XML(xml) + thing = doc.at_css("thing") + thing.wrap("") + assert_equal 'wrapper', thing.parent.name + assert_equal 'thing', doc.at_css("wrapper").children.first.name + end end end end diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb index d934952fae..83bbd60e54 100644 --- a/test/xml/test_node_set.rb +++ b/test/xml/test_node_set.rb @@ -511,6 +511,19 @@ def test_wrap assert_equal 'employee', @xml.search("//wrapper").first.children[0].name end + def test_wrap_various_node_types + xml = 'contents' + doc = Nokogiri::XML xml + nodes = doc.at_css("root").xpath(".//* | .//*/text()") # foo and "contents" + nodes.wrap("") + wrappers = doc.css("wrapper") + assert_equal "root", wrappers.first.parent.name + assert_equal "foo", wrappers.first.children.first.name + assert_equal "foo", wrappers.last.parent.name + assert wrappers.last.children.first.text? + assert_equal "contents", wrappers.last.children.first.text + end + def test_wrap_a_fragment frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML diff --git a/test/xml/test_text.rb b/test/xml/test_text.rb index b9dec941c9..661502e206 100644 --- a/test/xml/test_text.rb +++ b/test/xml/test_text.rb @@ -55,6 +55,15 @@ def test_add_child node << Text.new('bar', Document.new) } end + + def test_wrap + xml = '
important thing
' + doc = Nokogiri::XML(xml) + text = doc.at_css("div").children.first + text.wrap("") + assert_equal 'wrapper', text.parent.name + assert_equal 'wrapper', doc.at_css("div").children.first.name + end end end end From 4e19f323ee153f3f5e89f3ff48e101b7aefc44ec Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 02:51:09 -0500 Subject: [PATCH 150/176] update CHANGELOG [skip ci] --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bab6002e0..61108a32ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ ## Features +* `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] +* Introduce `XML::Node#wrap` which does what `XML::NodeSet#wrap` has always done, but for a single node. [#1531] (Thanks, @ethirajsrinivasan!) * [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) * [JRuby] NodeSet has been rewritten to improve performance! [#1795] -* `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] ## Bug fixes From 2bbc84db06891325fb9d3124a327330a645b134d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 02:59:33 -0500 Subject: [PATCH 151/176] avoid non-portable C variable declaration --- ext/nokogiri/xml_attr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/nokogiri/xml_attr.c b/ext/nokogiri/xml_attr.c index 9d6d7b702e..9858cd3976 100644 --- a/ext/nokogiri/xml_attr.c +++ b/ext/nokogiri/xml_attr.c @@ -11,6 +11,7 @@ static VALUE set_value(VALUE self, VALUE content) { xmlAttrPtr attr; xmlChar *value; + xmlNode *cur; Data_Get_Struct(self, xmlAttr, attr); @@ -31,7 +32,7 @@ static VALUE set_value(VALUE self, VALUE content) } xmlFree(value); - for (xmlNode *cur = attr->children; cur; cur = cur->next) { + for (cur = attr->children; cur; cur = cur->next) { cur->parent = (xmlNode *)attr; cur->doc = attr->doc; if (cur->next == NULL) { From 6557985b2364a496230dc3cec823fe114de97147 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 03:47:31 -0500 Subject: [PATCH 152/176] concourse: remove windows ruby 2.3 as a req for build-success see #1793 for status on standing up Windows boxen --- concourse/nokogiri.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml index 8bf7bef26b..0c092b8dfd 100644 --- a/concourse/nokogiri.yml +++ b/concourse/nokogiri.yml @@ -376,9 +376,9 @@ jobs: # <% for rbx_version in RUBIES[:rbx] %> # - "rbx-<%= rbx_version %>-vendored" # <% end %> - <% RUBIES[:windows].first(1).each do |ruby_version| %> - - "win-ruby-<%= ruby_version %>-devkit" - <% end %> + # <% RUBIES[:windows].first(1).each do |ruby_version| %> + # - "win-ruby-<%= ruby_version %>-devkit" + # <% end %> - put: nokogiri-irc params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"} From bf42407c3f33ab557e4604251a5285a924e8447d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 2 Dec 2018 21:20:46 -0500 Subject: [PATCH 153/176] update mini_portile2 dep from 2.3 to 2.4. --- CHANGELOG.md | 5 +++++ Gemfile | 6 +++--- Rakefile | 2 +- ext/nokogiri/extconf.rb | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61108a32ba..a731acf977 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,11 @@ * [JRuby] Fix default namespaces in nodes reparented into a different document [#1774] +## Dependencies + +* [MRI] Upgrade mini_portile2 dependency from `~> 2.3.0` to `~> 2.4.0` + + # 1.8.5 / 2018-10-04 ## Security Notes diff --git a/Gemfile b/Gemfile index 80b8736423..d65802f1f5 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org/" -gem "mini_portile2", "~>2.3.0" +gem "mini_portile2", "~>2.4.0" gem "hoe-bundler", "~>1.2", :group => [:development, :test] gem "hoe-debugging", "~>2.0", :group => [:development, :test] @@ -17,7 +17,7 @@ gem "rake-compiler-dock", "~>0.6.2", :group => [:development, :test] gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] gem "concourse", "~>0.15", :group => [:development, :test] -gem "rdoc", "~>4.0", :group => [:development, :test] -gem "hoe", "~>3.16", :group => [:development, :test] +gem "rdoc", ">=4.0", "<7", :group => [:development, :test] +gem "hoe", "~>3.17", :group => [:development, :test] # vim: syntax=ruby diff --git a/Rakefile b/Rakefile index ea11d13973..074b6a06e6 100644 --- a/Rakefile +++ b/Rakefile @@ -127,7 +127,7 @@ HOE = Hoe.spec 'nokogiri' do unless java? self.extra_deps += [ - ["mini_portile2", "~> 2.3.0"], # keep version in sync with extconf.rb + ["mini_portile2", "~> 2.4.0"], # keep version in sync with extconf.rb ] end diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index 4822d62531..7c83cf656f 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -462,7 +462,7 @@ def using_system_libraries? # The gem version constraint in the Rakefile is not respected at install time. # Keep this version in sync with the one in the Rakefile ! require 'rubygems' - gem 'mini_portile2', '~> 2.3.0' + gem 'mini_portile2', '~> 2.4.0' require 'mini_portile2' message "Using mini_portile version #{MiniPortile::VERSION}\n" From d33a9f68c76272b237cc612d2cfa42dccb796868 Mon Sep 17 00:00:00 2001 From: "Taylor C. Richberger" Date: Mon, 14 May 2018 18:14:42 -0600 Subject: [PATCH 154/176] fix DOM2DTM to work in J9 J9 wasn't coping with hot-patching standard library packages with a user class. This was done to work around a package private constructor. This is fixed by moving into a local package and copying the class with the package private constructor into a local copy. --- Manifest.txt | 3 +- .../internals/XalanDTMManagerPatch.java | 18 +- .../internals/dom2dtm/DOM2DTM.java} | 10 +- ...OM2DTMdefaultNamespaceDeclarationNode.java | 685 ++++++++++++++++++ 4 files changed, 702 insertions(+), 14 deletions(-) rename ext/java/{org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java => nokogiri/internals/dom2dtm/DOM2DTM.java} (99%) create mode 100644 ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java diff --git a/Manifest.txt b/Manifest.txt index 7e8b83ef7c..f731e2e690 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -81,6 +81,8 @@ ext/java/nokogiri/internals/XalanDTMManagerPatch.java ext/java/nokogiri/internals/XmlDeclHandler.java ext/java/nokogiri/internals/XmlDomParserContext.java ext/java/nokogiri/internals/XmlSaxParser.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java ext/java/nokogiri/internals/c14n/AttrCompare.java ext/java/nokogiri/internals/c14n/C14nHelper.java ext/java/nokogiri/internals/c14n/CanonicalFilter.java @@ -108,7 +110,6 @@ ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java ext/java/nokogiri/internals/c14n/NodeFilter.java ext/java/nokogiri/internals/c14n/UtfHelpper.java ext/java/nokogiri/internals/c14n/XMLUtils.java -ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java ext/nokogiri/depend ext/nokogiri/extconf.rb ext/nokogiri/html_document.c diff --git a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java index 7b0d206c47..89cab511c9 100644 --- a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +++ b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java @@ -22,8 +22,9 @@ import javax.xml.transform.dom.DOMSource; import org.apache.xml.dtm.DTM; +import nokogiri.internals.dom2dtm.DOM2DTM; +import nokogiri.internals.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode; import org.apache.xml.dtm.DTMWSFilter; -import org.apache.xml.dtm.ref.dom2dtm.DOM2DTMExt; import org.apache.xml.res.XMLErrorResources; import org.apache.xml.res.XMLMessages; import org.w3c.dom.Node; @@ -80,6 +81,11 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage if (handle != DTM.NULL) { return handle; } + } else if (thisDTM instanceof DOM2DTM) { + int handle = ((DOM2DTM) thisDTM).getHandleOfNode(node); + if (handle != DTM.NULL) { + return handle; + } } } @@ -107,11 +113,12 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage for (; p != null; p = p.getParentNode()) root = p; // DOM2DTM dtm = (DOM2DTM) getDTM(new DOMSource(root), false, null); - DOM2DTMExt dtm = getDTMExt(new DOMSource(root), false, null/*, true, true*/); + DOM2DTM dtm = getDTM(new DOMSource(root), false, null/*, true, true*/); int handle; - if (node instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode) { + if (node instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode + || node instanceof DOM2DTMdefaultNamespaceDeclarationNode) { // Can't return the same node since it's unique to a specific DTM, // but can return the equivalent node -- find the corresponding // Document Element, then ask it for the xml: namespace decl. @@ -153,12 +160,11 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage return handle; } - private DOM2DTMExt getDTMExt(DOMSource source, boolean unique, DTMWSFilter whiteSpaceFilter/*, boolean incremental, boolean doIndexing*/) { + private DOM2DTM getDTM(DOMSource source, boolean unique, DTMWSFilter whiteSpaceFilter/*, boolean incremental, boolean doIndexing*/) { int dtmPos = getFirstFreeDTMID(); int documentID = dtmPos << IDENT_DTM_NODE_BITS; - //DOM2DTM dtm = new DOM2DTM(this, source, documentID, whiteSpaceFilter, m_xsf, true); - DOM2DTMExt dtm = new DOM2DTMExt(this, source, documentID, whiteSpaceFilter, m_xsf, true); + DOM2DTM dtm = new DOM2DTM(this, source, documentID, whiteSpaceFilter, m_xsf, true); addDTM(dtm, dtmPos, 0); return dtm; diff --git a/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java b/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java similarity index 99% rename from ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java rename to ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java index 526f2ac3a0..7c2b08da24 100644 --- a/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java +++ b/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java @@ -15,10 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: DOM2DTM.java 478671 2006-11-23 21:00:31Z minchau $ - */ -package org.apache.xml.dtm.ref.dom2dtm; +package nokogiri.internals.dom2dtm; import javax.xml.transform.SourceLocator; import javax.xml.transform.dom.DOMSource; @@ -30,7 +27,6 @@ import org.apache.xml.dtm.ref.DTMManagerDefault; import org.apache.xml.dtm.ref.ExpandedNameTable; import org.apache.xml.dtm.ref.IncrementalSAXSource; -//import org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode; import org.apache.xml.res.XMLErrorResources; import org.apache.xml.res.XMLMessages; import org.apache.xml.utils.FastStringBuffer; @@ -62,7 +58,7 @@ * mutation. If you alter the DOM after wrapping DOM2DTM around it, * all bets are off. * */ -public class DOM2DTMExt extends DTMDefaultBaseIterators +public class DOM2DTM extends DTMDefaultBaseIterators { // static final boolean JJK_DEBUG=false; // static final boolean JJK_NEWCODE=true; @@ -114,7 +110,7 @@ public class DOM2DTMExt extends DTMDefaultBaseIterators * @param doIndexing true if the caller considers it worth it to use * indexing schemes. */ - public DOM2DTMExt(DTMManager mgr, DOMSource domSource, + public DOM2DTM(DTMManager mgr, DOMSource domSource, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing) diff --git a/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java b/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java new file mode 100644 index 0000000000..42a91c52bd --- /dev/null +++ b/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java @@ -0,0 +1,685 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * $Id: DOM2DTMdefaultNamespaceDeclarationNode.java,v 1.2.4.1 2005/09/15 08:15:11 suresh_emailid Exp $ + */ + +// This is copied directly out of the original +// com.sun.org.apache.xml.internal.dtm.ref.dom2dtm path to allow modifying +// DOM2DTM and working around package private constructors. Other than the +// package declaration, this class is unmodified + +package nokogiri.internals.dom2dtm; + +import org.apache.xml.dtm.DTMException; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.TypeInfo; +import org.w3c.dom.UserDataHandler; +import org.w3c.dom.DOMException; + +/** This is a kluge to let us shove a declaration for xml: into the + * DOM2DTM model. Basically, it creates a proxy node in DOM space to + * carry the additional information. This is _NOT_ a full DOM + * implementation, and shouldn't be one since it sits alongside the + * DOM rather than becoming part of the DOM model. + * + * (This used to be an internal class within DOM2DTM. Moved out because + * I need to perform an instanceof operation on it to support a temporary + * workaround in DTMManagerDefault.) + * + * %REVIEW% What if the DOM2DTM was built around a DocumentFragment and + * there isn't a single root element? I think this fails that case... + * + * %REVIEW% An alternative solution would be to create the node _only_ + * in DTM space, but given how DOM2DTM is currently written I think + * this is simplest. + * */ +public class DOM2DTMdefaultNamespaceDeclarationNode implements Attr,TypeInfo +{ + final String NOT_SUPPORTED_ERR="Unsupported operation on pseudonode"; + + Element pseudoparent; + String prefix,uri,nodename; + int handle; + DOM2DTMdefaultNamespaceDeclarationNode(Element pseudoparent,String prefix,String uri,int handle) + { + this.pseudoparent=pseudoparent; + this.prefix=prefix; + this.uri=uri; + this.handle=handle; + this.nodename="xmlns:"+prefix; + } + public String getNodeName() {return nodename;} + public String getName() {return nodename;} + public String getNamespaceURI() {return "http://www.w3.org/2000/xmlns/";} + public String getPrefix() {return prefix;} + public String getLocalName() {return prefix;} + public String getNodeValue() {return uri;} + public String getValue() {return uri;} + public Element getOwnerElement() {return pseudoparent;} + + public boolean isSupported(String feature, String version) {return false;} + public boolean hasChildNodes() {return false;} + public boolean hasAttributes() {return false;} + public Node getParentNode() {return null;} + public Node getFirstChild() {return null;} + public Node getLastChild() {return null;} + public Node getPreviousSibling() {return null;} + public Node getNextSibling() {return null;} + public boolean getSpecified() {return false;} + public void normalize() {return;} + public NodeList getChildNodes() {return null;} + public NamedNodeMap getAttributes() {return null;} + public short getNodeType() {return Node.ATTRIBUTE_NODE;} + public void setNodeValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public void setValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public void setPrefix(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node insertBefore(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node replaceChild(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node appendChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node removeChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Document getOwnerDocument() {return pseudoparent.getOwnerDocument();} + public Node cloneNode(boolean deep) {throw new DTMException(NOT_SUPPORTED_ERR);} + + /** Non-DOM method, part of the temporary kluge + * %REVIEW% This would be a pruning problem, but since it will always be + * added to the root element and we prune on elements, we shouldn't have + * to worry. + */ + public int getHandleOfNode() + { + return handle; + } + + //RAMESH: PENDING=> Add proper implementation for the below DOM L3 additions + + /** + * @see org.w3c.dom.TypeInfo#getTypeName() + */ + public String getTypeName() {return null; } + + /** + * @see org.w3c.dom.TypeInfo#getTypeNamespace() + */ + public String getTypeNamespace() { return null;} + + /** + * @see or.gw3c.dom.TypeInfo#isDerivedFrom(String,String,int) + */ + public boolean isDerivedFrom( String ns, String localName, int derivationMethod ) { + return false; + } + + public TypeInfo getSchemaTypeInfo() { return this; } + + public boolean isId( ) { return false; } + + /** + * Associate an object to a key on this node. The object can later be + * retrieved from this node by calling getUserData with the + * same key. + * @param key The key to associate the object to. + * @param data The object to associate to the given key, or + * null to remove any existing association to that key. + * @param handler The handler to associate to that key, or + * null. + * @return Returns the DOMObject previously associated to + * the given key on this node, or null if there was none. + * @since DOM Level 3 + */ + public Object setUserData(String key, + Object data, + UserDataHandler handler) { + return getOwnerDocument().setUserData( key, data, handler); + } + + /** + * Retrieves the object associated to a key on a this node. The object + * must first have been set to this node by calling + * setUserData with the same key. + * @param key The key the object is associated to. + * @return Returns the DOMObject associated to the given key + * on this node, or null if there was none. + * @since DOM Level 3 + */ + public Object getUserData(String key) { + return getOwnerDocument().getUserData( key); + } + + /** + * This method returns a specialized object which implements the + * specialized APIs of the specified feature and version. The + * specialized object may also be obtained by using binding-specific + * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations. + * @param feature The name of the feature requested (case-insensitive). + * @param version This is the version number of the feature to test. If + * the version is null or the empty string, supporting + * any version of the feature will cause the method to return an + * object that supports at least one version of the feature. + * @return Returns an object which implements the specialized APIs of + * the specified feature and version, if any, or null if + * there is no object which implements interfaces associated with that + * feature. If the DOMObject returned by this method + * implements the Node interface, it must delegate to the + * primary core Node and not return results inconsistent + * with the primary core Node such as attributes, + * childNodes, etc. + * @since DOM Level 3 + */ + public Object getFeature(String feature, String version) { + // we don't have any alternate node, either this node does the job + // or we don't have anything that does + return isSupported(feature, version) ? this : null; + } + + /** + * Tests whether two nodes are equal. + *
This method tests for equality of nodes, not sameness (i.e., + * whether the two nodes are references to the same object) which can be + * tested with Node.isSameNode. All nodes that are the same + * will also be equal, though the reverse may not be true. + *
Two nodes are equal if and only if the following conditions are + * satisfied: The two nodes are of the same type.The following string + * attributes are equal: nodeName, localName, + * namespaceURI, prefix, nodeValue + * , baseURI. This is: they are both null, or + * they have the same length and are character for character identical. + * The attributes NamedNodeMaps are equal. + * This is: they are both null, or they have the same + * length and for each node that exists in one map there is a node that + * exists in the other map and is equal, although not necessarily at the + * same index.The childNodes NodeLists are + * equal. This is: they are both null, or they have the + * same length and contain equal nodes at the same index. This is true + * for Attr nodes as for any other type of node. Note that + * normalization can affect equality; to avoid this, nodes should be + * normalized before being compared. + *
For two DocumentType nodes to be equal, the following + * conditions must also be satisfied: The following string attributes + * are equal: publicId, systemId, + * internalSubset.The entities + * NamedNodeMaps are equal.The notations + * NamedNodeMaps are equal. + *
On the other hand, the following do not affect equality: the + * ownerDocument attribute, the specified + * attribute for Attr nodes, the + * isWhitespaceInElementContent attribute for + * Text nodes, as well as any user data or event listeners + * registered on the nodes. + * @param arg The node to compare equality with. + * @param deep If true, recursively compare the subtrees; if + * false, compare only the nodes themselves (and its + * attributes, if it is an Element). + * @return If the nodes, and possibly subtrees are equal, + * true otherwise false. + * @since DOM Level 3 + */ + public boolean isEqualNode(Node arg) { + if (arg == this) { + return true; + } + if (arg.getNodeType() != getNodeType()) { + return false; + } + // in theory nodeName can't be null but better be careful + // who knows what other implementations may be doing?... + if (getNodeName() == null) { + if (arg.getNodeName() != null) { + return false; + } + } + else if (!getNodeName().equals(arg.getNodeName())) { + return false; + } + + if (getLocalName() == null) { + if (arg.getLocalName() != null) { + return false; + } + } + else if (!getLocalName().equals(arg.getLocalName())) { + return false; + } + + if (getNamespaceURI() == null) { + if (arg.getNamespaceURI() != null) { + return false; + } + } + else if (!getNamespaceURI().equals(arg.getNamespaceURI())) { + return false; + } + + if (getPrefix() == null) { + if (arg.getPrefix() != null) { + return false; + } + } + else if (!getPrefix().equals(arg.getPrefix())) { + return false; + } + + if (getNodeValue() == null) { + if (arg.getNodeValue() != null) { + return false; + } + } + else if (!getNodeValue().equals(arg.getNodeValue())) { + return false; + } + /* + if (getBaseURI() == null) { + if (((NodeImpl) arg).getBaseURI() != null) { + return false; + } + } + else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) { + return false; + } +*/ + + return true; + } + + /** + * DOM Level 3 - Experimental: + * Look up the namespace URI associated to the given prefix, starting from this node. + * Use lookupNamespaceURI(null) to lookup the default namespace + * + * @param namespaceURI + * @return th URI for the namespace + * @since DOM Level 3 + */ + public String lookupNamespaceURI(String specifiedPrefix) { + short type = this.getNodeType(); + switch (type) { + case Node.ELEMENT_NODE : { + + String namespace = this.getNamespaceURI(); + String prefix = this.getPrefix(); + if (namespace !=null) { + // REVISIT: is it possible that prefix is empty string? + if (specifiedPrefix== null && prefix==specifiedPrefix) { + // looking for default namespace + return namespace; + } else if (prefix != null && prefix.equals(specifiedPrefix)) { + // non default namespace + return namespace; + } + } + if (this.hasAttributes()) { + NamedNodeMap map = this.getAttributes(); + int length = map.getLength(); + for (int i=0;inamespaceURI is the + * default namespace or not. + * @param namespaceURI The namespace URI to look for. + * @return true if the specified namespaceURI + * is the default namespace, false otherwise. + * @since DOM Level 3 + */ + public boolean isDefaultNamespace(String namespaceURI){ + /* + // REVISIT: remove casts when DOM L3 becomes REC. + short type = this.getNodeType(); + switch (type) { + case Node.ELEMENT_NODE: { + String namespace = this.getNamespaceURI(); + String prefix = this.getPrefix(); + + // REVISIT: is it possible that prefix is empty string? + if (prefix == null || prefix.length() == 0) { + if (namespaceURI == null) { + return (namespace == namespaceURI); + } + return namespaceURI.equals(namespace); + } + if (this.hasAttributes()) { + ElementImpl elem = (ElementImpl)this; + NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns"); + if (attr != null) { + String value = attr.getNodeValue(); + if (namespaceURI == null) { + return (namespace == value); + } + return namespaceURI.equals(value); + } + } + + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.isDefaultNamespace(namespaceURI); + } + return false; + } + case Node.DOCUMENT_NODE:{ + return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI); + } + + case Node.ENTITY_NODE : + case Node.NOTATION_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.DOCUMENT_TYPE_NODE: + // type is unknown + return false; + case Node.ATTRIBUTE_NODE:{ + if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) { + return ownerNode.isDefaultNamespace(namespaceURI); + + } + return false; + } + default:{ + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.isDefaultNamespace(namespaceURI); + } + return false; + } + + } +*/ + return false; + + + } + + /** + * + * DOM Level 3 - Experimental: + * Look up the prefix associated to the given namespace URI, starting from this node. + * + * @param namespaceURI + * @return the prefix for the namespace + */ + public String lookupPrefix(String namespaceURI){ + + // REVISIT: When Namespaces 1.1 comes out this may not be true + // Prefix can't be bound to null namespace + if (namespaceURI == null) { + return null; + } + + short type = this.getNodeType(); + + switch (type) { +/* + case Node.ELEMENT_NODE: { + + String namespace = this.getNamespaceURI(); // to flip out children + return lookupNamespacePrefix(namespaceURI, (ElementImpl)this); + } + + case Node.DOCUMENT_NODE:{ + return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI); + } +*/ + case Node.ENTITY_NODE : + case Node.NOTATION_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.DOCUMENT_TYPE_NODE: + // type is unknown + return null; + case Node.ATTRIBUTE_NODE:{ + if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { + return getOwnerElement().lookupPrefix(namespaceURI); + + } + return null; + } + default:{ +/* + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.lookupPrefix(namespaceURI); + } +*/ + return null; + } + } + } + + /** + * Returns whether this node is the same node as the given one. + *
This method provides a way to determine whether two + * Node references returned by the implementation reference + * the same object. When two Node references are references + * to the same object, even if through a proxy, the references may be + * used completely interchangably, such that all attributes have the + * same values and calling the same DOM method on either reference + * always has exactly the same effect. + * @param other The node to test against. + * @return Returns true if the nodes are the same, + * false otherwise. + * @since DOM Level 3 + */ + public boolean isSameNode(Node other) { + // we do not use any wrapper so the answer is obvious + return this == other; + } + + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be null, setting it has no effect. + * When set, any possible children this node may have are removed and + * replaced by a single Text node containing the string + * this attribute is set to. On getting, no serialization is performed, + * the returned string does not contain any markup. No whitespace + * normalization is performed, the returned string does not contain the + * element content whitespaces . Similarly, on setting, no parsing is + * performed either, the input string is taken as pure textual content. + *
The string returned is made of the text content of this node + * depending on its type, as defined below: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Node typeContent
+ * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes
ATTRIBUTE_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE + * nodeValue
DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE + * null
+ * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a DOMString variable on the implementation + * platform. + * @since DOM Level 3 + */ + public void setTextContent(String textContent) + throws DOMException { + setNodeValue(textContent); + } + + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be null, setting it has no effect. + * When set, any possible children this node may have are removed and + * replaced by a single Text node containing the string + * this attribute is set to. On getting, no serialization is performed, + * the returned string does not contain any markup. No whitespace + * normalization is performed, the returned string does not contain the + * element content whitespaces . Similarly, on setting, no parsing is + * performed either, the input string is taken as pure textual content. + *
The string returned is made of the text content of this node + * depending on its type, as defined below: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Node typeContent
+ * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes
ATTRIBUTE_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE + * nodeValue
DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE + * null
+ * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a DOMString variable on the implementation + * platform. + * @since DOM Level 3 + */ + public String getTextContent() throws DOMException { + return getNodeValue(); // overriden in some subclasses + } + + /** + * Compares a node with this node with regard to their position in the + * document. + * @param other The node to compare against this node. + * @return Returns how the given node is positioned relatively to this + * node. + * @since DOM Level 3 + */ + public short compareDocumentPosition(Node other) throws DOMException { + return 0; + } + + /** + * The absolute base URI of this node or null if undefined. + * This value is computed according to . However, when the + * Document supports the feature "HTML" , the base URI is + * computed using first the value of the href attribute of the HTML BASE + * element if any, and the value of the documentURI + * attribute from the Document interface otherwise. + *
When the node is an Element, a Document + * or a a ProcessingInstruction, this attribute represents + * the properties [base URI] defined in . When the node is a + * Notation, an Entity, or an + * EntityReference, this attribute represents the + * properties [declaration base URI] in the . How will this be affected + * by resolution of relative namespace URIs issue?It's not.Should this + * only be on Document, Element, ProcessingInstruction, Entity, and + * Notation nodes, according to the infoset? If not, what is it equal to + * on other nodes? Null? An empty string? I think it should be the + * parent's.No.Should this be read-only and computed or and actual + * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and + * teleconference 30 May 2001).If the base HTML element is not yet + * attached to a document, does the insert change the Document.baseURI? + * Yes. (F2F 26 Sep 2001) + * @since DOM Level 3 + */ + public String getBaseURI() { + return null; + } +} From 2b0d504bbbd202838084aa61fb0fb3085b0c7904 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 3 Dec 2018 22:17:48 -0500 Subject: [PATCH 155/176] resolve merge conflict between dfc19d8 and PR #1760 --- ext/java/nokogiri/internals/XalanDTMManagerPatch.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java index 89cab511c9..f85675b0ee 100644 --- a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +++ b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java @@ -76,12 +76,7 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage // Have each DTM cache last DOM node search? for(int i = 0; i < m_dtms.length; i++) { DTM thisDTM = m_dtms[i]; - if (thisDTM instanceof DOM2DTMExt) { - int handle = ((DOM2DTMExt) thisDTM).getHandleOfNode(node); - if (handle != DTM.NULL) { - return handle; - } - } else if (thisDTM instanceof DOM2DTM) { + if (thisDTM instanceof DOM2DTM) { int handle = ((DOM2DTM) thisDTM).getHandleOfNode(node); if (handle != DTM.NULL) { return handle; From 44ab23a7111dca29fae835fc33586b66079bfea1 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 3 Dec 2018 22:50:19 -0500 Subject: [PATCH 156/176] update CHANGELOG related to #1759 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a731acf977..cffc90942e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * [MRI] Decrease large memory usage when making nested XPath queries. [#1749] * [JRuby] Fix failing tests on JRuby 9.2.x * [JRuby] Fix default namespaces in nodes reparented into a different document [#1774] +* [JRuby] Fix support for Java 9. [#1759] (Thanks, @Taywee!) ## Dependencies From 2ecd40e755a8fca5baa4fea5eb08dbf63f002565 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 4 Dec 2018 09:45:53 -0500 Subject: [PATCH 157/176] bump xerces to 2.12.0 --- lib/xercesImpl.jar | Bin 1367760 -> 1386397 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/xercesImpl.jar b/lib/xercesImpl.jar index 0aaa990f3ecadf60d28b5395dc87bbe49da0cdd7..b69d01dac3753830955e945e6e96e06fca567a8c 100644 GIT binary patch delta 382689 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

ard~H}VW+V3 z-e1x;LAZ;(7&iBBv_Ur{UVs4BUN+gG80}@$Zkq2*SOH4APS(F67N5^) zZaQHfJs@D+GxX+HO~ZrIx7e`nv_iY1E8eKHN)+RbV z;BAXx-{}N5YQx9s6~y3Dl5<5VGK2@bOV5zDD8zLv`TJK98>Cl{3$M!1m`uo@9;t}8 zLIpn-M|xTFZCN)0j2i&j(#%wbr(_{Deu#YSEzDjOSJwIa-Wqk#sH4$8;gin$h=q|vp%S!D ze`k87AiQORO(0qEwMgE$gwSlFnTiP`zXnFT1|RkkoBKARj-(H~Q*Rkr3f$b_EZKPX z^{PgBS5jgNY>+_K-9vBnYFygBDP7fqi+_Gg9FEH@naHHgZ28t0?x4VlmfvWW&Ey%c zyk>~zw)iS!MqGhrnFx*MXPj-GHD~gNR=i=!q=LHiNEr|Tck>%_Nyqn^(uV81`ph2& zzw{nOt^wn0s&h#<`nnps z`r%}tZ9=sVMDoI}bVg7F_G94ut5HOzG?B}e5O6^lhkpYAX9b1okOYzrC5l{%wxQ;6c0lh~aM0$c}{A{7hoZ6~xp%<*r78Kw6uz@s&r?M0%ZV(uze( z>cU7>I*WN-&Hx2+(^?{z4wQt?)F1cip6qoHYh#RF*aWNTxc8TmMn_v$9x9`8MtF1u zz^rjc)eV`UqnYab+3#1DZU(sV`QGA@aL}dcwUfBOsRv8fhS~yHEqSx9_=Tb9z%^PmoZ^D!N>`jAR-hjJvlo2VbosPJm)6) zCc8Gmtq0~pJG0vIn}vr!yO}Y0BMRe6opJb5?>9>i+O@#?v1=EH$LDG;W+%i{HG6z^ z?)1#@ivQBqN_G3&$;y6rL1krQducT&Ew*2Xb16&BSadfu(pYYk1paIybvK7KWG>B? zr>>b86^+*17I{F2!`k?5HXk-3eTe>e2GN|mmK%-5F$q%p&M~JFVf$2?Uh8`%J3NNd z-}Q37Lf9Uq`$>%}h1ydovCAH+r-!f2CUJ<);XFhu4;|7hTat_hdy-Iyw4|0m{KJBk zX~lQTsrzev%>e;$x~@h7q)ysxqn4j7@K)Ys8co&|TtF~a`reL*?WFu!Pt1&H#(U?f z!yJ9((jcVbaoDLhqU@JnmBqL7d*Att!Z4Cg_pG6v*bj<%d6Z}roHQ)J+!6cEq}a5&`aLMb@Qu?W8+=y&DNIrIstGfgL|lRi2q&e?ogNi zQ0rz!_ZNb5_93CTOIA_sxpvs$L2ICBbmB$~C~ilvpJSOFt*ZBq1}7Ibg#&rW+ELt$ zk_tPCXo9{VBQi}ks+Sf-yi2viNUJV0zAyEPNRj@v0QwITj&+1uo+hx{7pT6XIO{@t)7&2)Q82^J&N<#z`Nha=IOGHY_=NHKIK=o{S|~C#{9_R3_J-|;J5$PPmHPx z4uXRvVIn%wc$*IZy&-QD%9-1m$6_t@%Ix**bt5I@&u=?i1XJgB}U?%0>-yy1Tu{y3Y zC>-*ei4o+lId<5$gIx8Y}84$^vO!DQ&1=Dc^}HXNtu z3$+ouqQYF*&1Yu(xrsqU8kr^}nvz}tIO1%$;W>&`tAbg&We%=d zTi!KT;;c_L5lYjh0Vu^huk<2t@)O{t%F!tuyeKLcTuiNiAwfilMJZJ1f^L*^OUk; z?3xgCYKIMU3_^nS;BfU-_a(%L-tady#w$BpHm!!2N8}2aN!k(v!@v*Aa)A_w*bzJ1 zSqfGks#R9LW`x_(-yZVbXTl+dc=iaPIemer;E7(ks3HY5*6yPk@~w!%Ed5fF{6oWr zjeK95eaGqrsc)NQFrGzqrzlm?X(HKxL5Rg}z@31lvuj~8h!5rkbcF+THPV^P?Zo}H=hgtf4bZ$tg>ny+!2&2#z%l1w_{}>e@+J8rLu-!PE=J>_+f$%7^ zi7Bt>qDmcfxaFnz6?yU|1zDRR$xBYh`T%HHFn}xn@gf{GjGul>g;}>lwol5aqldoL zD=7wF&d({_E4}XrMaNRl4@^AEz8{qF$DM*QFz%8R;-yHb{aYVa%&wq}aBhO|CAsu$ zI9FhSRzh$>MD~4hWGEtJpT6)`tgoXrPR3epzVj#qeHqp;eLvVH9L7X6#UWYBHALbPq_mG2^zHw5!`$VH~S(Je4uIS?Ph z+Gnx?T17_yZ=Cmkg3NkDdrV27p-lz@=Pc>&sCN`AG3UbQjta^`~<;n;)j83-NdMCU9Q6y3pfsTkp#o>S%E!R<3{!(rrC@zAK zC07O}4fn~arkH1PE`(Mq?Qb2~<94CzTlWSfQx_DyZqfc$T4oZlX$vH=KE1?=iT4DN zYd0JDbo~03hpIXr;+S}#F6kyCU6A z{wkbAUYg)&IR0Bk@AW-&D}f)BXoi6<0y}I488nh;>KQTkq5@5o6Q(_h`htL2*{G7d zze6AYwOC8PWLX``Fs9}M#{XUXK?0@$Jao_H9pooKn&1hxU_kFa{}Tb^5DU8hr4p>c zfxZBs|0@b<6<+5jK9-E$aNuqC$8+at9B5o{WepG$a*PL^^+Jyzga$mndkKjpftH4T z()8DdTMT@B710?9Oi_aLq=^8ot9`sPz#)f@hJAWL6Pld}AN}z(SLx+I*trgf1)||# zHMci)bCXtSSC)8mWV>Ul(I zQ_$r;3oMa)cIBIxR6yUhaK1W4v;YxJ7KrnH*Ukuc79k{O zP3WT2O^MFN9qeNBs^RcAIWpVGjE3$98}%8-pJ;lpO-)s2Cu^&mpvS{fsD35vXI=o zPuYC)Wxt{(3!e(0n%Y9XQ+#3*btTb1*ElQ3-kpkwE0n24=!M1CQ3CYODD+gf~nD8@w_kS{l9 zLV_KReI483=Y79~t57%QLEC>EZvY+py$2CZKO9H{q~3}xZj+L3ENs&s6#hE8)gTR! zA-*>ZG4Wcl_cDnvnZ2v!zTv69kHZ%Y+_b$A;)DLX(SOiSUiRxv);*Brj*AC0vn@$_ zFP}p0?YyvQ{r%kd2H`Fx{Gky4Aw46q>cRS=o@5$6A9LQ6k9d-h3Um<2Brq(%TIMo6 zEf*IPPIT>_+y4G+rd8)KJOckhVm%~5yz7E04&PT-h^^oq4NpDk`pD1|88k84@eRw#%<~^US(!;}DwcwpQg+IO52J4mA7uN4X zwd)sWvSlgc9TLH|7f03=$yTz>E#XH=X;WCTGH!6AYn!gx2ujVe{9)FHAHPcks1XAsFD$1N4a#B-{z8F&e|;Ci={}#oH8Kw1>wdHQ>+79pvp{eh zb;4Cew)f57c|UaGA5_bKgn3LZ8XCR%6S9UW< z`3>n0tT?f+`w5pW^TNu7U*wds!c~s$I@a<8!zT90) zFex{U?iK#rUnDzYv(FC^+&8{$|JhcOxVFp{dqX80m!+O7R(n}%eFujzvBhTF@fl_A zc5eRUXAkK3j`r&{=6$XD70=4t%{W;GO#6t@+3d~hIC5z120zpO4$W6sdP`}@^!W5U z*}O1ZU(M^C3+ady>H6i~`Z#>Kqdly#se*%N3c{TqFdx-qPuC}k^$3F#1i?=*nmU&U zR~zUrEzhD(G`E&JzW(dFUb>yU75>(eo4~Hte&`frcG?((+d^5KqhwpCm!ShbFT7A+&(O-&GER)<*b<`dYR;bTcJL55*yoW)g+<==@hTvrCDBk_F*YZI=<~s{uzYjeHS_ypIJtZCck~>l6O9B8 zJVsHl6>{dnICOE7mbjC873R^MWs|dsiA`{Cf!|5cuZL%StelO6gPQUa&9Rk?>NP)7 z8$!x?*5#OKT)*P6I_lMzv=x_kT^f4-uy$YhEi2D~B>i5S22XAhj!vGQ4ep>UNfUn< z)If8cJ=9>jHdLQM?x6qnw8YE9_E@z$Up_(uChb+b9|$p(#O%86`y{81EkO7ST@Rx1TjwuESNGC!{t&|6}{ z?>&>>Y)iis$H)B`+7}50vNdt*ghR0vE`G zxQ0JPeEw0`T1KYPAf;1@++Fz{={v|mM{;b{UA2dG)RUsv_4e1PN?E+=x$_$<+s0B{HZE+wbc-AmIx}-0 zeOTxhD~q#fDtth1Dd|I+xOgM8I>V$om62`g<*X31@IGIDg7=Sn(!%_dU1mhvThWia zInrhmTE-_o+p~5omR*G>)l+-k?e(t_D$?{LCI9K6b&c8iS&&fzRuG+Mt5(a* zA;b)61)$YU2g>NeR(+krC60^$^#=|*Q`XhL!3+T?1!^sgzQIt0*LJN$ZAJWws*CnM zLw3KMp80TXeL-$!CNRb{4q#`BRuQN4UFl<&nKu=FAFv|{|IC8@~?--g{l+u*m^8f~5><{W)813SybX@i zpskoneK%vJ88>qFJJXBJf@QTykkf^j>N(y`Rqw-y3D-^jO@95(n&J|taCptWM{9o| z>+;)+?h6c_dz}!_fEYIgl67Q4FE#uF@qIvGZA#fu&w?2x*M(3e8^RStKvy1=QIY?r zT)*io*_lbuZ8DZG%bBQ;mK(+~kR^Ot?j0~*pOLUnDb#2B5Si^7RV{Ie_#oXG-adRB zO^rc@LMw#JSQ4iIget|6+aVRpJ;1QdHDK+MLpe099N-67>b=$tVY=8I)P->j%|>+z zCMb;pqP1e2@x3Ls=Ns_ScfpR9Rs3*Z(Ic5}t@0M71pBKd(B_-Q01bDb;m$1{3rbY{`Yu8k`00%Q#r>K|`WMRdfEFUIW z)>o|KbWd8AeZ|hRCa@};akR&h5zl8yf*yDr9l2sr5b$a0<7Z)j&g{~&_^lAw{^v)m8 zmCWMWv8NX*u&vi&A+^g^@eT|w_ux9y)~UrE+3zoaGRp5bf5z~bRZ|8(7S`O+^BQt~ zx#Hco^}1;GKi)Q*Y5s z$%@;m5+SZUP=5UJfHO!~0hw7%W|8So9D;aVpSAi<6HDpCr{*XdFL9ysAUGc-2P5Xt zElq@E(2nPRA?G>GSM#G_%)uVChJ76u2llqSdp)=CW$_xbqUDcKli{s~h6PbfXfC*I z=nQkPuMT;3^s9JWuQ{`W6O6D?Ok2nmLyy&wCo4qX8G#6P1iuq6T|rP?V6IytiP2nA zT30ah3$|J2{nE1x%G=_~T8-9Uw>Xzlo?&|ugLcSvenDkJ?x?@|)VF@d{1x+=aOY|V zCHx4_AW8a4Uq9>XA)8IPfuv4dmKW3){k(N}^Mrj^q-9Ku=m_@Y1Fk@{wDD}M9NXT$ zMNACf;2Nw?GwDuJ#|oKgdh~3S=DFHs1|=E35LyylnvcZ9;y_CHGHq9+@L6eBOHGNX zF-XIxnlcZYOO^PW-LZUAfupIB`8d)0cE9A)Bt>*a%xqV@%mR|*-%zYXx~IPl`CLZb)CEmg|!wF{VkF97^+Jn zv_Dmp82_|S?L9jnFv7!A85b&4sLxByjt9MJ?qq1Vthsf}sGpY1iP2(h)iY+r=mgpk ze#AvW+8}NXwslr`^x6o zjs}y3|BtD64v%DM|A%*H<4la**iJS!Hnwfsb~4F^8{4+6jcwbuZTxbcbKdLw{!`a| zRd-c&Rrkzv&HVx5sHvs4fX70bN+aTlmdayI1^(0~6^^^+a`rV8zj|GiD@H?!S)Uqf zz^o}7NGK-7Ij{1Y^T^Q-n0P;oUuR0-K$yYH_8#97wQN}rol&h{YaNc%9!OeJ+ozf^ zW05OZja{WksCeY;yfOd3ZIBjef#o@F4nwDf%h z!h*rpf251AGvv$3x5F6HTj$sy5(uM3jsnmXD5`7@CjMw%4MoU22V;&NHEg?jPoyAz zc<{R*@{r=#vnW$u*y{d?^wcJMy$BJemV=>|;#o9QE_TcoHjVjv9jmchyr_2X^tkA^ zK5DlJ<82KEHcZK48?dGAihfFMkzoYv0;(P`!g*u=J1co*h5-AnI+&IKoVze!%uv&%oq;!Nz#{nSl#cy z&>AHc?}70a56+gD6PgEgY}g=yq5ZLH<>H^Jw)hsYY?_(D19ZE$6X<0Kq%W1NaT$9N zGC#^p{%*L?X%e`4QLgd{>)2o+1MfKfLCg%9%CM*kBBb3oS8#8c{FWUCDI45@k`(Et zPy@>fC;8^ta2$kh{)lrNsH3Rz1%58;kj%Hbp~-Sx2`@eYtJ`r!g3*ARdv+} z7nj5+6_PIsA^fblM!{VNJLze%D!Z9OKf=KG0^loLFl7)XgE!Gv$$l!}eI0#AgGD415qlh55B6LS>!q}gHK?bo|74s%(ifK<`_?tBlL z_*PPBM-34a$^ujepeoHb^JC4ci=bL$y__fn$r~= zcolAni2DSKN@&(8Q&IpQl;zt|gBgt-X1GijJk&?PxItcXq&dpN`TLJiv?6G=tq)$U zowIDq>+W5Vkzs{prWLz*9E6jxQKOPs1}xK;UXIr2zhf@J0|qG0Ip4-i+3Wojq)<62 zkGs&f1y`0cf7z)Sa`Uz)%>z*o>!8-;FzGAn<>9SGo5?lW1Y4J-*VeBe7rWLTwXF@k z*Ud)9{Snf$X5o7pPtLqvfM)Maipr7cq=2ekyNR`P^Xiemi9IF++xNrR z{5Mw-kR6&s%lc`ECpo2Cd!?x;Y?NSi+kad4X#551xp z4foUrRRx_ihjSJrP4ZXBpSqZbByvo%!<4Rl%h30)g+nY|Nh16&01)JgeO^tsTKzN4 zG`fS+JU0`6P_t~BN00<^_28Zs--}sPqgRgFlSGC{8CP=v6<_eifU0?26-N#}26FsxBfi6T?A`h85V# zXdzSol*a{jpeZV$KMcC=gxgAgl_E@s%WZxd5^xJogJ$_Uu6OdIlZz!V{Y$-U&>MId zJ^aD;V=LdzGvCh5*6-7#H-GlSM9M{%$w;M3_7HD7!c3`2>H`hkKb}7WjIRG;D{t2N zdrJ}yd?)aBuSl4XyVXE?(zM|5tCHr?ARylAo+Mpplz0`o&4mYfJ|Cslc?$0(&0KI@ zvVS!T=fhr+#PDL2z81xO zk&WMN8~6DG(X|FNf}ef33!B{U=$WCWEWN9Qmne}|7H5y``ns{K$?%O=5?p2VSq z;~^b5c4lDmQ00L7$l)G$SL2oz@#~JA1q7bGGGIOmdGMlEe!PI>7sUyihCIJp;+|HD zd*H;_md67cOCvcT+60&0cZnNa{eukum=2jdaDh5=HCUC&O#T=!SHYCJ>2g;iTvlJt z&_UIMP61)ztx~_gU}}4K=@GI#bj#ZtiuNfZ7RA_yfoY-|%SBmJyPU5a#=50`x+&@} z;mk0A+i}vzT_oya54n)U&`q2dXKsdTPqz~gG(QxkmSsbujdi}9a z_gk-aZt+P)(AT1mfO)>(V8g0=T-@S;BJk&h@q#fL;0L83znzf~t43toZ)+C#hhD=k zD@yXeuJ(i=7mxp%vA`Vs98cC@bXiqqX*0AEn|wlRunr(Mv(ny@r5l4(g+g=8jQh*C z`+_qLirM^%u3WM~Iu$31MSfv$Ruo*Md?FWj8z$=@#!8iUkncq;4p0pF7B;>FnfaNBN;l!`L^hF@g;-p z4cXHGUV-%uVc6h?*X{7z{d_!EnSxgP&ZT93r^A)6f`6i`EBH0$%Q>(`9%qkIv9EOK z=t(NoaRxB^Xn`GuuIXWkuI%mj8vMf16?d$OKz+uR(oKS|kmg}f#<_(w1 zi1ICJbV^tML%15Ne*HzA#5JDKDL|SyJAUYfxrvucS zF?}pw(yrTKU?YB2=8&{K|6aW`R)C3FCXAEjXbC52!*U47OHd6uldf&B?+|!Q1C7^X zG}I?@cgn@j9rDG&nOB>^At;@QHfjItn;gLv=6`kfi)#tQ#VohMimLt#S>(SWR|6Lg zCopplT&d0(e%jpfm|3+)zHH=zxfR9q&TGINc2;q zI&E8 zWUnL14QOe|vnmg^p@#L+PM;NvB9@x#Rf;@(VCIzl7-s3LaaIEY(GL9gDKW%-4O4QG z7#}O+>-e`*Xvci(V=lKi*L_TU;zYCwd$5HOXE^RG4#XJzMiuYPP^z|Y zk<()kwot8@zp8Qh%mpt8*t<58K>}ol#qr=ZKcD^5r;_K885{HCR)D)sk`#pTi|-P+ zlBow-^R^CrsW~+ud`!~}11bNGzIh^BJY-5$JahXkKW;a-PBuy4rc=i9dhR!hKl}Lz z({h=ec8Tv%-ow1WzrgTpbpMi6M#a*LRr{{U(3SR>rb>XLV~~RLolYv3OI9x>Czt;7 ztI6geDU`Km&%D}?fs&SIqnr(@8MypWmX-9DgI4=e!*U<7QJvUE4C?v7y4@~qQrSf8 zQPh*q&DS*ntD*DtUinZT8qviv)e#mFtEKTj>rnJLHu;NnRX}nm_$iSXz!S}j5PgR$ z=*CG;wM0=G_$Mg>&$4&F+FF=Y<#gd&i8C*$#>I%DQg&zE7ZP3=QHYli;LCGF4}9Da zYe}&e_)(WZTdpW z?j}f{+elr0)rO&h$?>tC=bi=mHWxd7SPnCPDi(JD8)D{dKrg~GNc`Hs^MG_fcH1TO z%elEp3b$c*BuIXlBpRErO=G|4dJ=b{+NH`B)VNEAai1|!+xHFQeg^oGOw3viJP^hI zYl_g3Tso4#z4hXgE^Ppagat`6UqGBJ_NME6iCHW$WP|IwYM<72zms_JTvfVmSKOrd zmJN!h^#J`!ZKINUyNifaF?m}@v&}zZI-rAm*Rxb-2ie<_QIR$Vtb=)V+DxAcVj5xG zd}V-;dBbH0Sf^CCtr<$Ee0@COk*QlCctWK2JekQ&I^_?Iwd@S|{%u1KND+ms^v~aw zr5~$@mD3g;P>mv6qzu)#;tIa3x4d|7Adjpv#meeDcbJ(Y%&+~}d?gDKq{KBQama8} zgGdbQ_S9+Q0&nlB#Tzg|+?=RGjfG3hevKc8AduY)^*}{EoAckH>O~~B`#R#MYyxN7 zt7`cc2X4L^yC&p9YQs&4;=yX3QiJahJg;==7V8|Hwm~Pa5f%V zj_#C#U~}h7@?ODL2a>hN2GK@~#Lk81*@VLL;Jk6M`JAz>CUEb=RrPW0gD3rHxpZ@0 z;$z9>`Zj*ei_kRe6@fcBOy$l?`@reZ3DVN8j-)yHTKA-VY2Ofk9Z5p_jIByBtj)r- z3dNcnTq$@AZCBW=Yu+0W=!R4sQsV<`vloQ-)nU#J!|p{0K-mptQH?A)Hg%T^c7%3O%aU#|zUuQVq2T zkyhU>vd>$h1fyIWAMfVlVauGUZVUpKbIjrl`sVn3 zHT@g$sqeY3hl3CHJ?}%;8w}J3G{7G*V`>9(K(B2X*1$)Jox&jShSE^q-jntbyysX+ z+Z?+CA!IhU>U+fZFv>~+OT+uMVC^5F#>HFH+HAhH(R3BxrFTsYc9iB?P(UMUY|!yD zG$mZdIg5}e?pubd3x0PbZJAKU=1s5Yq8W zSm?R7Daj?A^l}}6hzW%JOjmxV3^fXhla$|Pcq-$HCKiX4hx2)ezQxX15};3dWS4zF z?Oj7*6v;A4#@PUNy@b0_DM8*;5Xkc~L6Ya5<2ae8c$7gCMthwRtcT6b{y$KV z96%rNKN9BO=QU!8PiT*KBK-;?M&f4mC%six5r7ExKj06v7JPc>CuFDz>|cuLWE23H zm{o%UmMC8HNe9hR1;qc?BfADb;M>3B_-F&Z|5ux;3jqEXmg)n<|6_JO82~W;qjRDg z1JM7gr85Ea{rI~aM~P1jkk47cC;F~`&iQ|nI%z~fZtP72 z@c(zYFew0m|3bMm059Nw4fkxb>M}kXn*G~Q_b&=C5&rLI!?_GV(SOh@-)un1e{>t# zT)@$PA$C5%0_|VGR%kPz5fbhnYRlF0C1!?j1p z!n*g7(UWM`hggJeJ))ySD8orPBz+TIP=nN$M@ z>5qVR@+}Ioge{49+s%=^N09Xzxw<|cFB=J=xoR>I1@f|^y4AawKlNt>$#XJyctT~6|0bt%aZ<;84xCt3Y2@9e4 zs3^rOEWaP~iHV6N1K)mN-jyN43dy$eAw3xD87$Z;Witecc_o`vq$U?&xgLm!(_4F- z^d*sXHftz(6?M!Z7Bl%r_iz#>teK&c_S&U?47SbNpUF&WTGxk0g?I3>Bk}x;!Euz68B%B-A;ngeygqWKP;hv$Mj*`IaAy zI=Wai0*Oa0RzfU6DOT<4JGjyJT6;RGqn}zO$f3k2K@^3pEiM)&GFY{Al(@Kh~Mj^mhsTSxCWvC#a z-XX!x0#dY>gt6UURq6CQy^3~68nuRDF(?9|i!jEF2U4-H$jHc8C9Rh`M@N5zIo>-? znXxe}Vn7Er1TCw3@JCBHwyvE8cN6}?UGB=Du%DXU*Bcd zHqf9iegK7+-8ol!xT*R2X+~pW(JT2eIyy@M%5hLIBQis-a2;`1RHMU>%p)4e5w}3= z$lE}_=9rBtjpOq&Y_)A72A;6U!ABa8C#P5G{tNov9=cL@KO7MqzeOsd-y$F*L8REJ z-wzUxeqq11WfH7wMABR~tx0eka{2@BT~T5{hlkEY~T{$lP4d z^8Hs1kVJ8YvkoU@w@t>X5Wkrw+mK;P(b>bC5TiDVI(?@mnkzPD7!Gdcj{k&js4uS`b~2RQmPEU$wk~rv+9i`|I5HiO+p|%Gt;aN5V%)p8vDP(N zxrNmt^;ZYv9}aaJLFgL|Mw;8Gh}wMM6c@!zj(u)Gg}BL5WYO%60_H*ew<4jT%>u0QwrLuHBO3e<=j>+XI*|c|{r&NE%dwRDwMw zD>TTI-` zb0oB!EX!5PTH0#?uFz2L9AS0{6cQ{O1MLAMexA7mHPU1{8nJ~SbgIXeeaus%CTPej z*za)f2w5YWHa>8#lXs7=4cK{B^@Rk`Ge!FI>alZ%C&G~dQlQx-0DD}cE45{YeuMUH zbol5!fPTr0N5IjDUC|NZXAgS-O*=Map{+{2W}BcZl0?r!wPlvLItWdP^>v{t?fKC` zRj6?8N#Si$q>!pec<>rMTkSTjo1+w*DpklzOz|hybD^Bd{-1iNR+kJe51dkn;mYj_ zs;XqeQY+igX3*N3`j6u7!;h|4xOE2W%jb_P2y6E(t)4Z&VyugOxb;cfANMoBtYhlO z+xWLQqUUt9U8+nDKH>IG~KLA4;n;82F6yV2-%ac!&^t z^y*?vCU3+ojJB`_U&{d+Tnaz*y=sf*u`i}@e!;0#PS>M$liFdXCQp&BFBq z&TKh1ow2u41$iV7oHYfy#2yU@b&CrB z_p29FyMrQh%*`E&IIUaG*u7rx3PiyL0tfdXNSD~*8T;Rkqztib3T&%|J1UBPR+^@U zqbj{{vCqcBgW%V9Sh^HE?(aJsag<(pnf+&@5a+vm7VvS?e-oo4MnVU{b-Op?5ow24 z8pB919UG7p$PMWz+2C>8fx{KtMo&+l-Q-156N1*Xquw*wr$rXEm8#~=u%H-7LSp&?%VDKLqYHW3-V~c%Aqa$H2*cm9s4xl ze31i+hhUFXL1QkL7qsC52ivAzbpFufR_GTvlnlbs5i@W331g2XNnWfQBNrJca(| z%`(|c6JQW%r^hhPchl4C(twVk#5zC@iM96&p@nUy0n)T#$U(TFUX!4NX+zF9d@ z%fPBqBK&?>R$tf(8xlBP4{;!#K0{1O1o{a>>Yo=)U&L6aUxh(&4!L43BL_~ey+8HK zln=zCZHM8@7_hIeko z#}R8KOY}rK8bpLRhkU9`l3x-N6cs($`j zbcc=pj*?|gs`hYhvtLoTiKm&qxO`UT(SdQ`L z_Fkz$A(5jF0=u>)W{0mNCP&;}gh5)2iB9uR;xAbQS^83Ah>iO-Y{?Bj=O7$XnMnY^ zN7Zc@E#y*+Tjyzx)aUCh8tXmk_vY$x4Az8?Ac#MKC84n}H7QdEsYyNj zY=)7$gg^FJ)z?>HVuy*`TNV^(#iS|Kg9yh7ZSx&xMJVo$Pfvi!_RzYy7mn#PTQBL} zI&Z1PwCPV^su^fe!p9|cDTZl9q$fB%d^y?JcV%nSM2p-O_*H_=^mxqpI>4}?iYhr{8guHG>Rj|$_51sxH5dOT z1Vrd?7x&bH2+Z0yB{heSCly&9rpi0mN#?ssj9=fdy+Ku1@ud5By z{CCnzdk6`tK@sG(YE!0FPSkTEpl($e?R<;F7wGwZ{YmX`-Dz>SqU=O~4{+Ey^P=+_m2J zT{1|y1NuPhvzPaxiik6JyLy|0xTB_jO`R1Ds#<@gVx34!lZy1$p9`p43y!!%8k03c zVHBV9OseRSW{=7Ylsw3)C)Q*tDL`olc4ReHXx(XG*I{b$>!)PfBLDbKD7&W zPIIcc0+P7qt>H``4Ra!c`KxFQRLT}7#zi7Gd7KPpQRBtRa-a3Y7@bj*^0|?gmNrkG zTE7A*y2o{y+x_uNjQF9x(c0h+>%2Ah(sY&)-b{oF*`Ro`9W>`1a3 zW5?E)szv7DeQ>#(=4rONwanq~#2;tHn(g>+{@9hj)YJ^gP9fBfZm3QMtxdvul?}I*+4nbB z+Gb^kcEH*nWB$7%_WVF<*YF0#cA1sTH1R}g1+qqhnv`*4oAi{~^15bp_42x9(((9} zjBWO``NMH;jIb$w^zzN(&RI2~eNrg4{6|XyCK1l?!l`6ZZSjbVUP6Bl`xAfYI5}Zdg1+NLpuDi{lvckf4 zQeL&j>9`wq5ln>p9hQKkXm)rY7!Ugm!;m0i4%j1{QM(IEz9+8L!A!`2DDeNfLFMTl~_dUd#tQ+WVJx*#L*j0+O2AG z@}+Kk0~tEGIo&F{!U1X^=P#jF82O7nV(<4?{CW(tYhIU|T~3g+S|Y*7X5qyW8 z9@}l4_ov}IpQYBke&_Q<&yZbuS>lFy@fki3m~o0XvepB;+c3aWTngH(gW1U1k}%8=8R7zo)n0V> zz`Rrq^Y8#?`*3BqlscaB^8wVG7VASH(5W$03uj1{9+8OyDBMez7P8}#YVG#5! zVqbx{+@TJp+GsCN{R$rUL!g zY!Pjx`T=&Jsvu~{Co&oeI%|DM>sl{esj!=5|?e^jH!CDFz-wp*8P-!`T=1+BD_-o{^n6(?`vWbWwrr7?9R~R{3FRv+ zhB7dBpecJD)H3h-`Z}I|rgS0cKAzDa1kxQoM3?&g6bxpG?uD|y4FKt@@MPW+OCem2 z#s6Ibo6%Y2m%GIRWA4WUahE4=6a_jbV3V{85?@3i(KUui2My@aEoMPWk0Ddrn9D z(b4Nu+|qiAGckv1W%kAbE5$^){;NfzJlP1GoDN=Dw2Q`;Do+ov+y#p<2=EhoCPB6C zaT>21-)YuWm)UyuG4n!P2$DSMX=-1q^G2xHuu$(nSP-FnT$Ag%7>Dt8QMznt`MvQn z@<`(g^4R>=|E%o~ngshmR4qEm+i)t5*lt8Pr-~hb#QR@C`x#}D|5H$Z77vL-JAROo zC!gcY6x^BEzNyVTJ2df_tK<0*#NFOpg0DUio>O(am;82NfF`cfgWLMMfL0Lzz{kVh?^SN)^<|R#M44B4&O> zf0;_aAN$&z`Y?QtVWwzVNn)HI|D_#5X5N?Hy!ND9`g0p{Vq0>~Zdq~CU6o(q&wT9S z>JGoicxg#8S~=rs9l`kuI>M&&lo5A1{erb%ePX8CJTO1MzHgut6cJl>noK$H>d+IE zxJAIAkA-8uay1L?B$NK6rJBxMrc;jKiJznkXY}ygfV3&)Y1K=Z%jyqSpNmQ?0vjNR zlmPj=P*;fP@b*ebQN?B>{oB2YFfO@@4CDH3cQfnTIyPzt0*FQrBvFMgM=I-v3i%sH zs7bVA5n;buz1ZLl@x5O(GMs_izKpPJ+UC8{Ves1JlE{wpo+HC$=YjUscc61$`xWy04tG`wQT{{k?1KIh0`w{Ss?trpz#`h>@#2RL6SxnZ&H-ZtSx*g7W3qDNc zm#_uo8h4t)tXRH5&~|+q_lLNTtmnfbQlE@vn!f>6kJ}QSJs7`qWqj@W=Jj%~;9XN0 zS=Nw+7y3N<*Jv(Eot53?p)J_mik=hV=W~p9EZ(ne@Lj3BL|Jq4G#ewYO!_Nr<1u;K zkop=HqQ~{_R*^C2Tpw9trYV8wl>(b==VtmDq=0Z9kmI`&LG%U#QFIz$h$89~ zH-L!UNjpY3He!Jb4rjd}s%Isv#BADk4EeC{$lyQ+pZCiG%}mwkN{&vAP~nn2%x|!} zhR+$~09)}SL>@iXkT5SqOaw$sTNAOrUZAsm8v#uC+5^#ZM_i&u5H6u?!G`XJq*fzP zREer$bl++~3Osm--aQZBn()#g$gIl^5aFD;Vcs_}RM(s!ex7#s>iD0-C1j=(tbk8S8U{g9D}Bx zo?;M*u2$L>NI$tlZhxlPRi+UP8Zi@eaT8b!GQ$P6nafs*gctZ}MRp}I7zhTB>{L7?J2Go#m!8cv#|ZNsSrIs4 zR@^m%ntS1&yOoIFNKb%$8DhEw@R9r~II-=--L@oa8Wi1ua9m`UYK(!(wOi7Aa>vNT znxAEk#!I<-TnRvoCQ`man96)PA2LTBJ^z#9?9?t-GQ2r!HXkDIVDqX<#BDAQw zWCtL8&lO~PP{)FtRKoVfXGv%&#aae2lz_BSPY*2>C0LXU-Wgv7mE-%6XM~^y_&n6Y za^4jllX>+eWWQKSBoB{-T#SHyFbC^PYu5z8Qs3WBL`vNp?52RC`qAXD`FFpVbnf-N zyWG&LBD2AcX^{{B7TI;goK8z}5xZ~ez~2^^ot;+Z32(FfvapuMJ7Fr};*sSqEkP2A zDik>Pl&?&<8^VLGw?JJbeyiJY-L;-FXP9TY?Cgu?X1c!tSYIBHx;^&h5>QmD>`Hbd zIQ-8KV^ZZMXgfpY;~9%cLJCpH!{f(N9Kj!zsm&~?yyfj>KEjgs>HqHIP0w3{d{AZm z&uZslbY{NP0zZ@_+WnlVND8GWo&%a_MeiQ;v_*BSU_?e~~Fj!EZ*lPKuWo*&l` zvFJ~z8tP5RS@unkh1=9!-U_8g@5%D^vwB05_q=OoYnWH-Wlrc6`mRtZfa^+EP8%83 zOA~Us7Q)0&|Cj6iD{c5rW#`1+73&mq@q~BzD$t^(mqsND+LJHjuYZ#aYzM+`I$8-o z&*}ue^Af8l`Zau36|7#%Fawb4U)h&b;92Dj2l$54G>|}L@`SP*5e*($Vy@3V-qJ2_ z75!%%x2T@p<88-}KW8Eg)!cZOH`3xv%)6TdZYLW4=}EQ#&2Gjj)ze^-?<$+8$ZUQj zX*y25m4O$`?2_A|Lge%#SXAcD6offt_7;A#`Q2Pt31Df=5v#rE{-- z{2oZ?hqRd=OzZPJY7lFC9o(yI2CJJL$3yoOWWXn#N}?61=En|t+-z79ffiS@^|Ftq ztH7()^3Fw0B6@F&Nswu*rR94+VXH>r<%Sd9gZ1-Bk{-QX1306=wEeEB+7wAIE6Fyd z+lDjfMb314(S?U@3^Xp*Jb~l3DJIH8fY7Ft+FT##o?jpl3|I*qbYO|9DiGZ(rmx`MV6#tjHHai7Sd`E%1t=aMx+3ex}dwM zE=(=fTKnVMXc_|jLU{b$<>=ST|KERW|I58wKz`HtPpfzw_$~Hd6^=pW1!L>a%xpiz zKkCici9GF}`Qvo>Z?6AkW-*YzrTu$m3rw)v&ZnPLAlko@4^i!(s_fWP@SuT&Ix4pv zfd&DVq%7nhj&?&+yB^Z7X@c*+p5>z6531Jbs4*++54Hzpkv+lWXRk73h zY5K6!`VsRKw^{iQUX#$g8I*Uyiu2*2sH&5w?crn-FC7~_G?eIdWP_EG$7h5N@{ z3i`q^8+c)#jlIxhOJCun2clg+%iHH>SRe5_X>!Yi{j`ewz8;An`j`b9-=y3hz6uIX zMPMA0Lgpddi9(@-A8AtSr$M%MnmWW>_e_0rJBdu*7#|b)`;-(Gd2=p9H-&?I?wB22 z--PROwUXyg@jYU*$Y19A(HbK&=E`i{F4Er&<6$_-t}E1lfrn^^2ZT{uwwH#2u}Zu1 z^;3JGcJ$0)m21#>;$}r)bW0ESb5yy8ts91Rd;`9IXbc_4sr!MXshw5Np#a()s-K={ zGJ}tpHXqGlWF(#f-K<8QBLO&%4X|F15&jp~n;u+`Jgg!{ue|*TYKxJ?ud3ZLV5_M+ z)wYJj=}>uuS4p(dpkOjER1kFm8H>obp}Y)KHmA_a77LY$&Gz?n&Sx)9$hUT1ueEnv z9UYa*NVZ#SC~Tl>uJ2;73x0fXukbu9HBrNmB7VX$PH=(K*BA7S0xb>jUTxoH>K0s3 zrVU>85{D~6`Qr!$)-$+yx5urZtjs;xwt+h#njTz2D#LU!NOU$e(}aC1gO_0r3qhzG ziCa*!0lEyXW;^_kJAHrt6Rc}DA|XCLR`k{)}y_Bgq;-p zDbH9eD%)92fE=1PjzVsu-lEajz>Z635vR+Kkmnei*x6hVt7UsVy8N5Mfo#bBso(GU zM@vT8>V3^4s8w=2K6)43i;a6b6g)8Z6tl)Btc#FiMH0ecz+ z!QXKhy57vHx^k2xMhR)A@)GL`KE`F-!;TTA@tmgE9S*jT4lm5Vj2dMJY4=oi(`OP%k#Pt9bLkRlJM5Vw1E$7bph)6{vt3Ht9|%CX=?0z|hA=O8m;- zMf+(nrbF?_>@841KJTr-fo-gkhHgxsu`9@sAL-sNnI=`|4$lzCO8H3RUAXx`{SN0! z6dwQp@wn5a2j`K(oZ4QSzq~&dRcvCM=Dvmsiwg<&qF0uk@7u zl+#qXMCh$4&5H(!SSxk?x?)-~;-Emjk@dd;wY$MqpdJ#_v=t<1D@f3q9ckqm85I9+ zp-zp=u;t=ySn!OHg#x=@2aNE^_T7hRr)JsqhK_# z$~)Fa^ra5?M~_3^8SdxDvi<8A(UzN#&$R%QBzaC)s=c*kcg3cZD5-RggTN=&oU8vGmtRCi(Sb#=zs$pmI7%MAJ*Kog>ph0}Nw(Ng-ALeK~*X zv=G}rFhb<|$;6asasgDtpF}Lo{)m)w9L6b0be?Ysb|Q)$fJZ!9c{LMVVcNSCR_c!POyts$b7=D4Z&yXmO>MF`1^fx#7+ z*-0q)QSYB{)ZKpa45eOsE+KCc=)c%Q$FVYTsME$A9f~=!=%^|LB_l%Mg1k9lN3db? zYfj;ZpN?k9z_7_IYq`JU=_3~6u;beJ^3M$4E}S160AO+f0P zO;NW~r3nhTKsNRj<1-)f%Skqws`83sF6a1v`z`G)vBiN`UPxV?97FpfoQ%R5El+U$ zY>d|Xde44R_k5C82IV#s-uVP*0AfY$?+^aRUMdRV!~q5?(Jzg!{?lFRq~D$uNa`%APg>H?=$%uzVWWy_i|gUal%Hbdsp?_vb6VCzLtx0 zfzWPqIg!G5Zj}YNl?)bBKh@Ei7Vx8v8XVc_xA)Ya2dQ(l&CzKvL}wuQetWYl?=g$U zlA0~aO;1X_ons6J;kTq?G%*w%T8#5fS(aFR#VN5uAF&pQ<*UACqYT=Y-K)qDf~%Yz z?UwRT)JUcATRsw7WKNy5q#+Y5ojl!3hj-zwjVbdg5!5iQN>hKJ06i_Bk>+OX$OftJ zSIO6w-UFr293^waV~;0ofu+6lX*}O1ppoB0fa5G*F^r_>lN*z34+D7N6JBX@C4$GBhbQ*wMnlb&GM{{+2Y<^W9dvbW#r_~ zQ$R{vcLl=VNa)dTC1NmV2Fw^}w< zZFFqBUrq)xzYt&62UbwEEr3fusu6qUXi8n$ih$)@x zqYw~%7JrmxeFR@kb%;p^D*xlJJv&oqs4uQ=W=2+U+B-GNGf*9N6+=|I*n-AnEK(49 zp8or+-f)CkEmzl7UY$iL&Wy-n5ct=arg5<%l{jlj-{xm^?ApQ3ch${Ew1%Eqn6rX=#yKT$rd-NP%sQOOh(-^*p5DuXb*lomh| z<*w+CytTAW#gOXXRm&auV6|vZZOpgTSpdR%%tHvnuT6F67GksWG278mzRkb)Z$p~R zfeq#oK_e0dIJ4Ts>PU_)J}ZF|e`(L+Zddp6HDzD7uEdh}L0pxUBwf|7dTv{BezNz)2xt-BwPKaev&JU~ zNhg+XJ3W(%_kZ80Qsq)BN>IKE?6f{bI_!4(jhl7?ZrvFkcS=(6E5Tb~lXR8Z_WyD9 zl|gZB!MecU8r&hl-QC^Y-QC?`g1ZNIcXzko4#C|a5L^b${qCqX$Zd(fe%@2fo7#R~FT-7j zVn_)mF{50QmG+tn(aW4(US=1ELM-ee8->fH1aw<}1aOAW0w$;Kf}M|q56ZJ>ObszbmxfEu zEb*5Xce=eI6YLe>SAfC4Ta6~$(+)Rp#WkBZxy*fX?W&_b`6u^zHu&$cMb05%>=6aQ z*Ie(chz01Vx!QxIe65$#$>+Ijv6s?-vs~Wp0t+w`N$TE5v!V$t;L>aEH(RXuzN=Qiz`>bt-RPniGKed@Icd zK%`GZy*JS4o+J|!RQag6s>}Zfy{~LJzwb&=j$?bn^*e%ef1~IRhLFSccsRs(tU$(c zrli4DVpe4JJ8<8pKp#Xz>&F=e!ChoNW5s^rL|$x@JV?2?jQBO&pT&N6H>CQW+ln8C z3ikO>dGjEVvLaE`EjPl`K&%Sl5^hj~nF7bwv^ue2DTbY?HHeV8LyhnCPIdHi(~SZ(_hfNa1&JcU~sRlyu+FtDvJX$8igUQ+*51BZTebYP8Uq$j%h zm%sK|9vg?}Q1szK1z+b%h4}I$!G~Lo>R~cl=O*?z)_x3=;d5p!1U>ohl<$U8MwNeW zZc*dLxZ(ex%45yiN@&KfzMAjl-0|DlyqlhC>$sg=a|MHFzZjP1Qc_qIhK^_T3K~de z$-OPaP`o?Fg`Q>ciW|5?Gyoc1lLV*XbWcSYB;HhFvwKa4uiQXK_i4wqU2~XTft*;k z&98}qpKu9GuEB#*aQ%MnG6jF4aZ_(1QIJ4Cp7I*PW^oCQ{$L~a9{$lp?6tU#jdASZ z3cKnC5smg(ji9h7jQx+N5L%^bWdU`Az><`;Pa)?jh44B}L7}>0F;I@&_>sDyS*P)J zZh-YcbDdH8%RC1=fhyuKnFri7VJ9<&Qj&~U9UhKyY<(ttOfdwn$RB3*T8b%xV=TC% z`P}*92}?8$?4+rBv6c`ES?@x9JUA%;TKBw?3X-j|e5@2ztj>(Im5Xx8aB_o?8J7^9 zju`Wj6cg$aJ$9$tBG4m1{u?$ys^67uQ7g;31B*O+F54Os^-mr8B#StiYw-;vQBIwQ zh|Hw9T?bM#JROsAQQ3^*b{5k4ic*z{F9_4)4Pw~Fm82Ae9v7-%DME76h->@wQ@A9< z&Y?xD`yP4^q5Hqd@;;~Bow-e2%0UaKgLv}?ff`#%8~09`S3oAIicch<9|xtpzngzH z9NgB*5(X^;!UnsHwu4(0coetPN;Ca0?Be_$ol16ErOj2bBQ^fw%#1hX0qQdxR2%7J z*<5Th?k=ub=0D%@8mj72r3Tc((p7WrPFGtD#@N(jX20pOs|t5*R%$C#<#u;gcof%a zDA?yN+5P#k&;VQ#vwO4wRMVQ3Dk1zz@CpE`JYj0E6s4Rb`<3AltHqw_K!mo0w5KiM zcK+si!Bv$QTp!HT3sptXWp#bEt+4x}JZ{d;}Y1^5TV?W3Y zDT&1evTr@M^4e1@QmB_#{;aX;`9u0y^UmbPK^c!?kzD%^i^IW@de*pY*=$S zz#O;1H(;6h8;KKi4}|Gy3Nr&!pdl2A5>z1$niphLzk>yin3fSETOjy7!iCW_lL!38 zpn{L|U&)8XMfLAp>Xw&@ejb6+tq(YeflcXXpxER_!f%26hyjv%y97l}@EgXBvs{MCUKA%BJ>W zQVn(67ZysfCUGA#LcBJ3+aB((&S1knTftZ_r_O1uy4yaeXciV;bAU{OExS|a0HM0A zH(+)MnrKO2+I%vuH21&}fnJWB9iJzQx+1aDA%J%{O)M>g6TC+Bw$o-EHCBJ71dS5k zJ=Vbx`re)(-_apbAe6QqtZi3g(6OlQg=7;MWfpyqpHHPar8KI=pRTMzDABYUcH_!7l=dWl}xTsz^EpU4w|^ zGUb!@hRKvBk|FKH$qrt8mD+Kc@a|D|qWA+;ej6n zzZiPssYxw<)1Zcu7-C9zLTtxPLx3eo{K`5f>ER) zWvr5#?df&2!Ghq|{P~P-jJ55I6b?n|J5EN86m?=aGyEIE{}#Z1Y@5C^1JeE@k9DyC zhW=$}HDR_uWqsN<%@O`f>-y)_Ctv{mOIkY{;0pu}XWIlD00060);7Zd$ODIPO-Xa) z0^kADVvepyC0NzIf5VVCBBQmnwRL`yS5xB^;ZmA_#eeO7aH3nPDI?iK1(((Cuat%z z!$gnml`&jAope(vdRl~G^Fis+EW$tY$LopSp7!OmHbLI1RK{a{`Lac4wLQ#cy^qFI z8rebjyNK@IKCuks*E%@;YK?l!7ia-K&NGEP^n({ zX+yL;C-0$L7TIEwL$Q2U53Yco79ES1QxXs>py=shBv2SBzZxvNw=!+gA@LMQ^IJTa z0*`qPY%7*78^nL)DOJ>U+Wr-djr55kcJMoT=IUTMoY@T~iFss=Ta~`uVhC|Y2$5+Q zMW$F21q2C|)j%2@4}c4NJI$O2P!5Dbe`K@3bvie@r}<*fB)__E=5@HC`nAhE*nE4q zWr=WwV^F8&P8m6LR9G9ML&NigRnsb>Jj4eIg|p)OEnR7{8CRG z3l6<|vt*tQ3f7#6N8W>b*g!9sHKmJM_@wgTYIG zaLG2T_klsas8EbBIE>ix?s?>|uv%1hqf74tpEBb0l`)Ng8g z1V&7fGZX`3G+C%Zhf`{B&C);63l1|T_wkE;sQU)YQDY7hfu2ZwHVe)?U7&pij^dz@)WZcx2%9QI(hQ52A-p`-0z zyG7e4lm|CnD`1(eWY7)3ZKZdAdBb0F%kn}v7-o9x11G8N;$&gotW@!AmhM!>@xGe2 zZqSxs6~brb1M`<`X$S%y?{Ts4J!k1AKHsJ<%GaF({3F08k*{o!Fb z-g_qTm)35Ef26A-I>I;q&f!ff-v$ke7=5UL| zdZc&eHp|x?Kikm4LYx)Ql)}E+2rfCzirr>uMXC``&P+4I-7ekZksFm?)$M|Jrw@u= z*X$1u#Zu*J)rC|r4|zdtg#-MFTl+;YYpLdUA|OHSI4j#*CjJ9H$40a-D`vguk`2Jq zl2Fpjz*!!*j(>fa+hB)#;Z7<^P5b$f^1Ec(`@@eF&+JGnR>7IM{G?uK_X^t0BTUPR zroz0{9DQvMks(B}a{Ls{UE1(i)Fx{GkLKSriy5M6<(I3+BkG+`Y{*^n_rtN+CJOTyL8zgIwMEI`Kd*Q>yf4GK7RIFA^(%y^Vu7UvX}T4_ zQ0g~>Nv-gyP#~`I!%vMvXO$!3$L581^2r@(lxh+E#D*`R#RWrlc*B|d)}03ag8y&r z{AciPECOKtkG!2O1|a#5|K2MOsKES}G;XU42m}9zOMMrWHA?nrTTz;pZw#RSzqa&< zZ36nA7ygqnFRk)8TZeg{DQ zcNs7kkpACh_@RJ_e?bF}4%m&tpM;(!`hTAg`UgKb++V^0xWGvN1Fp!seMCxUG&Bfl zA!UMmAy{y29|bWp=~L;*X*9-#Cej3QP14pghqG>?x#_^s&69_%gOzmIkI zzE`@E!8?q=?y_0_lUmo=_E~RG-jiUlwNCoSeBG81`XpO)lK+q2D?U{8do<5uW8u`q z+QQtzqc1mi?ZA9#Vb!2oEVtNvTPXdunA$Qw!7ZUwzw9q+30H+*b$iR8rtfVxPKyc3 z$xbDnd!?1Mdo5qfNy=%g6y^?~mLQj)*df`Wa?scqt%Tq; zRH69g=N6&(Md#>)a;ZOltdr|dxnw5RSt28^djLEBWP8p4if_ZGr!a6ZxbZSX!>`E3Y3;rSa-J*snE zkXzqQw}Q4wPka3Ddj)(1t%DPFrghk8rnS2)*kzXBtpPVO!?og*8a)mxfzqsk+=)y@ zk};96)9^=suRG^}Y!%LqAI91`m<2Pcvx9^1;qTWR5BX^};FxEWLN z_=$E5riY8TrhEd@>rqxMDvnwyBg|Es%>_SV*Y1uwtIZ=(t02lGilW0?v>6j!2d=RwNgf^yxbdYX5&{_$a{U^b zyujAMaq)N-S$G~K(|x6!BD3hOwC0rCdP&LP)>o+wTxl|u(Itx*Q?0;^_!wS`$Z-zC z2hrl1M1#bc;spul$@@(c*Qp2!Bl#ABo$gw!sU>4?!)Bh;%zh6OXj|Q)w|VE}e0Q?c zsAGzHo}=3OSZd0`??sp(hW_@Qy@5~=3v{KHDyw)AsHpPb;4doEGgVIamdQ= z3vDcAQ6zx|y1cv`l`JR=2pdN@{rzi5vc#{-j5ksomc*!^x2Whd{JAVhWKHq=Uk{Os z63u8Tkw?<}+(sTWTgRk90!MKd9i91#$*p>=py+qRZc)N;;>F8!VZJ8U5!gKSGL}S6 z*G~p?GP}t$94VIOV%D=7OQ7mAf%SQD6#lw|fWT!bo-j(6?5$alfZ{q<%UDQ(0#Bw$ zYX2)J(Q8>dFrP7@Rob4-L4q^`2bju6G*0fPFKqaenaAJ=r(dZxT5NA#>n^RhjmDS6 z>PPXGilN7})20;Jp*1eEu;IX7WlkyjO|`2{P;Zn{TC56nQp#njx&d}t6)4kIKRbyn zGrx}1b23ct){4cQuVO}Zj&nE5hWmOI5Ju~=o$+l(chV+3+g?PAbz7xxe-yF^X#eN+1s0X;};{hReP4jJ%25R zqn64V-46=*zD5y?SOpyrh2zoXF?n;Yp8+&su1Fo~77Tf97n!Bpyu-RDT^&z}JwbyL zM4BKwVv}?USI4$=7EImd140?bNp{tmY}`muz_m?}x^NwpyJ?U)%VC$>J*l}!Q=-+Y zbkt&%5at|kY3EqOy}-TAac|R-j*2qt8t3!KfPjp6WV$O&oleeG|79_W?%0hS#0oP2%<2&X%!IZf(RBEp0{` z#}Kifi1e?{dRRS-8gaRSl-r=#`n?IwQh7K@UeP~V=@;9S!z;6#aT}2sS|y%@^9xSW z0w1`gKfDoNoCLeV2aMZ6;%3|j$ebKk*A2aXEjnxw@*+_AsjUL@lkA*z2gM~Vnz$~Guw`m zthEtMbMM?MW5&9EoZOtL(G*N5@Ak)k9j{JC|T)Ws&NWhX)O_8H8uvL(cF~-!!gcg4Fq10mytIT^dX|5%wXC0__yzt1#&y#iL zDVb@B24TC1jGA5R5_}={w4&o=Fx~!vnJgbZ38&Cyo2I@%tNYkg@aJPfygY=S5-q|5 zl!nDgX9g`Q4wN-71kSRW*6%*g@}0O=GnEWDKs0Rg(-?2+TKhSF6Xm zsax}3i2aq%LvFqbJv}7688@sf3F7Lre)dt(c4V16>=UP zL%-oMBxgX9+7!d>4l(b=P)qq%TDKp_#^OsfEV!D5AbI!d!zN!8cdWeT7xtFv{uqLF z)fv@Lo2o*e(70!GIwPS@?`#HgGGOKpRxEJduwk>kt@52_-|B7Bq^@zR;jvu7Bd_4( z;%Bv90m6ImpH}+H>!HMsT<8@&$O3yDYKNXYbZBX-0 zXe}=!CTYSw{{&2ZgC;cZjaag>G5mwq7i-Iq(ITU@+o`WV^%c9>4OtMsm~eH8`pRxE zxL9G+3LDSni*vn_#s)z?EftGU+8p?TL{&>hy%D=5ro#FjR7oKyV%^;lFONU>z&n%T zCi*4wxOcElTS{c>guc;DR_jpZSy!d)#RD*bFQ-p{dzcqf;&*8V&@A8{J1W6rq}Bd* z#c+>jgJvnJM{^-hS#JycyZ&hVMr1Wj6$!yMuUf{Ia!D60n)gA(#uip03{hJ3HxOr^0MSaL1(dT8Sjm;7n5 zI(6zFyqPXL#vkyf`)v^>?i^~$s4MZY;lD4}HDM-USC%ZCX9(>J&MZ0z24@H5E7NA! zqM}!wE54(RF(c=?JcxR;{;Y(WC$-&pIJjMg$d#(?| zGDAAB>^7~xR+SjFZc*y?WLlIn4SvGuuy+ujY1kK{PpjZcIG5N)mvp*<4ciDSU?)+A zTrk|J&sSoKPU}cBcy;PzwU{jfH}}09hO`HzyOe1{n1ovjmcze=ztK0dIr3@OsAaW$ zu|VLSNiE0XE6{R^jjiz#9Ezwo);kSRZ#yE%Z|RjM3vRNW&R^_BRz$8+Z4yOzP?7pm z6)DQl|v>9rk;{D0A}@%lFekzq4%vIIx0;xG*eN z!?VK`iOHosNE42~)M%zv82sH#vVmFAFYUgB`DsUx?nJK}Zwb>{MZ zU#Ddqw!@j5{tDk_oj<Jf`^H(dXodpb5k#Io9`NleDD!?I9cm6MrIouEjb1fepv{lI>XjQ zw(zHAX#Im}NHm&HVfGq~q&;+Y?O6aCx;9Rx>O%+9?t4>KF(hjck(Gf_H{iu8JX5RM&bOrs#z95xdh<{QNoq z{`l-#hj5E?$C9ygKFys%6jh+zrPcUjWm)-QGJ1d?V%Ux65U4L0vJx?qd*V})sJZ@7 zt_-Ce)y;BFvzO3~xly@4knF6$rR)A8tok~VI=f*$>c*0Wyp-sQU*LgWtBhIqjnNaS zJ^OXKUS_?Py!+nbs8q(iccC%J9O?{uk(~R($Tw0v$~jt9QWJ5jQR8`wG)KSl%VaU_ zI@*KF)8lbWFL0uyF|RarYDqCghmq6);u=ZIt(LBR*pmjzT6~RIV5!2C-SS5q>tgAQ zZvlGe?}@TX?0|}7VX##MSB>GwI{&|tjY)9dHIY}^f})CS7}4mFr#i%-*@wEgAvsJN zJ1SoY$Cg`up^LGz81}4_T+_;E=~ISx!SV^Bmf z_KjMOt5V?nOB6oU?)S1wPC75N0(y3~SUZchoou3AlQ8uJy^7qv9SfxcSaaue_yY(2 zKkt~Em8TaR=Ggw2uh+kE4b>SxgO_fzUcQoT7pENNi8Tj&4nk)kcYb>DwoiG%c%|NG z@4_GC>;h>Hng(2Bh*4^pYlHD)vUXKtP6iNSum?C<10X<=F?o;yEC*%Z^Cm#nyJf5a z&>*Z4+WuKHKV*=0jAvlpv==9cJLc(o-XzF-_k=Y7926R32pPb9koMhhLM!)R61NZH zO=hGHqA&Btw!hB&jpzCtw-5YHVx%o-=O<`-7r24b2lb{g;t1&LnKs-W0C`;V;`Sl< z!5nx7?+k%@cAuC71VIWTo`F{uekdS7j3BJQG|1rEKSmI;H}3|pi^3Z4jxw#IYtobgY97UyWk|qbvGOrNc09ZVh9P0yh$4{H139fQy)1A>Kg%_?>aI8 zKPW)DF|z<*){STXjyVAYF#g8i`Uy9DK+xz-^g15r3h+1mM)+D0Cq4)`;Ux${9XSaG zj(|>f4Viku-egCxgMh;z=UqeAUf4JM5$s^#Bna*L3Wpf%Z|+UWt{_t{;+y11ct6m@ zj~g@_QwR1p^al0X5O;I{XzE7}x&p?K?gE*J0Dtihs6acoqy2veR>A&K9ynhEnFSC( z97p~FJ`6|xLJCfJwQ$Jc9TXXvWP{}mctLCqaX}dja={tkF+Bvm;vihJl;%M{vG(G1 zXWy{zf{&~OX)^V~cPBYRcSkkA5t(H})mdZ%&h7kd`$gpf5W7>yR{~d9w}D_p7B8a% z__&HeoXqdjyQm|&{kj<+7+&}X=lzx}y+qwP&P3h8vEe@QytqXIi`+5FJ64>gzgT(F zm~Y`it?FjSP@3bJ_j4XuCHxkl+zMtRG&{@X|L$YG$KIm6fO?ca)D3!2I?4b(7&5j*{^=4*V}cME->Q$e!olf`|%>Mp2`>_!-1dI;OW?SbB)@ z+ZA(s9%o$Dz}RkGyg>EHubc9$ptR1XWlX01-uE= zAUzOt>Td+)z34O__}AX?IGX*nw%?-XXLH#WZR39#`?Ky+(e%;WI)JOMG{_6XQ!}!B zitG<+ZoMJ0Pwv(3k-Vq>-Q!;WBy7K-79UW`-6FQ*pg_OmnXcONqJ6BE*SnaF_Of=& zzmDr4x4^Apou;-jT1#UacVVEciPKpXMp{L5E5o3x6%vo$X%tHL|GI+ie! zN62U{Fz7BY(jCD+HidQm?9#LZ$E*idcqFLvj#Us6sPb~vdN5UZFqL>XwX6@Y+rX?; z66%$CIQ6Ux6Wt-4S@5ISaQ4q$&ZqKNO6dr{z-{w`g18DIf&X8_(eaIPZ|_rX(iyx> zIuk(l@7ONQIScUi4?0EUV{6d$vw^4rk>(r^j+6FJPp)np9Vx9O8!!$2>1mz=sQV{V zm?kDe_!HVV0-rYU_-`hB8uSD@Mw>-0Ko;tsoH%N8WDJB)Cs>@cy<>R7G{XsWqPCYJ z01?7J%d~GJ2*1$4!17rC$E)|BWvDc%IsiIwNgK`!eF>}g$s(!w3LBqWW(9Q@TXBF+q`8)A?uHYuBR-YNi0`c)$mE>R?9vgHJIm{ahXT?WA2Xi z4b;9!x85)MO@_maH2345!~01LE8jL{yWD?v<~%IT-Z)4U2yXP}wOwNSHtJH={{52^ z!Nlf7V_mh5SHO6#b)S~r!7fssQ*XSMgrq~$>;6_JWfyYz? z0%@!@-3&PUbX5WvJiXmKUs4V*v%M+k>kyYl2i+5)+uAX)*wmm&n!mziE!vp6kA{VIBuzr8q>+POp&+Bc;3vFAilTxv6;&p5SJ8jBb_CCV{9m>`-GS z1`#iuaZX$*#LYR&$~~Gxf0KIM-5J~95)1fin1A0uf0I(%U2ma`tzU@gdWEixTyGhpZbE2K6ie&X`j2z%K)1(0^9ut4Y@BSO;apc*KTFF zYM))dn_+vmx||2AijkgLyVY(@VDfPXhLG9UVtkC*R3dFETTQ^k+kP7M;-YJ3%%6La z*2YFeJrEC9w9QKu+cC1u9e9IW3B)exEsK6qo`vyxR`NT0s#X zXE)rx*YtYEW88_Lmn{Msv&LFRr z^hj-VhB56OB@E6?bV?jXYN%qvinP_6fLmmiSBFgwx{P%=4HX~tN5i5GsiMb)l(H`~ zNKl@pxU2~^V$JR(;d|6LlURgOg?^c4?@ zO?`O@@Ik`cnjc`j|rrcz%|la;r=9a;nFvJ#%EDj)RcVXGsP&UN|A1s}5?Ycvy4wiIV{KM+}tc56ZE+9r0e!2C}shsSJ^*;-+ z5*4FKpOeSaDJ6e>wy+AOZeEje*-;NgovvTm<#rRwGo=?l;1GB%m#bq0t{S-Jz6^?G z^qRqOMKys7-hk~*$)je|szz%i`Pq0+2S&j%$B)^{ciAQ>()9K#;HWlNQD9U=frsj+ zfSv8)@T+~F76p19We*2h_$l$E6IV0PM%m>;~;w%aBTI$OgQeI1n%_julI!-6gn9I2OV11Rwl(n zQCrhmZ>C)bb8V-|uruX@{5@+^Zs%4>VFL$NR(PMrCE#?mr0{HD==79+g3%1$>~c^| zxn#&*VPI#;HSe~{Gp_3(m8oMORgT&*4UKR9#Fmu#wqLqoKK*)FCZRc$cdiA8)bBsi zKK$ivp*3MG{NPJ(ja;@t9*nDL@f)`Vi@F;li0x0`^!-a12u@*S2%yf7F|6Y_mVrcL z_Qpj$&Oi?MV-HF&DERL;0%|)el$a+2#n_ZBU#E_|=NJV}@!OZjjDWG_j^*eA+ zl*W@pA=ckb{t7h%6>%gJeNkhCPhVIZdGQG>B}IV|zq+jkI68c(E-$@sb%u=EzjAHE zOpB~~8zL-5!~5CWc?CU$GK2Ee!O~3FHdkgIp@D<~_5Nbrrv5=EL2v&1n@|WccDGL{ zr*WanV?W;B)t+CI-;_(=01Jn&2XtGK}lzDSDZZoNY_mL_^w8hHja_lcF%*T-x{TVB> z;@zw_hZpy)MEhfn^XJT>IbJN0WrlVCLJB9{n$;QW@}L~Z0r4~wC=ctSknP^Tt4I5u zA8ZmosE+sTM}zr>v0JbFF+?O3Ye0eg@jTF(0}ML8!4Emdv<7seTi{C|Zl@d;F}>RF zGoaSLPR~i#YF+yy6D3q5flZVal72cIC;PjxbT(4(08R6x^}0GzA5*Pokba2{@Q((y z54AD3KrAIYM{En0B1r{bt?FHS?kxzCRj|<7doy7sIbA-WXgC>N^){{IHZA#$LKXNS zZGEfxMNvT`Cm`y`ZGXJN?95vK&deN7QK2o6Z)kr!gGNzf&8sof%Oy4P?m~f2+w|s; zfCW?M#3b7NMrh&|@^q;|8_Hl{c;_ zq*U2w)-{wj4i`?ea8!~-(5zIbbr1z`x|L4EhM3zX(Qu-wJG5GNf3DY5sP)RrA8k;l zTrsH@v(u-vm8h0XQ~Xtkrujqt>{)SpMez(|JK9O6_-jx&;s2ZTv->1D0R)(x1><%H zper90uvPNe0iGkoQzX?tb?b{J4#ZLfGr00j#Zo9gh3w6hkIoR)yrBbTJrq-XoFSCO zMJo>n2`g?1l#jeaX&Aq%8-zIf1@u6Q^eli2rGzqFH%?DzlBqw2Eqk0DaM!~*_u-x3 zd|y$k>_+b6Oj4s>it+~b1IIU3v(`28%%;QZcj>c0ZS>3Crs#he8jktdzhCL@IoX9? z!hGtmFbACa;tp*2txBPukiO=|+fN84PBifO$xIYH;G&JreSu*)x#QZvmgrN;xFdh- zZA?FaWX*ZcF)KB#y0%5`L)Y+=zwVVT#pZL>c)gX`+gg|tV|6750b7{f>E<?R%TP zy*81p^3S~>Ao>Oeqy^GF+p@HEhgHSC$GV*RB7WWc%iuZ*)j^JFhL3l#*pEB}74}BD zt(>*{I>|NW^s!iaZMcA`Z1tW`^VTN62b9{2FC8S@qPd7@62|ihVkM8rrp;c5@c*{; zlaM8f;fI8>8+o3#KTs;7^r9-XS2c82KPmb|cvAj)3;IxCR%XDn?Zyr+&lgr;Ht~83 zcejhsUN8QND!Kcxqf|714Y1hnWK4up8++kn@cXy~7RU)YD$sLVJY2A&ZjhF_?^ja< zJtQp>WqaT=459xD`XCTp#Cmp5pAOd+B__XX{qoY2>~AEW3fzk^<=>YOxJsUVb+N?1 zg26a`-wUTi{b6#Le^?Fa`ZUWhO>=p5nYSd!oADz@MqG_8U2(}YU(Ia5A9{=?p(M!n zll^K^vD@nn=YbP5FCB6qEruX7cpG>s*nTCAx+$v=n>0!;0K13eq2v_CMRhM)v43r> z=4`foC&HEX49vN`ID8l{!q3U)6X5H-@u<()0Y48*P9=GbM2It6DfHy1S>T$&qJ`n@ zfx+M)Hy@K)!z0rc1xL4z7rZ0ID#Z_uSZNnOgFEli`r=ExLmu>- zb&^~X3_&I6Y7wX7$XmmaXu#zfrGeK%c1dNfNV3N)0ZA@wg7_su^=$@;WLHO|R~N}I zSkNE6GBfl01*qU&ji4TXa-Am|i5fTS8KVsHg^f@RHm#sM3ilj_oA3mxyJ~cB zX@JGSu_%r`&atgcTz1}`@hKeubJJ}juD92G2ad*|N39b+8$=SX9t$5Nav zL!3441>lY8iupjmpJ8PcR~1*}i*zPPcalSv0%gec*^?OTlI$y_1^Djzd7fwV!}3 z1MR`|;5^`P*Jd3E=Vn9ilgAX56Z33H1Y>t=*v`Vo6gd;~gjFqR#x%(j>ogMb%;&Ez z*j{SB!JVYvcTJplqQB3GzjP!9I56ZH+0wrZaDS>Ez03pLUiMBX&tT$R13sH1Vj!r?kbV_yz9d8PNjmGH6ToT;$60tFa4OoTx1s zt*ugpSi-jG!t0xvgFy;?IwtdbQ1k=+q*c1nAo2q{5kXvOPL?=O^4upO!g2fkvBB(XE+3d*HB!{#f834OYSI_k@OBQ(;1q zw@DW{az6WpkDq9uH6bmF46lb+qg}P5NvvD#&m8`QKW$F_*`-t{h`{f`85nq%1W1P5 zrhD!=)o9;=i9VZ7-Ep)40m$xzf#gHPK|4eBNlM1l{%VgBvQ5NU;dLu-&VE_q{9fD4 zjS|mIgaPr1^6C^>m2#~a7Hf?Ye4*;c%&Rw$;C?F8MRuEugJ|iqS(@GnRf-jQ{_BUo zSs|aaal?aQ2V6_3XBRgSqNo}1h#L3F?ZCA8cOTNsGoB$N48M_Wn7D3Zykb`%9E z!41>N%Q%mJrLl~KA)gf+1E*1k;rP&R>&5~N%R(2x5N5+}9Ld;#amOnaA%3!reaQm- zCfAmm)~9F!e=(pxM9}`)Bx}WFw&AQzFBAY(>1OmxTtzvX^<>pfj*HYr6y58G*n+Ww)FJAB>B(LIqs}@G6cuZAi@2sjM&+gshvnb;MzV7GWj;7&O`hk_*XoFR!*{*)b$=?j z-w2ufK}Py^7^tZJf6+E$6tcwVR|1BPns^>ML-ajGK%6UnTi59D3epUCxb-qW!-13SzFk~pvU;ZL zm|GJ~;S!RS=30t=aO93b{=rK+x1PLvmGY)Q4m~dTGVe*l48)^AUYiPct#Zz^ zrRSZ$Sb+4}u(0CQQ2$5{t6V5%N@R#zaW$jV3oHcc05ddu^&!~n-&K$f=T#5ojU`jm z+$D;1vi!1{A>Dq2&l5ME4n`TRI#t)~IC!3jemOhP3)Cj_XeIHO;q$YmaTUT1^u%CJ z!J^m_UKT-vDq}5UEQc!aj(OY2 zX@%V>-GwIO;$V1pCHUBiG%L))T2t#s9XQ$gg&Gw3{Q-(`2!D@o?y=v$WR=3f^6fua z9#}9iSg?Pfce#TAw}1U@Py>X7w2?p2f23)9Zm@)D#FOZFX%~Hvux*B;0Au8T;C~Lk z+jPf1n|l~(1zw+SE1%6fgfyrrbc{5pWx&Eeb}c^e_4DZDU|^ZLX~HOw4!RzV?P~1p?d+E-)pcuH)vK0X5dU(sx?XLE$_9PB|Gk==xtrp) zoZ)soo|+<8B=Fls6_M&#P926{HKLfb+!+BL@}_U@nsJ)+PL6w6qLy9sj*mOckZ3pF z>dQF{9QvkjMoB~X_QjVF8@b?9w3)huN53mIn>FyR>1%cJW^D~U8oAVg^~Zf{YS#S0 zByG~jh>-Nk)IppKBi9boaGwD8RdNrgo%}9+6F}+vExBjRV8R4w!DzZc3xA=WoYrS_R>$y&XX3qO zcHy}C6qekRA+BH?%<$+r^*3-_kl7oEklcp)LMZoP9_PDKOj3D8?emu-6t2@J&;Pss zU*_SLglPW=)%UUN`_Zv!%JL^g{R`G96qB8L@P4>v=gP|G>=LKQ#03Sg5Ys~AeXv13 zKwwUKyPR5v%?0?Q2$pZ6Wd`BeS3oW8jNu`=(A#FDJvtKmjkK0~bmbZcE_ysL`Xn6< zbG5YHtJcc-rh;VlcoF30dMe708&1!vMovr%b$lv?Pd)w93@hr?{vykM zm}}Gw94TT}{JVELK@C`xT=p=Qy%S^W40qU&HY&g9K$ib*#~}kN4Fr%(-22&ym7aN0Ryw?TQmVeUEEu^gMvO;Rc1SyKSO2Cz zqgedCe_o@-Aw{>#B}n+q09$Z;m@`vsT?Ji~FAHO8oYd`bKda`n&#cA{*r1`n%nW1y zBTFZxj0WW4dR;#ZX@u%Q^*y0pll@fz&_y<1V$|B{r6rtgVSem}-pHHGPnTBOS%4_q0%(C(3b`XXBr-3$LVRlkpwWC^g$-qb%IK?-&j6c*s7!0 zOCTxx^yarSZjl*2+<8+vK$srWVLb9k0j580d#!U0Q%VzFVdoZH){2ErL+= z-xRR>CdaQlZhf=;;*)pI4@G}WS=Ck`L;A_MC0|6cCI0?Rgm(!-4P z2oFO2KGkAmZ)an5&)xz;y)si@vl32}sM`CrDDua-ADEzeuDjG}A&d9=HH<^1k=It& zW(As*aH~K-=6G5BwR0l4XW+4>;MTsN_fe_ZPnS$DK*e7l9`Ra!Ncn5O7ZqAvyhli< zJR$;0 zqTh%Qp+FL$;3R3Ta>h8ZpslR}WU;C-VaeCCANBG9vZnUsoV_V%nwCY150)MzBimMn z1jZX?c@T@d=fVDEZI6||ixqZ9u_MC|Hq<8%6@bM(U45j#5YafDWz7Me3hKpX$Ey%5 z@}@yS21`3@ks|bsxQoOno@LO|QaC)!_NOFfg+Kf)Fg}+h*JVOVY-mQSSkk-o&2E4yUV@!$#syZekA=dyIr(Mf zDSQ3va*hQ*-AS=7J-V)rah*~fESVc4|BJsr6WRrYkeRUw9mbQS&+EbTd;nO9Ss)=R z)hTe>$dK+=xE9?tgk-9tF0U1`1)l3|PyMBdQL2$r*dO+%Ja{#uPI3ETdxcy%VG!xr z7hG|Bdoa<+B1SU2RD#^BOe;l39KLE~R~?036f3vTeffe%D@`&#k8)FYDx9k;(coEn zn$`!}#f4q`*TSBHUN0O;xiBL3UXD+X?JFSkNE`!RY|-j6g11rgVCxovz!lSwJPI55 zPooDmaZ@<5t)+Y&3bzsz{?2l*YzG=ev=(=@QG!fxUd7Oa5#)OYi#pOfuD=^mJVdss-a~W$pk03DQhR7e%1w znNA`xuS@3wFT_CZ7oEnw)tRKS{oheS-iNmkbpYE*YRHw-CeD2h-5)%Kc5wCp>@8#> zW`wHPk98wHDe2)8v>xM&bLHUgP^pYE;FKurhMwh;b}Ull=(@j$Hk?!^T6CGtF-_TZ zhqego3#k7OSML~{S?%1|%O>8FUCbnNwIY6>A_Q$U|OA)cG*MH2sF9$6g-sS5Z_gfSj0hu8=F8p=3 z1Tsu+Dp5dPZ8U0g2d9TWhQ6^{Ih)t>ZyE(Elewt3ctrc@S|HXaTcp}%&ZL<% z2Gv41lVcV(>1fD}Cx)XI&-mJM+Cm;gE4#La)h=ZcC!?=g=hhCD#9@-FvgSe-1n-Pq zue^Z2i{uIo6NjaCa1veDGH9+IlNZ_v0=NG59Bpe5X%H0&P?5zp@`T|jd`8Rwhl!Wg zL|ezkfi?H}H~DAp7VoUN*T?ba@5eRb7P6~yxr}D;uI^m?vKD@0!wT+6Gr)oT*%#)Q zWWMVD?E@CxOuOZ^HYHDL6BP*CdxKkp^BN4ZAK&wsV*%tN0N=r~c|XgD_rnUeBye%4xJZ&@{Z z0B}=v>-hya1JWxTO{{=~zx)cO3)IOjoFqn}&g9@v*l3%{KW658k>&eh|Mr76n0u*y zXXg8&2R~$g7gRxPXA7F&1S`}cxcruK%*<*dX2Xg^Qu5i0>pzB&?|$*Se)4@~&+LFC z-f(~GLhdE;3Q?W;H0t!c)DmZQ4uPYG#2N3Z#}2n`ZtenAH(Ds9KxottV6+hQK%5?1 zeIunsArduE^Z5D}7_9L87Eo_ZIVOEf9ANnZTutTsN&uGJ$7_=_D9_zf@hcwZldLN? zyvcuN&LERb)l0a>f+@!q-fb_m&&(L{yUH&Rbf$q0aZsPgxERr@PR_U3_7|P5L*(XG z%P+P_XX#p46!G=V)CHUX>w9sLEMk{9dl}_>(RDxM3*yv&DB%+5o%=o(R53E*xiK+1LAWjV@A|bQ>S#`C>17ieP**vMnWu2<@a%F@@oZG8*uwARLQB_jz z<^%byrzN|t_K6B16oDUC4BE^pg`YKIUS(d}SBDkgYKK?kJY!!2tgN-KTwc=@HoWjn zS$Dn2Fkh2csF9ci6wV0mzvzJ0gaalDwt;9EiwJJDD93|QJ)Q0lWISl7a@ZS9cMBRS zDN`bwoNkEIKRDSpGVAG@2OJ9SpQ-AUG`i7}lm3)$o~5Pn0h?5o3m>gPms*MqbFJ8w zjiX1Xpvbe{t95jNzPez$U>I>a#GY4HD2Rp>%NTscLJ07`e+`1m$RI_|407$xt%Y8Y z$xMtA71`4!Se(~KuTk<U21{v zapZ3+BRc&NC=Z;49B5E8L^8;w<4 z1&oU=;_Jrx{1UoFHkj)w-C|FjL&2;*@b+xlCsq41^wT0XmybVHl$V=fS ztWH10raHq4Q(I-KMXC%ZZMSXp@2yU5=WF|o!6CW03{UgS8=x0Wc!K@~ee`s;O6Z<1 zzIVEV0U==4`4H9A<2Uv(Fk@G25uaYj&pxLs2bNd*U!4^CSDLe~EEzbw!BQAL2)xm1b!S`T6noKrbsXa5POm*DVc9zACr&+;2u?9I+g@bmn4pFxyRl1!Z+DSly<1 zLiN3!GsvJ-1z>yt9TLo2sBrCw-mRTy8a^o0v9U>|k%^((KZZ$IPz~ zsLerb{p>|_ zdZhit$pe>0KAX9r=cmGGWdNg$0%PVM*3~(to$WG=wVy{80pZB*qY|6ucyzWyKzt6T za>4zrl1CKp#;$RqwuxCujnTi1E{H$!OAWFJmrdny%|cC}7FfKz`Uoz9wLsSqY_*Gc z!@9n3RyyoxKC(W4M4-tLQAyz)eRN()MsaQpXd&dAr^R_d&PWe|cWT{*LIu^3?O$z~ zczk%%1eSK?+IA#IXvmz6xJBFE14XxNec*GpI<^}fybX=wRKj%U4G3ePyD-tkx#U(8 z#D+3skcr4+ILKGw=S;)31`gVlxQTz>UlOr0^l*lsxcx33xp#bxVi!-OFAi)O(0Z+I z<0oLRYePs}wbdl&M&U7n=I1jV+S|ENxn^zs!{BMdSU0qUpyz25yT?SC3>;)F6p3jy zgRh(A+A|Q3>`$T}?yeo}paroWlrFDQiH=|Jb>q@BvK7Ie8 zNS@RGEu7+3F8U2RqN;( zxcV%?Cl@r}l|wqlK{{q*2`GO8YwrLDxyLg{%u7hf0$~lp_y?iE(*W3|$B^ASrn}tU zL4*4b8W!f#mOF3c-QaoJoCA4Kt3*8oI3ua4^*k7^+tp765bSC9_he}#oC}tg)lESH z${RHIVawt90$$rM5*}-ri`#kt-BjiyDt`dK#itMQ(p3w=u>w+xfLWM!4%lz7c_MBD z@!kX>KS0>&m$`E;8$2tZ)4dH09DRJ6vCaRsto{1nlHYG|7iB@><82WlN>cT?fbT_J zXK46}4j*=s)#@&R^4_0YxGi1sL`r2>XErPUz$U`B^DXtOA?Yc<3)~l9cl5Z!T@)}b z9%@7_a~x1O{kXX$1d@%a4`@l9?I6!svGKeuNAN^tbPXRdzwYwqSsXtml?`-=xNHGq z%bwE;TwJH5#)|-+Wpg*4e807Ln`^Q405Zm-vC*n;iU?S~KcPZ?CFGL^fqK3!a8Rb_ zQKwMJtgSxweX5yu(?g|N`34)&EHF*sZILm|qsPS@`HupffZ?xT3c}ZNZ@!Ap5chzN z4)ISXKYo_u8+$M-dCq-2c4t-lGOx|IllFhQyVi966`_HRIix7+#1Csk8ixI-Cgj`) z?JawCwbS*G;$6f41P0kNA6JjzVAsV~tFFZ5Gj*BTW)}|;MFl#!nx|nH9;Mbb@$5~I zxqmEx5EwZP0I8XDgD(Sk!fbSHS7{3nUZ#=TryS)x^*7FGlig4$z=`w){Ozsmt?r1Qx3@w^T3tp?np?_+A!TL&M&YlMm*)Pol zaIiXrqxpV3QbAPfW0Y8>vEpsN5N~~Cvr9@ja{@Ly=DBWMWc1OWNqc??Jlt30bv+d5 zQQAsV+d$a|H78LxL*pu*@pH6qw@gPiUI*gL?sU&9(tUhK!xCv$XGE4F5&zRKX7cT% z9*R-j&UCrkv`fkkv%Jb}QZ`2EGJFEACM*Zpt?)+!J5_&V*iy0z~?0NPKbnX^4JjbR536dR2@uHOQov za0aQQ(D)>A5BiJ(!l`}N3{~x}Ank$&)^KLUgwuc;L)3~J9F$k0#uCH1Eo@dDklOf7 zj(0px36J_&oMLQU3C)aR?DE(vQ+?}ZNgymGcrDwXi~|iUjgMr^FQk-q)^`r~&aIo$ zksJGE6L#N9R)N7H8A=ay=!&QW-EPWKGq3d@&bE=qJchl4iRU;Zy(z!bk&?zI1n5*- z`-nC0O-pAR<(kzf$DOZ7NE=1@&6u?lNz5n(q%}H^uc(^lR^!4A9)B49)9oEx^SAFnzNxddMoxX6bQ=UaXVM!@`z=HNx87&04JefTcf8A z$4t%x3>^gf9TILRr}2VB4y2cP-GCV`>v}xGToWCeid@b~B zYm@)r?767N(+^jztPAaouq=|vSX8J~Z|*yl%My{bO07&Ac+NFHTne$}$*)D6;hrZ8 zju$Dc@)Ictul6ZmDW%If(rKRwQ}L3@YhcsAqD1x=(Zmjn=Z2QsV(m27SAmtyPDBB2 zwJfv2SnEbc&EQ8e7^ll3j*&Tnq8fM%YM5 zeQ79fP)`P?r+r!v24EjbFLYoC157lHlcrBC6dm2$x^Sse6l<9zcFlQE-85}66fd0` zlxr8O^vh~c25Rw{tu!EOn5EKph+}=cVs&y!)lkx0YIRJqNj4?&@<243Rs`Eq9mLu* zzIylBp|(58u4~%owcPnLu!OW57vos{{E>jb76|=;0CVkXTDjvO8^y~iONr>&ZRj4A z#vP)_*&A-Yg7>)1IQ#mcH#2bN9#EY?fH&oS4{As%MHd47mZUrKK3^B?^4fI3W0$nE zEaAo3?1P|X=Mt26BXA{|g@IYRH=an1ue-Dz@CkCH6fd_0#n|R^g|f^(4EUmL3k;vh51c=jB_4$p z_|7o*7gM!H!_-Q+9UbkzbD`+4aC|1C`5L?rNwACDeTPMtPTzk|7uA(zFLPc8a92SQXrBp88YE*#|6Y*^Y5kE4yowNUT>Fd*;`c_#@xdE#5Vc4oK_Bzh?SS*mES6 zdSxYX&Wh*9p}m7Yk79;irFM;#h_-oPk2AQYUtrzB0Aub%N9~hND;xvvL+xoS40(sN zNe6TE!c(|XzF>Y}W?GdYVm_JV$%heR$9q|0~p_^jLrjF%Ty4-zdf8vj& zkX5v=3!v8;*heGm);W}{2fsN}1)~G-B zt+&hA8QZVYNs$`T#NyTO(LHUS^zG)GWCn^}=Y1jz_}gkXk-g9In?w?E?`M9D}^Ln)}jH1X6 zW+KSsM^v!=sRpxvu3;3Y^3Q_RVW@A$doazvEP9rcx!Q#ePayFA40i857Ija&6I`L+ zX#%1bVb9)&2blAOqZxT=E5T4`<$FZT6HLT#LD`{vs^kGUi{*n`(F>*%0qilY2$t0W zToy=fxOPmI!3PY}Q-#_Rx>(HvwpQ*)OR-#n2?fM}jSvF9Im>JqJ40Jn6(lzke74{% zo;f<3Y_m|!s!wycmKYJQLtMijMtQ|+Sbn_&TXFhB*uokNnG90psu?QwK?2!;_<(>U zB3@%-$khxkz}Kw5@IFC@)aUmbXF}3Fe#?Xivbee13ImE{EI-! zYfcCuQTya|*O#LpOpT|=s_baZB)2X_d`OlFq9(FluvAVR+YxK zyX_;IuKn;P3j90f>gR3NR)CkUgDhLN23Q~k)GAK#o-34UZuuP?wnPwq_mR2e2EATo(-eeT$-ouqI%!kF6kjq1x%FlU)p)OTqeIeJ zlM90Gk`p8@Y&i}u<6qc2=rNA-N3qQAJeb{)PC}NPyppZdOfTGhdtk~_L@hh=nKa&j zp>KqQx@ywXgdH1LtOX6r^X;3ZLDC3HaQk>*Y~INIE{E_NVLc_WLvt=HqlMKh8!_F+ zM2OPKlb&W$-lhE3bQzF`U7^=HK*S@Z+hKLJz+M9~-H zf40gJ9QA*G20htLkx2J-l8Sgl1vuvk*vKhCdedel(Ep*-{4(p`UqKsWJ@aD1Emiog z@3@0LQSzt?JpdyF3W{LEY)&FgEMd0Sz(7{mEk)_;MYn#`sR! z=S59ZL&wx%Rp_=%kskEyPCG^hi;FI&T?V4+YNw_kSr=^POzRdDcp*a-`br6wALoq_ zJ*Z(u#K3m}bb1|iZzsDTo~pF14nx)sk40v_76DTbo!nBLFz)0D+mPTM#Y3RF6KnkRoJ&1#yEP3Ma;`=s=ybW1?Fja?(=MWL#eJGI zrXdn;^bt(o-<*EghXW38>JK~g*DywmLr9N)_&Y%v{va9l#clzg?xzXYAmMt{gm=hG zi6DDd5ba&Ij=R>~J^?upYl0J`{?yLIJ5??ab+-|iOSg0YU;Me#F-&;<(51J!bxLFp$| zp}zr^!noxE=XGc^rcD>aoCgC`dRl)vER1(u)B>bHUQv(P?-n=AJqBo7ld7i@-ko;a3`~P;*ayfo#ELFu^Nv)8!BZP@I7{^H_!Fz&EF$!1XnfPdBPn5&e+d@=b0{ zqOSQY@EDR~cKO{fvo0ZKW>jyvgbn^YpTq2DQ!RXt2A$LX)yp$YoJ z{LEtor&XjS#4=zPs^hmv^AN!afcqNj&pdzu5ORZ}$E<8CJk_sf%$^7rXkFF~)UI9^ z-weH)?vm2j^JB0veAb3kW+B<8GUszAd@!-k@sw~NMEFWDAe^mB)P&pr?1sOHGy|u` z)CtTft1J4%McM4Q&1Kf@L8e^B`pV)|K(IwJ>Psosb{M(` zq$~>4s5+i`@kCUQ8i$ixXW=DEW|Hg9m>M*#ey$(rcM+VD*4dFU1kG0;pk?d6t(+L8 zKbZ3MxV_qI8}0619V+9n)ZJb=Rz^dOT?_%4f^&v_NW(jbRa4hwYexL{VT@CWQJ^X@tGtaswp_?Otp z7s&rjd~1CN=lEX~8qWu~#(%-#nKwJRgs>nW#u({eqwwFv)ERX6^k38H>}~(Pz^P&X zlPxJM1XQZW0|7x6O*cA5{9ox7i3kMD|8zuevw(%@$NMjijh+Hx>wn2?2=ow^|I2Ih zWQSOR{?ANMg#7^i@6^p@xb%iNr2jJ$M*7>t? zrps$Uyg>Yi{3@dffeniIKSg7qUMIZo#L=*H(gFzT^j*VmVOp*h1pWVVVW+eqguwng z23ZfH_`itQPV)KGY_M-J8f3bW!nYVrX%QW(?Mfe_7Yy}(rmXfPgj)P=_WgcUzVx{z zaKiLmeF&uVoCS0=V6Li-Dw+|7|IZG_b}tdemZ@%+#00Ts4q3ycT1YwJ1?DLz{5n81 z_~PQ9Q|O06f|1Ou?`Lt=c2gHssj9p$&z~QEI=YX$kN0X`;!3Tzj*ZpdG!5STgn?fK)eei6@|;z3zSRSqS?z_Dn6*x*OSRm|-s)_0oz^#0 ze9lRa-twx5d51q#vduRx5|TN$W_8aI2KxVk*GUN>0IyhiR3D>8>R*pj`Y=$JCph11 zB}v+;jX|SL)5IW9(NL+_<0B%vBD@nUBEJ4~)&JBt4V4)c+Z=3<;Kw;WP9~70p!A1b zE{BFh73XsbDx%^q!jK*&@+uo+m(Tmjn;$)lg?1|z;=qZ9%?jw%W^=*VmAPbKV2Xx8 zIqhl>1#U*0^y-Fn013kT4rDdQJd{=$@0Rtm@nwGQqkBDn;hqe@#E$hzd}BkYZF8EP zCPu9AEo^gIoMuJ>B0riD(TBM1ax=zO2Im5qI<;9g4{TwWczC@5dpGZ^xT})0@uFCl z3EDGy1d;%Y6S&X~$B?59$1pOxc2U3#*QQ3CMF3CQMGmrK_WB$14Z$H?bHGb<@AmxMqBek2mP~%-L-Kx`F%%yLz4@$KSPfnG)uYQ*+cRSHh9E+=?XY>V z#yLV;$D`AOA)?96$N%rN_|FcDGJ#n9?`{Dvk+|Oa-eDKu=|Dqh!t{O%2-LPLGl;kU zHm^I;kWPO$PyU}~YM`Ne{Y?ghjO|*@B!Ynv#(Q?${RYjY=6#SG#N~TymGe-(>-GQ*NiBU_Zfzm?{2k;+M zq)PEhTk!H3Kd4hao=~w@h4|+ncKY=9+z(fKEfvF`7|z4S2Y8kml$Donc;I{3Y8d9I zLncV(>8KXbbBQWXddw4-^jJk6V&-oBOOl31Jl;RG1rQdc5Vy|^YYqYxf^J+fAb%mh zy<`K-7L`WNUx2kXn4W^k|Gt!4`28{s@|}4Dp^hN1F6RQ6S>TO&%K8aC!DKy^0NM3# zKth;}FD}x;$8a-K-SwPCG>w-b=a&Qezzd#>M8dF31RnwB{Ci(rLs{E%XRss#CW_>hj;mh$t6h~0TX+NNd0?i%h?883)BFSH!t-2`X8fiA(iM@{2i*!b<& zt2-{>$fR}u&(Z*QE)%AQ00H5GNuS0076kuiJ@i;XC_()9oJF;V(1iYv=$D>wLimLa z1O#aMKb8~!IcG6}OeVHQE-tkKu)Zn3A02vM-1{834aUrqA+gXzAYi*-Ndr*R0WP2e z3A46fP|ZftTt=Lx2Uk!c=drc5c7j#4O2{`+b`4?V_$*PLfjTzK=WBrKr7Al?pRd#} zpL@R@A|vpDW#Y_(>1=L??QXC8?WwjOZ!Z97kOH+l6O(FSDQ=4AMTX}kiz;22H7q4N zEp4eO7NuFrRGDcU*>p>AS#e&O)L-|pIr?(?c>#W&#|hl1!=_-_UsIYTknT9lj3pCf zGBau=O&3Ze>Pn?aBfpANI8&`Fnlq9pQy5B1(!%u0q%1a!I@Kgo|3cK2mx!clRLrMi zRL&tO%J`E3zkecDmzc|Fpk2|4^Nk|8lw#pO{gg-e)iB_Dy2)@Va5|}Gr(V($g`rg9 zw%9d|1YhdT&yWzbSRI_CFsQF69g%czwF_UdC_Wy>z(e6iud<3XSwe(17^>{Jm} zJEg1Alb`M-*&h7~5wrZr>R*lf-HYxlx6MHSv?NeLn=DGOw==_9aJLNm|6R)O% z=t~HJQLfm3JvR2xPKm5L(jBjgt%)By^QH6vO&@_|AG1g+(n3Y1)U1yIv9-zma^t}% z4;!WW^Y(O?%B4M6vtI`ggi59Dun86C1@i0Em(-2Oi51~$r$*}DA;WF~hc6X`W^M^d zqn0Z18+-nzuylfzQi{srG$*8Vgk|#!Q4cXdLZXBy^z)kmw?gHx)GUCJu$I2lH4l5J=_sZ`tqAq{+9G(<%|F>{+j6O?bOxn2E*CXXZ7A5) zm~j)&6hi4q_ZPOTUyXyhm$tYD)i(jTOUi_?nt~3hUR@Kxbk|Cr zx+iC55~DDCMfSE3^kN61MYk@2fo}Q(>sNW(8A4dFP+Tmt)?Hn}iB)yN9C$HoW7Rsu z5fJOf15#!Vl9DWqWCT|#o*5!D^-xeIbljssm0E&QwPjt5n?z?!>yB0t-ni4eio7#&y>MC0ry>9ojMl^tzXLwM+8mvf-(5~VJ zVGmogf@Ae-%5z!`-B9$j zwJ(@%Ziv-7>FPB#!j|elfScV1+F5f|QA2M_VQ)*Pm$<&2y0~iWb~)sl8OzL$nzDiZ zoYvO*rq+hel2TuLp_7-mA376E+#dCnO;(nxOje(nml;6cMpfKQ9}%|eTSL{*(qJwQ zAa@QDbnS$>8CQuCIOX%rnnfN$MPizKUQa&XmDSS|ievr*Ggkt&H@s=sb1PU5T?cPa!r@+e zMp7+Ihj7BiwI%=-#d46&HG}<|4kJlRj`bqM)YspOPTM1xLJXdDBCG~WygJ*?t5eb? z!CGAVh2&nK-H|3A3f(q0~rbB8M`VMYi@d8 zWkoZJ?#saGg9<+UihF4<6fG_r97sYPE`&2SsH(L^^pm(Eh;vbV(FTN@Dn|$IK|4Ze zO1D!VIT%Fo#vkUEN#<Z^+b}ZB=Jo>%@%%z2yk%v%IQP;|O9QQS z!owiA8{vyp*p-W|2PB1YDAR6FQuJ{q1hEFu#nHf)70IfTQbHa(h;Nz_;;QnAA%@Ri zk7sU(&dzycVW@iv!O4fbAY*-!d0YYo*79Q7_Cjh{Gm_d$iVK8Mj^NN@A|ZfBLu2fK zFuy&WpV`uk`R3#jDFNps101{>OHxS#=D4ZHGPF}ikzF7Whwbp4b&j-!IP{t@xQ@hb zRWY!?36~~UHaNR#`M?^3q0-9Qu8h5|6Dz(L3#dBnd~a!K#G)=+sw^2h(B68Q7x4ff+@< z%b>qyr1ooCQad5%aflSDgl{S+CWv_<1O*5VnLCitFwJHcK3^m!5!%dq;9tES$Zl@j7et{C*J#;)P{(cFpSg1jD)pV{T_OVx(bb+3lea5X0>e&Ca!_`pqCW5x7@NcmwVM z$Y`c%$Z7bCh#$;9Hsv}68t-CDs-!(ck#)rSUf}vrm)7c=e=9CEk3{|a!Y8Wl{h z$-9!ML69gK+)9mp7bWMDUr4=S?*z%? z;${S6Leg-B62(!cepSGm1D4ep3qg!~*#2{f8wtX<-Z-tniIpC&u`^kSJe^YjuiEUM z%LU7{jGL5d0w1Ea(1lo`UY*64?SQ$BVK`7~=fL#nt#hUaYj~^{ZFt<<&Tur4vWRO_ zf<3Y|rHWz9A%9Xm>luG9;smC)6bpH&@<(4%mX%*KL%E4ZYL{%j6Ks5Dzh+h0qdFlRSNvFzjwI$zGoW| zwUZ_~n#q#y-L3G_QsoUMi!t@c5gmt>3*@VYU+)Y#sBI8wRWx~91K{yb<&_><#rkFI zS2vu~zWji(# zH`Ab|A$@fcuP+2Bevp1Q$>Go27c?+6hc7-L)R!dq>$X~{>3K=a3cgQb&tU0!<+%m# zi|-4nlhDAjI6puvod2toyt?Z2U2=nr6!izpbh6sGgwL_OPV70y6O{aEc8YJb`K_Hy z-Drqk{8rU1{xdKZuMZaeiOUCCzX{zDD)Q5V!=K$pXRpojz3alNQ(_r=3g~_rg~_>u z_eC@+(t2kH_tiVH{kP3Zg=v(qJJoLCnef63$~J4{+Vq!=FaKNZhzE=7@+gv!t*cqt zt-V;Ev-5b-I9^}$PV7;4;{J=Jr3nivqs=>!KVz`(Jr8h}_N46R!M{fM$SJ=u_%|h! z6{W}O6yM<=%d6EFoH12w`a#MeShmPT2T9qcaVdSt6;FwB*X4)M1pk)hD_-9v2`*!( z61sv}T|>?|K0&@%gJEG;RW`9b-RS$a4gRzA zWhPeg6qp8LF(E%B{FGFRWFT94CLxyE5bkv3=#59V^cC_EKR`|_LQuYA@liO4zxg(0 zN|75JoTGCbDJMsJ6^RuJ%a(DL@xlWVgwEs_97_9F59ZIW3eBzG0}xhbf~ft+1!9Sh zDwH*A}i z(f=JiCBR(qO?*n)mZ~U048@PLg-J-}5gi5QiJ@fbO;>ov(9RL!el`x{%JF`7A&v+Y z6O&2Bb5SM^ga2uG5c;4!i9yE^i>ReY@`RaiBqBa1j2H--Lrz;9PeMHEn#p0l`8iy0 z(H@+&GB%zl!L~X?l)&)`_k#H=sn#dVyNVR1}D!B*DV{^ z_pM9liqfCiJv>kV37(Hx51X5bpkwntbel#@tYp@vo;gjjJTX?=;I=FR3Jaz6jg#-g z@#~x8bp`2HHdL=+K@~KVuabuLmEH>7wc*Oi@fO9{)0SBcj-?}>5V?koy#YfAXIF<@ zd%K6eN^U(~eBgljGqFO+=Qr4~f)hX_>kHPW_L02)kgrr=!7cKOBtltMT6+io`UW}G zj{V3KEEUHSg%3e)x{7=fW%P(p8istMtaet3v^M!D_SoLy-$15D*a7#N61j;~)H-R% zB)~y_g2OHC7e1jOkQ*7EG!G*Vsp%ibCo*5>m-NY3(c#V^{95OrU0~hgo+WVVLCVoR zT3YU1D1zeeEXtQ8q0m9T%{xqo*@5b<$~C(q0WL@89`3g(u;UW}cyCdMbh6n4xmmQW z*{(ut*Vw2foB>LSEc@O5?4Jb8MI>!XtS`C^jx{C=t41mdn>(CCz)T`xRt`NsC$Hj6 zd6I1M=)?hsmjI=`43!dFViFMSe*(bBr0>{oL=2DK=+v}?IyQY1$MP&s%uK#Wiugwk zTTmnkWW^o61;>n6)D40gXMtrcX%HeUUC}r1=}v7k=#GQW<6chh!~Q1@fqWKCtm>gE zr&s5pFt_BUoaH=(6+s;;ALIQ|uDgUyCT;fvejEk4c$NU*sUVLi78rJ&^n}T(&!7%-iGb9nB7{}_ zba+k(MJ8x<9dpt=(di#Ihdj&2G5Ly@lCyho4rAmk;rgMY3Jht&>8Enoy^oe?x4D9w z*VhR3M5~?VnMC)Lm=Fj?&D*&cUje*Ek>Kdgbs-5l?x+3aI}>GvBTiB+=(?E@=Ewkx zL<%?c6~I*V%M4-bw1}L-V6?MrB*RrqDgFU3LKp$T9l{Mo-`Q#HWIG>QHexOif5-OY zfu=ni=DOX1063~LbD+~QJPMip^$%X4D&9;grgtvh&-J)QsX3~Cy*j(<^fHb}zxd%Q zC@L17=?564wugy8WVYb!0{VqLHnD2VKBYw42#pjc)-tISZJ07$Fz44&m-pQgS(Evk zhSZs*#sqvqFDu${=!?K#hKU=ZB>65#L2Ps@Jvfy!T_D^U6;a*RxDD+?yS&-~9sL^D zw^s>&73BDCfK@(nyd=n$Atw~`uvtWDZ+@J-k7;FTED?M(GH86*{3~o_d3JqBo<;dq z;2zsS{XT~(KO*LA{^-J5zq^?qi4HT(f+kt?5Qh2bduuqERCe!T%zO^bm;?M73~ek2 z$^=MoF3{+%$OQ@--j!74_sNbVn@~zE2C)*vI(_Gc{1=JPEIzy@w8@wRn-(fp*zyn9 z{!3-tvzk+T>j#IZSy9QiAdL)l75BxYDL^0Z;&!_?1vR~|(&>rko6JoK8#?wJ z{a0*kYVqW^c~`Jbt~Z|`JF!0fuPB>UXxwbc&pVF4!JBikhRp`2Xa3slk~um?I{65s z=M8;jvwg%;zIcgCnXjP3?ZcYHLqb&3@;N@7oyCE=qKNa4%?7@x$>z`~DZTlSadEUx8s_mexsW zt>`=Y9FgXn%9Ksej5Q(6dg-D$2;{!K1VR&fC8DguQijwml!YN}sY|SMTx1von*La8 z1kAzZx+-mMubz|)UEwF;VZyh~9aq8S67ItRSbvn0WOveHP(n^D3!MQti_W7k-fZ*? z6F#;aLD#KbzfnFt(mZ(;I7>zi*N=)`RYR}2&`f@6z7*u$a0jw-2b)?%F}29}z@L_{ zE2Ia}67N_LL)F_?8SRK7)?9p}Vxb`h*`Y#$Ue{hn0`1fO)JY<4jZw4)t0$ZCMbkXj6{76RX0<2 zV_e6z%O#4&Nn6T&VJEo#y(3NDr*-bm%#4BAcEuwqKF`fsI0-hs(-HH21vD~-fsO~$ zBjd_`B@_Ef+GJl>%#5&N6DUKQ5EliHICEa4(p&uf5P^>F?qM{dWCXz!?veis*_2P| z#VTBX(8+pcil>vPn2;*CI@Cpv7j0|li*gT^9JNfM`qLJKx@n08ouU;ANd&Te%^M4B zWTxEUyb->BJ5^;T;PEQO8;Ap^h1@k;GxVcIQsoTUNH9xDGvMyy5cqYKc!yce|kNm4?q)qsQ~GrM^s!^wV6dNj5(vO5ojj>^l^B-`to3 z+ue12wzxn1TisaSs6FP3Myvec&gf&|`*&kHi_d+5>RBj*1ramV7& z4=VRfJWp}QF7jQ{wmd+n-=EpU2OM2JAOjALGE0lRrSqBYuNYoKmEdI>Avi3!K%#jfJF^{azGV4r zXfq>{(bfHo!V`VqxXv|3_XB3(pXiH%{lq!jn!MAaetSw#l&5-EPS^Hp@ALiaKN*8r3S&T_3 zvE1}G^*@nitZ#(!V=MU|gn=NeYZL}C?X-5Y_tAd?MIt=OiKftd4Ef^NHD=90W_`tk zG1VQ=K|_E}!t~ zi+u~r#aP47co}^*qfKI5zjSThj0XG0TU7%pg=RWaX|Tw@Q=*u4JpCc^@dO;J5k0e0!dxzF^pD`NGKP zE!P&{R$n*m{#ZwrrRX=?L6)T?p&+Q%08^^F9Jw(AisF>UKyJ4Atw~pC!BH8)F+llEvgrgU=9Sn+wCjisT+h5XnjLept`QP(y?&W7K$=pDD4a95KJa66Vj4){r~;hBm1%dm%D zzY;{?#M)j^BJT%#Gn_H2{V^2IA8(oWZs4V;>45A&m>cMj7cACdOxMU>F<}sSURv)s z)cIIg>mg9tzLhS@chEn6URWi|VaowhOE`x(o?F4Y^_gz*2^ydvzHKV|$?pED+I?ljEuAT6@dPm@_HM9GHBh zwz=LR*)rS|1&x)sNEo&y+E6)~%MYFX(^P7m;pwQul`vSgO}LGh64CI^{O@4#d)-Tuh)8>U;Z6QHk!(3Hp)@M zm?B+agKeaYN@MkDyn1o=MxG~K_(12EEar@h1GIfJm2Cm0iQ8({9{rj5D7z*yZxtu#t+}AaJ9ps2RyyZyu$UwJ?p9LsZ zw1EjQ?MwFY!_Pl;^3ltyvMQcBSGJsV@g2&^UAALX*I@B#kTwt);868Al&s5I2<8(P zA%<58B)5nD4WB!m+-7#(4tijp%qBLnwdAgj1eHqOkm&|~JO$FY;BR@mnmpog9oL#n zbEYWAMvC~z&O39{@$P!yb^!U(A?ZE4TwM1au9S9Nj)xMj65=64&CH<-k$j-{A_8wa zg*r$P3WcTm)36!mTu-zt(@wfw&H`L{Fn@H>I^q#Jy~eS&2h&(}yTDv~aJMUy4mRt* zZd9P0E%G_CpG?p=<#|SVZ#xY=h~=GI<(-}^iX{^7Bae|`Mh4RjA^@|5he(79<2W_O zrigpc+mfP@1jX9g;MyF%NbG9o*Ry1X7dotCax=|p#?9=KX4kxiNJC5;(vo$=H=Iy& zZ+JD%2(!67Dyf7-nfgZ$N*fmKiDgAN_8DBDk%K!|M6N}kF8}R#68xvoeNb@E=UX>R z@;TcGNKEZn6Vm?*i$ELflc@zuN?W2_D#!5Gwa%M{2#1?7sz)gBc}e7tcjC@8t8k#0 z_f7!z48C%_sK@yy;efv&VL&bf&bFhakKhB@3*Ngg$)BWAX=Mei@WR89HRgjcAejPT z{+?gH%zfN&u*-Xpz+RVW>GzMzs9^`T-Kq8lQZz^2`!5E3ULYQY5b-67+t9XLfJKHTt=UG^7(W5+?tThHm_L{mNJExn#_ z6p2A#zoaMRc%WqbEv4HbE+>mBRiPCW=d){<;k)YRG|=+x`ji*KTe1?KrU-GH8=mhK zIY(R@KW_&~&{Qehpzb%HemYika%-O!e)U_gXr%wmE<56HEbFxq^6~z4U`%EVy94)S z_uh%~%c$^6X=T;7C8R79k~)Sud{pnOp|MsIM%jWrc;Pq#ewKur)i(J!f3=HE6yh`Wd7`JGuO4?ojr>-Ev4TEr>w!$=C;L6FBFmA^f0vzwmV|n)Hf(cbfcg>guYCM29{+ zwuxObJNTm4iD1#0q6cYUulpZDBmO#)wuEy3-pru zdl?KI-P<{|bixC=!?rX%W7M!WP;F_?D}+Vks+l>3dw-yeuj^P-vri(6xOK3&;jV(ajwpsDlvj zcyhAvZQIzFn|r~rWAInfnSMyIyb$@V@GO59z9(KdsC98oW4`HNBkEoey?_}p!X^Zv zL0lpGqq*0E5l-CIlBgW{F_l}E&Qr63k*RuDZTKRBYb0r&F&jx^O%OdU5!Un(*}d_x zIA+`(xT{>l*!2nbdR^nfqgjIihl>M}VU-2AM_gA?`!c zX61Hh&rpX9bu5V4*6(Y}T-jym3j7e}5@#R;VjF-h7)YwwvS*lfe-qSQ6bD$^E^z#= z;UNE0zt2!hoh--c`N1r(rEx5F@|e1Ax&HAL^69iazj=-ZaX?!4{B<+Vr-1+z>ChCW zw|QdvR4574wDSas5>O0Z5m-nCJAVRpc*WR|^-1p|C|gMQfx3uHtjlzZF+TbUh>EmZ zNvsXU2I(~8%Q}5>ioP1h5q2;<~vEb<;2%Hh6ijou5=7`(9P_F9W zTwfWT&AtJYzA&wC3UieAXVek9$d0Gq?&sz6jw@U+axmb{$1*eE!JD<`j7qQC7EFYtbM94pzXpv%jI<9C|Z#ojf2=5q# za8;Aon#3h#fk7dBERp*^?fg3dOMoMdbD4!xQm>X|e9BCH%rf^vZU&LB=SJ4Q<$)%> z@wFM(jI?pXx4psnn}rmB4;VFdC1BFl@|9 zQav|s`_X(&%(7=tq`Ah>GZYFq#F|xjhO-Sd)H45L8{UN}?~%(HU;6`m6N(iUzjT8c zA8oE!3+R%a0W-oF8SOu2#s`6kxfv!rMBI^~m(p5&Yh^FW*goZp?V^Gh!qZoQgm0io zoP-{SV;Opy{xhTnw^BE-Cv7(3j4=JyoYFCz*+P{F)4kzTY787@%lS~8Sz|whDn()P z7Mowfk&sb7i2`qC{f7vJkxxLm45h4UOfz|FIgrdprW{*JwbU9?CC?dzn()R(ugI-M zwe$?f3PF^H#nhBdT|-BB;5Sx!i?!EyS0&7>i-jXS~QO^_cg=M-ioWI3j&4D`J;5;)$eiW*KHb z9|-uac`2U<_|?I>eQy`Bh<%6>+Qv1f`tE-4waK6}41nw#dn5UYb($mj*&XI{;Unql zbeL+mMqg6dIy7=waJFj^xMu01k8K`ft~l$sMh~A;jj1{3#8sYWgjdcuLza0+0?M@G zWd4;SFv`~BY~;qcY?x-8=^VDfzjwW+feOP;MnRh)C<72NXcR{C^D!s^RI1bSJ%BZc zu@c|7o-nVtDL~PI3qE2Zli}v&IEtJC1qBvza&*LmYQ%)~$RYaRA$ib*EFjqsMJ|sv zp$Xc>;ed#|EjYwb4vkCNFX5E zH2*8XMNBU%gg^xH*m~h-K0MZ7mhy41X1PYA4 zf5;0+6^C1?l^l!0HhnY23W&@|R%Vi~jiJAA`H2Lw-Zp^64-~Wc#AI>X9AkLl&n8*r zKMs`h-2y|v^26qk@3?L9)OMS1(TV-z%76+%Kl8E}shkM&%0l}Kj-yK!S;-c7tslv8 zGiTB(Ut!q|OOI`rKgb*3y1;e<`c-zbZ-2ME?~LEl13U)!Sw3pvft17TICR%n8{AFr zN;^Vs4V)Yez8Rpr0|n$+(kJ&m|4?XoS!_90jzFUVm*rg2ZjZkR%v#%=^S)M2zYDhq zPsj860(-|z9qn%X^-lZM`{i$BEV|wxJ^$uL;Gw;mQS_z`7A^F-31kX(N-AEMN~8^T zeaU&$$mY)%57Cjd8p}=nmpFe#R zd#4pN*!1MSxlhf{zsjC7N3mo|CO<2rI|^il$zhrQW9uAIZ9=4^5Oz}}od|2*xjuf3 z9Ck6Gw*!+xSz9hAJkQOC7UoRnqc)cXvb>lq`rsT89|nH#I?YT%8h|BBDqcBQ`;#gF=JO2&yY*^ancwUr;1Y$^m_*gko$7Gh|#!k3X&?xVZQf z+OIze4JFy-?KtThJ;K>bAz&q>2OpgjHij3P%TE4b(25SNZsmf5Wmz`C(|bFGAG$| zbQNrA8v-{b4n0*KXhwp%D>}2YG|?{E*BVkAbS>;@xNi$r{(Rvotlk2q;T&U(leL1}H)cGXhH zFk;1n)MOtT%~ak_@pj<-WA^Xn*Udh&uZqzDIl>Y)b?;6`BTt~+3#9K-6{t zgaKp23yaor0 z@PK$7*@xA1G&9eJ?8O$U0dmN+OJj+$cjBY@Od*W<{7wowl&zv^M_sPYv{dK9Q?j_^ z{K=VKjqRX0+$OM;DdUB@Kw;Z#wy%4F`a>FR6`k{0&=$Zw>El4d3oqDdkI-SKY;vw)WU!6V4ep`HhNy8mE-|n z)-qkPsXalZ6?$zmB8lo}MI%IDN63cjIUSger^-1OJcz<3k1szwQ&kv=zvc_LcbU5P zaz&+@3OV8rVL_s`2<$JCG>+N8${ny~Ss(N?oB(#W;V2C$SQ9d=kAZ?V_IPLSs(}Cp zc32Qx3ZNPK|6!DClTrqieUs~>ML$H)vMn1QHVoZvQG$T{J%(G4O4U}+A6%}$xF zx?ED{7z6q(TI-Y^m>Tl>9rYtCixg6S8UlC08{mbLMzPwp`RBdMBqns}$=4z4$h!TA z$?4OmhK>MSJ3@OwrIE1$L2pue`Mk7thCm9+s}`TRH&&pL2Hz8}_Fa^qA8p<1cY_J+ zuTTtNkjA6&cQ2r3ja~~H9&r_Zw1}3$ z+EP~afPiLy-y<@l95Ljkr;LewYU4$&Mvj{rT_~EAc@UfQxOA|SR`R8*pr-q^zd2-D zx*p<$0=E{5LLr@a2d&tYWOl0UZRlic545d4PQ@?GPPrpWx3|vnAQZKN72rKmyCDwu zkwuoSQC{Dz-NetMKj7O7#=K>GNEZanv51FsZVH2oG~Q|IEPOxr9!h66J!(4GBi#^E z+guJbQcIQ^%Ff|CkX|OB{QLo~p;HTJRex_`yh?9x4U5Bl8^7;v#)f?%grSquSofRs z@Kec&3}Xm*UYoPJ2l@=@G=Kc)H`BQSudR>Pn#CcBDaj)|}7adffoR6+N$pbO1 zGhtvg^P8&kQDq%2xPDp7dgy#=sN!wKLaTZf=qV717h=L4=Mf=7Q$YJbHAyj=pbcTT z)`f&n{CLPSjNLHIOGlTd-Qjv#68C~u&a_wSzpvVwpp@&cWire(rX})1Xj)Rk>OXi? z>fCY@P&zUY2_fPsuoyNCE%)MR;!x(^WQ#`mk7nQzcCL}+|5+m0odAUFE zR5HtK7SG_2boNbQx%t4YVW!rv(hLim^@a$_vjzobd@<`7gcJci)93=c-7jpVB;5tX ze&%5fu1l_hT~yu`Ah0lzw(2<|sy|Hk6VLTn9+;>JpZdYdUjYZFGQu(d- zCwrp^%HKR83&X7xRk%NyVRJ%lVLzG)sur#;nFY^VAmDB_9$csKvLdvr+%D+sXXdzD z)D@+cYwlC*?t2J39cx|ezJ^!??`o><$7CKzf9tTa7Xr_|>?_WeLs#74J0Rk|7XtdD zL2+^dl1Z@pV>v;vo(yeA(yjqkWh9$BKic;&ib+Ez?7LDBm0eUux$$6SBAFjj>;kUu53eD8o%d*O1RVBi z^9EDaoWS*#^z{~&;D?X#nlqehdqy5p)}Dt~rWiGrm^Ju%dS*Y27??2qpgoKn+#zyHnYH`9|_)VEzVC6E~y z2iKD0^^{rf9|d{oM!vM(@(6Fz_`^Dd^Bxaae*zJmU=0kL38~&gj}dMq8vAfH&$?TG z0cXw%3|&|M4VC1&Hl!85pAlh`fb<8BJ6zVrC&n@;KTgmjAm2<}Q!9ynT_FW+^y>$t z!IpshGKqg(TP7Q0t63=l+mx|=5#!<;bDRcElxRT0Dl~+*O)H6jW5voXHYKd1JYD)B z2&TJ{ZRN%R@PEUme%RR7z6n`x-MoDQ?ImWyVG=cOmsda~OI>RQS;Sf2f83NfA^vwMI17;i|DO@sr@AeWD=ZKYLC*BOKM)K+ z9vGvP(UqH@zCYLfV2p>s0_mPnJkY?P10kTp$aZZIry-ddG1Ct>8oJhFeTA%mwf0v( zH(1YvThbm2YPFh->{s%hn#y}^b?djEjdg49`#E>~x($;MBGsRLSsjmiy?^(3v)U>4}e;wct zl)oM;*XEQonTz&8IO97D@r(IhAvw1rm^ojZ8lVp{b}_=eb}2BDY05hCEnZoHn>@4m zXbkwrIF#yskx`8QY9DGnnJDcQFDw|2>UT#peIlcpEEgMUei*}=)i1ad{`8E0c`yv? z_wm&HilZD=?q>M*=s&z^@lNbNI&%dbJr8(qbLE~GzIt>=pDVcbe<}MhMn4K*?9}f= zW!$3I3;wF*eQ_<1A~K8W)>=mbcHXhYRlgV$zD7h5nd>x;kG;4`jK;H0SG>UF-AQBI z9FxyhdBsQNtK8*8p-l@+;m=ij1@866yt1`ltKPBF_@});Kb(Mm@r~!t-JLwt++wMH zkPI_czL;YWxeTLzz&`g^?f+K$;Awu9K#~5-1nis0cWg}9(YWKK@lOv2_LuLI()b&W z5>>p2a!kdmeKbZ1D&LihlYO*f|7FD>QolQye!-&oQW+gn^V6&N^~N`7m*=*p`pb_i zwts)FzVrRxD>Lz4Vx#)aGo1HsAY9JzbuOPjUcrH1n_RbW*?RYe`>*|LqK z9Z2l00Nt#v;9LUeyf(a{vEkN6C%*!Y6a|R`a9$LdEVMf{9(+Y2*fAC!WjD6g_Ao>? z_VzI3Ngkf=;CG)mHp7Kw_mXONqQYYWt8>^^4+5B04^JrGCo~Bl+~1a)D?8rBt(Nv$ zjKY@I>gr@mqSMQBhbt2?NzaDv6DeO+$t8aYItS}5U#IWHvg_+QQi5FlD>9RMbQE9v z6nv0EE|Gh&_u(@ulG)z4+k!k?*yl59RN}=%DM?bw?D)`ReIGF+#E@iaew@W6Yn5mw z9WpnUTPu=P0s&kgY3*tYc@lW5v5AvhJ;7@7NI6Gx+%FsY=5g%O#8opEVYzVBiIzOE zHKhOs9xn9i-m+f%MYUkAytp#Ow(x_!K<&s{Rr-;_J|{i_P7`i-N?KbZoyWpQW)_nK zdXm~DO!BiK=6ioJ(vM`z#?YEYdWI#1w=6xznhT_o%uIjU$h*!Y=6a$D0_j zl1s7BZB+=saOBIGNdKlz(#rBjwxKo=ljbT>lC(@$R}-g*X?(@(z#+TM+TovvRxYTc z-pq|W33Bjf(jGf+RcE@JL1%nE!Q1H^8OU1#{5i8^(nXz2j;mTId<|_R6rV%tS_FEUn<8^{xP`mYoTAUT>}9;3 z_dVpypZ;=0C9S|c!$q7AAFi$88J0^CLOhd6^Vq6IFkN?bnt_H8t25j&UT+lHMA0IpxNckFMBPkdTpw0PAH8 zd0#dS5+0AtLEgf!c<@<vl?D4N{sBe7 zyPjrzn{lep#hH~c3w4a|Ml~(=sS1E*LWvDLMMc}Pv$Nh=w$>DbiVJ0NBS8w`j!q#+ zAJejs%9$e*2OP0@cPPIm;C09dQWpzK=J^P3q_fLLiMkPyCuCH>o=VZ|R@=groA45$ zrhr4)X}E6mNyrwa_3jNj)W?J)81{1k(7lW zr|&P$$Bw#rO#A1JkuC(vsa#HNGS>n3Jj99^dcKrq@w{PFitMVSUDvCqX;w*VvU&$r zc453wjmI{BFK}nrCUv@aed1ReBjg1c_BN!7#Z}|5*`CPOn$hR7zp#IVnTXekU5>I; z-a2hNkI{2R$|}U1FyP>Rpc3Ztlc`9+7~o+&C*tzBuj%-aYI9egGn7iHQrQ97O0^1S z_Hze2$?>(KEgr{(tvVkwnEo|4_-T|;7c#IpN@uRsTA9}QMYC_Nw3Q#Q@vkI9Ju{6 z@nj+DZtTLUiVve+Rfr!7kfoUh9#W!Io zkAk|5y*M8}RYnPHeuU9KiI%7P^BesJDOaxaudoT$IgERI8qa;K{YO}RG_);eh33EHeaofP9Vp&#?RGvk>NLfXP2+?&sqS%sm-93X)XMuTGAUR-P z0?|e$daKLcg5@K3O%_wmkTb{m?EfPu?cC7UGs75QRiTGusF zIJsNgR`_@xAFfpR)yB7&R3j#km2tp^#~4?WVDT?r>_*+>B#!(T za%|b?);BOYX{IX66Zk5V+6}C)g`GX)A6byZ5-;)y3qQ?3)qJzC=&?JlPHV*1zb)UK zJ~<&ED*2=Yb2L_G(z=bTi@4Sz*(&FH8K-)cB4eK(11Zc~aC3p#PT|xIF52CvFR0ztF13{0DRuZd)HAaR;3goaq{xT%sE5)kVam%3 zxC18n_~g|Zorx11k?hm`0eP?NBx*_!rSVTKF7%n>nGs?mORd%Ce~t^hmX(VupPcT0 z!IO(?vXL7AV)ePq`yr1TX6}LWO5$0tF1tW1pKL@Ixu)<5QrQXLC5ywn_jH_~S-wKH ztbJ9Ivgi|*Kd9tm6l2wxvN;WI)t26>nM2z+@;HIoc5EZMsSQ~;J!C=~B^WKsWZwAd zGcz@HOC6`{nnRvOP(S>zG(^b#kO&K(ovkAv zur+*f&& zO}OJ!2}ZcYB>dvf&^VENU%s~nJq9bV*NTI*^=R7yTO9MsG< z=*vi_wkxc~1{z(dOWZ9>VMOgtYyO)PbgH6T&qWo2vru%PS%gG0OSXpWkOmmplF4ds zB76_3uEm5jSqSd4#}o83A%JYqxC6mJ6nUQ5Ph2~##idBrCbe+Q=-g_cnFr2RV%O>i zoNZ@sTmQm|wxkn0CZMCyA42AHB~0O9e)mBwGg$pqc-0BtPhbv`x#PzG0xsRL@Tw-Z zM-mearnGUDG&aW_?3_!|&>T=Lb%^ePzZyPd5_-dp(19+EuMIhFk0&`?rcQbG5GMzG zBlEqWXAF}IDG;j6sVRAQW?o0ekE`XlF?JnX!U`wRSQ0@thCCI5t1!lh$ipa@01v;7 zr@gi=L!)X|L_Sv{)?9mSO-V)B1<~e0hE^s*@ro<2b*ZG3t;)h!br{H3|6VLH--{Ci zL~rB;X$rBe$?!z76F`VHut%T#l$A!COLKPeVi=~gWB0PVX!zav$*x_2H_Fj32)A*S zA4jGv;HV48+AviwoMgu{IKcYtNmwPY=}%&b?(g;aVebzjpQt^C9=2bI4;x z1SY`$+H;<0djj0PK>#C>&ANUq&5yW|%@JO>g*VUY@7?Mt2;hb4R<4lgjD6P zmj=G;Z>kMR168UN>b$D%a>eK9Y6iUQNXy(ki1nZ7eo0C?m~|FHFAVjf+yKg+xF+{< zBj&)?awCC2eV~~%*zefDbW0ikc1vP5MB(}aFt_;mG&U~+K0d^a4+BX|#8{zL6qG75%?J*Ci4n5^Nxvx!lnfH zi2&r?p+op&lP$Ojl|Wf|Z98CLjEdZ?G%EsEuYv-&09Xnn<{Q6tc&4!LrK+k>*(|w7 z66-*=eCrB^w>l$0nm-!YQ(h;96P$G(u<0bGcJkEKt1$RHqSp7sng%bzrvDYtP6anS z4ZKg8nQ8Q4xfwUf+f$!fjoq6Ov86G7B6w=z%VbW}WRr-D_$M{CBr;E!D6aNS;l`Qj z3o%z!pzb}GG-jRN#JCQBQS+-zJm^ivR_ow?$@o+-cB>vSQo-R^E*9Q z!?NmVj&sKKn{U!nIP?zu%y(vFb?%0^2D-*{uZ*z6ZjRwRyP&np>`J_t8SNP`53%&R zB+0#~xIVTiuU)ssN0gMrfRu-n=4pBx;8eOhzyDliLVEq^YjD$Y z{^#I_cNw8DMRiio$7-wzBG!p0Kb#}7?@6b-%Pn_4&Jk#)I@f4^OP*1)UB&qTw-@Q> zwpc%>BUIOY`ffEJY*A z+VR9%@5c;U%=Tc6lK?5ER%b6Okg4TXdnVHo0d$g2VD|Qbwvq~AjR}1h^{i&+fgvX+ zK&=X5tu79h5@+>-3*gvZ0xjW@d8u#k8{oxBf8n0FB6(MGUK~g%#|^gn3hZUr^PqX$ zCWS-P41~x*GrHWr_~&oN$<^6eJDg!gag3rtD&!tks0rHt;*`lp-{*ioa2ufK=t-_S zp*kV4_>re8seO$C+ z)^qDohswPTv4LF!0k=WyW>rrfeRIxP?^A7<`E|(_<=b>Z6=C;H956aQ6JK-hJjZPk zeo1GgJ^i(?y>`|gNS~-D=YN}ggJcnMH2-IdZzD`R7 zBueKuK}Qfn5{xeC(7>WH-hz~YKBS=N80+@NeNrbpW_L|IW#e@Wa*gTlN#9X&Z{Mq8 ztQ-9BCI7h$XR&@qiQEj&PqXbYgNRMQsb%_=zjE+)V)w@t8|y&s{ynANpm`w42>GC( zly5>DT31X;C*y#A$g%BYxJ1E$0N2*A>+E31=i9^W9wd}JJ+RKHfl<(=Q0Qp z>p&)*-$%pF1IzO>%p z=&!W+XuG>)z#y(VFLcIDe)`N8<{#}BenQTaE_A&h&-sbnoo|c7?0|40rf^P7eE)g; zI(n`TZdWf=hYmGFS`Jq`R?MkJ7w=*>0AK!G&`wSRVCo1$25NtF^7wUV%jK43lcsst z`Ol?Y0^YRgkfVVE!vL0~apTSdxi@eegLZ!zSy=MK9HA`nVGq1AplFE?sFu?1W8?PD-1KEVUqzVy}_ zNcZkzqu#B}bA)+unQI61i1%UA!kt}E96R4CL+^is|Gy>#=Rb&VT4*&2;8!0AV`* zpMOZ`cu)W$kW9(N+TL8j-QL99Mb+Hd-Q2;{T+-aZ+{M_<(dEBb&)g+hD?M{;$laTF zOBTx{xukFTtg=pao8+wMt7U_lR_Rs>c7hEHm&#hxn!jc)aum6;Ea@CNtx-`C9mpuo zdqoj$#3Zd&12!X}5kVbJdyAnFQdlGmdJ*Z*oIr~`iIKnufs-es@Mpi1hn*cmjKmJN zl?cjJwB-mCU3wI2H(&WYHs8f6RGfS{d|tLvlQJ|u-04HsBXF9+?LIV`y}cp30+W*< zKc&a1LA3@on0xEIs`Ffh4&I{Rvr9u+6BW|d9``}Pi!s_GISzrd6HBCjCFF)f+Ty5-U5kJ|Q6iX96Fm;`kei9$; zO-34bmG9@HT$ND(iEe$Abgk5>mDOny+p}j6=^m&<^^Nq()8Uc?@0%v$m$UuPpTloE z;jpM4s@9vHi>fU5%wlNZJ{`=xzjcqqrjR* z{%M_!v6yvGi`-b&iz`Bl;H|k9j|dpvX}gxkh8dh}|QXEm#@Z#EOXw{uylTlY(TnbcN*x|nMcM|!;<^+Ao z5e9sTD2M_{k%rXJh{9AYEsZthhYI7!zHY9GcRM z8Ir<{_4wlldZcHEJG6b!k45jXW3uzcjP=m4jQSJ|5^w*El`jt29dh;w^O%vgLqBs! zZ{+{Kxbc6Rml}NCvFQJP|EPblg9iiz#L>l)(b&n@)GD378i4x0;Q$?&t0wEZq=7Eb zR7a?Rt}ETa1}3_QSz(%t4PQ}9tTYBe;$$Zj2Btj{h0=&4sG@zA!f^TvSftO+D%U&_ zh65%Cl~Fed-(A;bm;MQ=KgO@w#Cpt}t8g&E|BV0h5^+WP8$&4{NcIf@QZRt~*TwlG3 zCTcR=?U;RCGx@b=F&?~^SfT;Z{86q2^agY3)3n~MUsr=wW2)(<6Zc zBh1sgJb}cQJhU7^w03BL%)f2ebmZM4P4zJ1hS=gR`1LEDAOw_&5#QA_OvYfOOcfmu z)VKgksOah)V46E#gem1gpi4AlKPrdV8`QX9tTALRJqVb9-{rTNu!ckOFb>X6O-FTQ zm+ajt?kYQ64x`rPHnFWf=W(8t?tN}wMYf!{ZN8`War&Qv4&h(9VZpJRj=l=u;nv-C zKl>MTy61#RzOF~6pEEwTCI&Y@>BrW)M!J^t{yGVol-hJ_Gp

HrGL7aD7HOmEVyI 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�>F}Hq{uDY0qI~K4N-~vA<2lzEkj83^G`ogy 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%0D0-n%Vv_s+wNSudD&e+k3CUa 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%0DCLEV7N@dKqHg18x-kwLl>dX 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

#>TWXa^Kl$pEG-D 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±p5Zm1D91?7c3uSBT$O{*9Ai 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�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

^o^lRer0wI#7S*P}W0v&Yz+cu!*zVDZ3| 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 z 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 KQL)Zy{Of=3hbE!` From 204d5fff8c27af5b025b1c5ee3179240d68b8ea5 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Tue, 4 Dec 2018 12:59:41 -0500 Subject: [PATCH 158/176] Update the CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cffc90942e..9c665cfb7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ ## Dependencies * [MRI] Upgrade mini_portile2 dependency from `~> 2.3.0` to `~> 2.4.0` - +* [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 # 1.8.5 / 2018-10-04 From b7d3aed766132c7ef67acb2006e18db8c771c892 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 4 Dec 2018 16:58:19 -0500 Subject: [PATCH 159/176] update CHANGELOG related to #1831 --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c665cfb7f..f674775a58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # next / unreleased +## Security Notes + +* [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 to address upstream vulnerability CVE-2012-0881 [#1831] (Thanks @grajagandev for reporting.) + + ## Features * `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] @@ -22,7 +27,7 @@ ## Dependencies * [MRI] Upgrade mini_portile2 dependency from `~> 2.3.0` to `~> 2.4.0` -* [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 + # 1.8.5 / 2018-10-04 From a3e7c20b084cba37b242674fa06055b1a8bccc85 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 21:08:10 -0500 Subject: [PATCH 160/176] add test coverage for Node#dup because I'm about to add some behavior --- test/xml/test_node.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index 107fc5d7cc..b83fefc2ed 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -165,6 +165,29 @@ def test_parse_with_unparented_html_fragment_text_context_node assert_equal x.first.name, "span" end + def test_dup_is_deep_copy_by_default + doc = XML::Document.parse "

" + div = doc.at_css "div" + node = div.dup + assert_equal 1, node.children.length + assert_equal "

hello

", node.children.first.to_html + end + + def test_dup_deep_copy + doc = XML::Document.parse "

hello

" + div = doc.at_css "div" + node = div.dup(1) + assert_equal 1, node.children.length + assert_equal "

hello

", node.children.first.to_html + end + + def test_dup_shallow_copy + doc = XML::Document.parse "

hello

" + div = doc.at_css "div" + node = div.dup(0) + assert_equal 0, node.children.length + end + def test_subclass_dup subclass = Class.new(Nokogiri::XML::Node) node = subclass.new('foo', @xml).dup From b92660e66785f5a6411434ec39423350e2bd84b6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 22:56:52 -0500 Subject: [PATCH 161/176] Node#dup can now copy directly to another document This is an optimization of what's usually done, which is to make a document-local duplicate via `#dup` followed by an `#add_child` or similar. The drawback in that scheme, of course, is that unparented nodes cannot be GCed and so occupy memory while the document is still accessible. Using this new variation of `#dup` we can create a duplicate in the other document directly, without a direct clone. --- CHANGELOG.md | 1 + ext/nokogiri/xml_node.c | 33 +++++++++++++++++++++++++-------- test/xml/test_node.rb | 13 +++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f674775a58..ddf90bbf5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,7 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) * [MRI] Cross-built Windows gems now support Ruby 2.5 +* Node#dup supports copying a node directly to a new document. See the method documentation for details. ## Bug fixes diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c index 91e0351e86..8c637c1b6b 100644 --- a/ext/nokogiri/xml_node.c +++ b/ext/nokogiri/xml_node.c @@ -113,7 +113,7 @@ static void relink_namespace(xmlNodePtr reparented) && ns != reparented->ns && xmlStrEqual(ns->prefix, reparented->ns->prefix) && xmlStrEqual(ns->href, reparented->ns->href) - ) { + ) { xmlSetNs(reparented, ns); } } @@ -532,22 +532,39 @@ static VALUE internal_subset(VALUE self) /* * call-seq: * dup + * dup(depth) + * dup(depth, new_parent_doc) * - * Copy this node. An optional depth may be passed in, but it defaults - * to a deep copy. 0 is a shallow copy, 1 is a deep copy. + * Copy this node. + * An optional depth may be passed in. 0 is a shallow copy, 1 (the default) is a deep copy. + * An optional new_parent_doc may also be passed in, which will be the new + * node's parent document. Defaults to the current node's document. + * current document. */ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self) { - VALUE level; + VALUE r_level, r_new_parent_doc; + int level; + int n_args; + xmlDocPtr new_parent_doc; xmlNodePtr node, dup; - if(rb_scan_args(argc, argv, "01", &level) == 0) { - level = INT2NUM((long)1); + Data_Get_Struct(self, xmlNode, node); + + n_args = rb_scan_args(argc, argv, "02", &r_level, &r_new_parent_doc); + + if (n_args < 1) { + r_level = INT2NUM((long)1); } + level = (int)NUM2INT(r_level); - Data_Get_Struct(self, xmlNode, node); + if (n_args < 2) { + new_parent_doc = node->doc; + } else { + Data_Get_Struct(r_new_parent_doc, xmlDoc, new_parent_doc); + } - dup = xmlDocCopyNode(node, node->doc, (int)NUM2INT(level)); + dup = xmlDocCopyNode(node, new_parent_doc, level); if(dup == NULL) { return Qnil; } nokogiri_root_node(dup); diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index b83fefc2ed..447c14c85d 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -188,6 +188,19 @@ def test_dup_shallow_copy assert_equal 0, node.children.length end + def test_dup_to_another_document + doc1 = HTML::Document.parse "

hello

" + doc2 = HTML::Document.parse "
" + + div = doc1.at_css "div" + duplicate_div = div.dup(1, doc2) + + assert_not_nil doc1.at_css("div") + assert_equal doc2, duplicate_div.document + assert_equal 1, duplicate_div.children.length + assert_equal "

hello

", duplicate_div.children.first.to_html + end + def test_subclass_dup subclass = Class.new(Nokogiri::XML::Node) node = subclass.new('foo', @xml).dup From f2f3a3bf2cb36865c681b51418dbf7957f00a1c9 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 28 Jan 2018 23:59:33 -0500 Subject: [PATCH 162/176] DocumentFragment#dup avoids unnecessary copies. [fixes #1063] --- CHANGELOG.md | 1 + lib/nokogiri/xml/document_fragment.rb | 9 +++++++++ test/xml/test_document_fragment.rb | 14 ++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddf90bbf5a..d754bc634a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,6 +109,7 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) * [MRI] Cross-built Windows gems now support Ruby 2.5 * Node#dup supports copying a node directly to a new document. See the method documentation for details. +* [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063] ## Bug fixes diff --git a/lib/nokogiri/xml/document_fragment.rb b/lib/nokogiri/xml/document_fragment.rb index c2c5bec735..57c266179d 100644 --- a/lib/nokogiri/xml/document_fragment.rb +++ b/lib/nokogiri/xml/document_fragment.rb @@ -25,6 +25,15 @@ def initialize document, tags = nil, ctx = nil children.each { |child| child.parent = self } end + def dup + new_document = document.dup + new_fragment = XML::DocumentFragment.new(new_document) + children.each do |child| + child.dup(1, new_document).parent = new_fragment + end + new_fragment + end + ### # return the name for DocumentFragment def name diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index c919ee2068..3ff801e847 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -263,6 +263,20 @@ def test_issue_1077_parsing_of_frozen_strings Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised end + def test_dup_creates_tree_with_identical_structure + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_equal original.to_html, duplicate.to_html + end + + def test_dup_creates_mutable_tree + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + duplicate.at_css("div").add_child("hello there") + assert_nil original.at_css("b") + assert_not_nil duplicate.at_css("b") + end + if Nokogiri.uses_libxml? def test_for_libxml_in_context_fragment_parsing_bug_workaround 10.times do From 26295d25945270ac81f2a8f1c1d22c9a9f94e692 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 3 Dec 2018 23:36:37 -0500 Subject: [PATCH 163/176] jruby: skip implementation of DocFrag#dup new-document param because I don't have good evidence of high memory usage in the JRuby implementation. --- lib/nokogiri/xml/document_fragment.rb | 14 ++++++++------ test/xml/test_node.rb | 20 +++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/nokogiri/xml/document_fragment.rb b/lib/nokogiri/xml/document_fragment.rb index 57c266179d..cfa826b421 100644 --- a/lib/nokogiri/xml/document_fragment.rb +++ b/lib/nokogiri/xml/document_fragment.rb @@ -25,13 +25,15 @@ def initialize document, tags = nil, ctx = nil children.each { |child| child.parent = self } end - def dup - new_document = document.dup - new_fragment = XML::DocumentFragment.new(new_document) - children.each do |child| - child.dup(1, new_document).parent = new_fragment + if Nokogiri.uses_libxml? + def dup + new_document = document.dup + new_fragment = XML::DocumentFragment.new(new_document) + children.each do |child| + child.dup(1, new_document).parent = new_fragment + end + new_fragment end - new_fragment end ### diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb index 447c14c85d..4cd82924bc 100644 --- a/test/xml/test_node.rb +++ b/test/xml/test_node.rb @@ -188,17 +188,19 @@ def test_dup_shallow_copy assert_equal 0, node.children.length end - def test_dup_to_another_document - doc1 = HTML::Document.parse "

hello

" - doc2 = HTML::Document.parse "
" + if Nokogiri.uses_libxml? + def test_dup_to_another_document + doc1 = HTML::Document.parse "

hello

" + doc2 = HTML::Document.parse "
" - div = doc1.at_css "div" - duplicate_div = div.dup(1, doc2) + div = doc1.at_css "div" + duplicate_div = div.dup(1, doc2) - assert_not_nil doc1.at_css("div") - assert_equal doc2, duplicate_div.document - assert_equal 1, duplicate_div.children.length - assert_equal "

hello

", duplicate_div.children.first.to_html + assert_not_nil doc1.at_css("div") + assert_equal doc2, duplicate_div.document + assert_equal 1, duplicate_div.children.length + assert_equal "

hello

", duplicate_div.children.first.to_html + end end def test_subclass_dup From 5b69bdd3455f68a3599e85839bbd9ec46cb3c439 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 10 Dec 2018 00:19:22 -0500 Subject: [PATCH 164/176] CHANGELOG: move #1063 notes under next release [skip ci] --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d754bc634a..0bcbb99ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ * `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] * Introduce `XML::Node#wrap` which does what `XML::NodeSet#wrap` has always done, but for a single node. [#1531] (Thanks, @ethirajsrinivasan!) * [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!) +* [MRI] Node#dup supports copying a node directly to a new document. See the method documentation for details. +* [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063] * [JRuby] NodeSet has been rewritten to improve performance! [#1795] @@ -108,8 +110,6 @@ If you're offended by what happened here, I'd kindly ask that you comment on the * [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!) * [MRI] Cross-built Windows gems now support Ruby 2.5 -* Node#dup supports copying a node directly to a new document. See the method documentation for details. -* [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063] ## Bug fixes From ed6afeb56d0acefe9ff9c9c09e5734c8e6d03f99 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 10 Dec 2018 00:28:09 -0500 Subject: [PATCH 165/176] update CHANGELOG for #1820 [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f674775a58..692cbd3983 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] * [MRI] Address a memory leak when unparenting a DTD. [#1784] (Thanks, @stevecheckoway!) * [MRI] Decrease large memory usage when making nested XPath queries. [#1749] +* [MRI] Use RbConfig::CONFIG instead of ::MAKEFILE_CONFIG to fix installations that use Makefile macros. [#1820] (Thanks, @nobu!) * [JRuby] Fix failing tests on JRuby 9.2.x * [JRuby] Fix default namespaces in nodes reparented into a different document [#1774] * [JRuby] Fix support for Java 9. [#1759] (Thanks, @Taywee!) From d4c546d0ca6b980bd7093c76dda97817f8fe7ee0 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 10 Dec 2018 00:43:03 -0500 Subject: [PATCH 166/176] version bump to v1.9.0.rc1 [skip ci] --- CHANGELOG.md | 2 +- lib/nokogiri/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc7a66a9f..d8936153a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# next / unreleased +# 1.9.0.rc1 / 2018-12-10 ## Security Notes diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index f00a62d87d..d421318ebe 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.8.5' + VERSION = '1.9.0.rc1' class VersionInfo # :nodoc: def jruby? From dfb25f34cbab09fd63cbf0ea0db4b804e55c6200 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 10 Dec 2018 01:07:34 -0500 Subject: [PATCH 167/176] make `build_all` more robust [skip ci] --- build_all | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build_all b/build_all index 8b983d3829..ffd60e4e04 100755 --- a/build_all +++ b/build_all @@ -17,6 +17,10 @@ fi set -o errexit +# check that we have the latest jruby +rvm use jruby +rvm use ruby + rm -rf tmp pkg bundle exec rake clean clobber @@ -37,7 +41,7 @@ cp -v pkg/nokogiri*.gem gems bundle exec rake clean clobber bundle exec rake generate -rvm jruby +rvm use jruby gem install bundler --conservative bundle install --quiet --local || bundle install bundle exec ruby -S rake gem From 9bb0226b680ef0d248504379be0584ae6f64a49d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 16 Dec 2018 14:27:17 -0500 Subject: [PATCH 168/176] remove hacks preventing jruby from using racc and rexical modern versions of both run fine on jruby, so as dev tools this is fine. also update parser.rb with output from modern racc. --- Gemfile | 4 +- Rakefile | 35 ++--------- lib/nokogiri/css/parser.rb | 122 ++++++++++++++++++------------------- 3 files changed, 68 insertions(+), 93 deletions(-) diff --git a/Gemfile b/Gemfile index d65802f1f5..174fed538a 100644 --- a/Gemfile +++ b/Gemfile @@ -14,8 +14,8 @@ gem "minitest", "~>5.8.4", :group => [:development, :test] gem "rake", "~>12.0", :group => [:development, :test] gem "rake-compiler", "~>1.0.3", :group => [:development, :test] gem "rake-compiler-dock", "~>0.6.2", :group => [:development, :test] -gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] -gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw] +gem "racc", "~>1.4.14", :group => [:development, :test] +gem "rexical", "~>1.0.5", :group => [:development, :test] gem "concourse", "~>0.15", :group => [:development, :test] gem "rdoc", ">=4.0", "<7", :group => [:development, :test] gem "hoe", "~>3.17", :group => [:development, :test] diff --git a/Rakefile b/Rakefile index 074b6a06e6..21b27a17df 100644 --- a/Rakefile +++ b/Rakefile @@ -250,42 +250,17 @@ end desc "Generate css/parser.rb and css/tokenizer.rex" task 'generate' => [GENERATED_PARSER, GENERATED_TOKENIZER] task 'gem:spec' => 'generate' if Rake::Task.task_defined?("gem:spec") - -# This is a big hack to make sure that the racc and rexical -# dependencies in the Gemfile are constrainted to ruby platforms -# (i.e. MRI and Rubinius). There's no way to do that through hoe, -# and any solution will require changing hoe and hoe-bundler. -old_gemfile_task = Rake::Task['bundler:gemfile'] rescue nil -task 'bundler:gemfile' do - old_gemfile_task.invoke if old_gemfile_task - - lines = File.open('Gemfile', 'r') { |f| f.readlines }.map do |line| - line =~ /racc|rexical/ ? "#{line.strip}, :platform => [:ruby, :mingw, :x64_mingw]" : line - end - File.open('Gemfile', 'w') { |f| lines.each { |line| f.puts line } } +[:compile, :check_manifest].each do |task_name| + Rake::Task[task_name].prerequisites << GENERATED_PARSER + Rake::Task[task_name].prerequisites << GENERATED_TOKENIZER end file GENERATED_PARSER => "lib/nokogiri/css/parser.y" do |t| - if java? - warn "WARNING: #{GENERATED_PARSER} may be out of date:" - sh "ls -lt #{t.name} #{t.prerequisites.first}" - else - sh "racc -l -o #{t.name} #{t.prerequisites.first}" - end + sh "racc -l -o #{t.name} #{t.prerequisites.first}" end file GENERATED_TOKENIZER => "lib/nokogiri/css/tokenizer.rex" do |t| - if java? - warn "WARNING: #{GENERATED_TOKENIZER} may be out of date:" - sh "ls -lt #{t.name} #{t.prerequisites.first}" - else - sh "rex --independent -o #{t.name} #{t.prerequisites.first}" - end -end - -[:compile, :check_manifest].each do |task_name| - Rake::Task[task_name].prerequisites << GENERATED_PARSER - Rake::Task[task_name].prerequisites << GENERATED_TOKENIZER + sh "rex --independent -o #{t.name} #{t.prerequisites.first}" end # ---------------------------------------- diff --git a/lib/nokogiri/css/parser.rb b/lib/nokogiri/css/parser.rb index 594584410f..ed6ae82364 100644 --- a/lib/nokogiri/css/parser.rb +++ b/lib/nokogiri/css/parser.rb @@ -31,64 +31,64 @@ def unescape_css_string(str) racc_action_table = [ 24, 93, 56, 57, 33, 55, 94, 23, 24, 22, - 12, 93, 33, 27, 89, 52, 92, 22, -23, 25, - 109, 98, 23, 33, 26, 18, 20, 25, 27, -23, + 12, 93, 33, 27, 35, 52, 44, 22, -23, 25, + 45, 98, 23, 33, 26, 18, 20, 25, 27, -23, 23, 24, 26, 18, 20, 33, 27, 11, 39, 24, - 22, 23, 95, 33, 18, 91, 90, 27, 22, 12, - 25, 90, 96, 23, 33, 26, 18, 20, 25, 27, - -23, 23, 24, 26, 18, 20, 33, 27, 74, 39, - 99, 22, 23, 45, 24, 18, 33, 103, 27, 56, - 87, 25, 60, 46, 23, 49, 26, 18, 20, 104, - 27, 39, 24, 51, 23, 93, 44, 18, 26, 33, - 27, 66, 106, 56, 58, 110, 60, 33, 85, 33, - 86, 51, 56, 87, 39, 60, 26, 23, 88, 33, - 18, 20, 39, 27, 39, 23, 35, 23, 18, 33, - 18, 27, nil, 27, 39, nil, 33, 23, nil, nil, - 18, 22, nil, 27, 39, 101, 100, 23, 102, nil, - 18, 39, nil, 27, 23, 82, 83, 18, 20, nil, - 27, nil, nil, nil, 82, 83, 78, 79, 80, nil, - 81, nil, nil, nil, 77, 78, 79, 80, nil, 81, - 4, 5, 43, 77, 4, 5, 10, nil, 56, 87, - 6, 60, 8, 7, 6, nil, 8, 7, 4, 5, - 10, 56, 87, nil, 60, nil, nil, nil, 6, nil, - 8, 7 ] + 22, 23, 74, 33, 18, 91, 90, 27, 22, 12, + 25, 24, -23, 23, 85, 26, 18, 20, 25, 27, + 66, 23, 24, 26, 18, 20, 33, 27, 86, 88, + 51, 22, 89, 92, 24, 26, 56, 87, 95, 60, + 90, 25, 96, 46, 23, 49, 26, 18, 20, 99, + 27, 33, 33, 51, 103, 104, 56, 58, 26, 60, + 93, 106, 33, 33, 33, 109, 39, 39, 110, 23, + 23, nil, 18, 18, 20, 27, 27, 39, 39, 39, + 23, 23, 23, 18, 18, 18, 27, 27, 27, 33, + 33, 101, 100, nil, 102, 22, 56, 87, nil, 60, + 33, nil, nil, nil, 39, 39, nil, 23, 23, nil, + 18, 18, 20, 27, 27, 39, 82, 83, 23, 56, + 87, 18, 60, nil, 27, 82, 83, 78, 79, 80, + nil, 81, nil, nil, nil, 77, 78, 79, 80, nil, + 81, 4, 5, 10, 77, 4, 5, 43, nil, 56, + 87, 6, 60, 8, 7, 6, nil, 8, 7, 4, + 5, 10, nil, nil, nil, nil, nil, nil, nil, 6, + nil, 8, 7 ] racc_action_check = [ - 3, 58, 24, 24, 3, 24, 57, 15, 42, 3, - 64, 57, 42, 15, 54, 24, 56, 42, 58, 3, - 94, 64, 3, 31, 3, 3, 3, 42, 3, 22, - 42, 9, 42, 42, 42, 9, 42, 1, 31, 43, - 9, 31, 59, 43, 31, 55, 55, 31, 43, 1, - 9, 60, 61, 9, 30, 9, 9, 9, 43, 9, - 46, 43, 12, 43, 43, 43, 12, 43, 45, 30, - 75, 12, 30, 21, 23, 30, 29, 84, 30, 93, - 93, 12, 93, 23, 12, 23, 12, 12, 12, 86, - 12, 29, 27, 23, 29, 87, 18, 29, 23, 25, - 29, 27, 91, 25, 25, 106, 25, 28, 49, 62, - 50, 27, 51, 51, 25, 51, 27, 25, 53, 14, - 25, 25, 28, 25, 62, 28, 11, 62, 28, 32, - 62, 28, nil, 62, 14, nil, 39, 14, nil, nil, - 14, 39, nil, 14, 32, 76, 76, 32, 76, nil, - 32, 39, nil, 32, 39, 47, 47, 39, 39, nil, - 39, nil, nil, nil, 48, 48, 47, 47, 47, nil, - 47, nil, nil, nil, 47, 48, 48, 48, nil, 48, - 17, 17, 17, 48, 0, 0, 0, nil, 90, 90, - 17, 90, 17, 17, 0, nil, 0, 0, 26, 26, - 26, 92, 92, nil, 92, nil, nil, nil, 26, nil, - 26, 26 ] + 3, 58, 24, 24, 3, 24, 57, 15, 9, 3, + 64, 57, 9, 15, 11, 24, 18, 9, 58, 3, + 21, 64, 3, 14, 3, 3, 3, 9, 3, 22, + 9, 12, 9, 9, 9, 12, 9, 1, 14, 42, + 12, 14, 45, 42, 14, 55, 55, 14, 42, 1, + 12, 27, 46, 12, 49, 12, 12, 12, 42, 12, + 27, 42, 43, 42, 42, 42, 43, 42, 50, 53, + 27, 43, 54, 56, 23, 27, 51, 51, 59, 51, + 60, 43, 61, 23, 43, 23, 43, 43, 43, 75, + 43, 28, 25, 23, 84, 86, 25, 25, 23, 25, + 87, 91, 29, 30, 31, 94, 28, 25, 106, 28, + 25, nil, 28, 25, 25, 28, 25, 29, 30, 31, + 29, 30, 31, 29, 30, 31, 29, 30, 31, 32, + 39, 76, 76, nil, 76, 39, 90, 90, nil, 90, + 62, nil, nil, nil, 32, 39, nil, 32, 39, nil, + 32, 39, 39, 32, 39, 62, 47, 47, 62, 92, + 92, 62, 92, nil, 62, 48, 48, 47, 47, 47, + nil, 47, nil, nil, nil, 47, 48, 48, 48, nil, + 48, 0, 0, 0, 48, 17, 17, 17, nil, 93, + 93, 0, 93, 0, 0, 17, nil, 17, 17, 26, + 26, 26, nil, nil, nil, nil, nil, nil, nil, 26, + nil, 26, 26 ] racc_action_pointer = [ - 177, 37, nil, -2, nil, nil, nil, nil, nil, 29, - nil, 126, 60, nil, 113, -17, nil, 173, 85, nil, - nil, 44, 0, 72, -8, 93, 191, 90, 101, 70, - 48, 17, 123, nil, nil, nil, nil, nil, nil, 130, - nil, nil, 6, 37, nil, 57, 31, 152, 161, 83, - 81, 102, nil, 95, -9, 34, 4, -1, -11, 19, - 39, 29, 103, nil, -2, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 45, 135, nil, nil, nil, - nil, nil, nil, nil, 52, nil, 78, 83, nil, nil, - 178, 95, 191, 69, 7, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 92, nil, nil, nil, + 174, 37, nil, -2, nil, nil, nil, nil, nil, 6, + nil, 14, 29, nil, 17, -17, nil, 178, 5, nil, + nil, -9, 0, 72, -8, 86, 192, 49, 85, 96, + 97, 98, 123, nil, nil, nil, nil, nil, nil, 124, + nil, nil, 37, 60, nil, 31, 23, 153, 162, 29, + 39, 66, nil, 46, 49, 34, 61, -1, -11, 55, + 68, 59, 134, nil, -2, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 121, nil, nil, nil, + nil, nil, nil, nil, 69, nil, 84, 88, nil, nil, + 126, 94, 149, 179, 92, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 95, nil, nil, nil, nil ] racc_action_default = [ @@ -106,26 +106,26 @@ def unescape_css_string(str) -41 ] racc_goto_table = [ - 53, 38, 13, 1, 54, 48, 62, 42, 34, 65, - 37, 36, 63, 75, 84, 67, 68, 69, 70, 71, - 62, 40, 41, 50, 47, nil, 63, nil, nil, 64, + 53, 38, 13, 1, 42, 48, 62, 37, 34, 65, + 40, 36, 63, 75, 84, 67, 68, 69, 70, 71, + 62, 41, 50, 47, 54, nil, 63, nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 72, 73, nil, nil, nil, nil, nil, nil, 97, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 105, nil, 107, 108 ] racc_goto_check = [ - 18, 12, 2, 1, 19, 9, 7, 5, 2, 9, - 8, 2, 12, 17, 17, 12, 12, 12, 12, 12, - 7, 10, 11, 15, 16, nil, 12, nil, nil, 1, + 18, 12, 2, 1, 5, 9, 7, 8, 2, 9, + 10, 2, 12, 17, 17, 12, 12, 12, 12, 12, + 7, 11, 15, 16, 19, nil, 12, nil, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 2, 2, nil, nil, nil, nil, nil, nil, 12, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, 18, 18 ] racc_goto_pointer = [ - nil, 3, -1, nil, nil, -10, nil, -19, -4, -18, - 6, 7, -13, nil, nil, 0, 1, -34, -24, -20, + nil, 3, -1, nil, nil, -13, nil, -19, -7, -18, + -5, 6, -13, nil, nil, -1, 0, -34, -24, 0, nil, nil, nil, nil ] racc_goto_default = [ From b61b34c1815d7e05b4bfb5a16c6570073f393ccd Mon Sep 17 00:00:00 2001 From: Stephen Crosby Date: Mon, 5 Feb 2018 21:58:24 -0800 Subject: [PATCH 169/176] Make builds minimal --- Manifest.txt | 130 --------------------------------------------------- Rakefile | 3 +- 2 files changed, 1 insertion(+), 132 deletions(-) diff --git a/Manifest.txt b/Manifest.txt index f731e2e690..7a97d815bd 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -1,25 +1,7 @@ -.autotest -.cross_rubies -.editorconfig -.gemtest -.travis.yml -CHANGELOG.md -CONTRIBUTING.md -C_CODING_STYLE.rdoc -Gemfile -Gemfile-libxml-ruby LICENSE-DEPENDENCIES.md LICENSE.md -Manifest.txt README.md -ROADMAP.md -Rakefile -SECURITY.md -STANDARD_RESPONSES.md -Y_U_NO_GEMSPEC.md -appveyor.yml bin/nokogiri -build_all dependencies.yml ext/java/nokogiri/EncodingHandler.java ext/java/nokogiri/HtmlDocument.java @@ -257,115 +239,3 @@ patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch patches/sort-patches-by-date suppressions/README.txt suppressions/nokogiri_ruby-2.supp -tasks/test.rb -test/css/test_nthiness.rb -test/css/test_parser.rb -test/css/test_tokenizer.rb -test/css/test_xpath_visitor.rb -test/decorators/test_slop.rb -test/files/2ch.html -test/files/GH_1042.html -test/files/address_book.rlx -test/files/address_book.xml -test/files/atom.xml -test/files/bar/bar.xsd -test/files/bogus.xml -test/files/dont_hurt_em_why.xml -test/files/encoding.html -test/files/encoding.xhtml -test/files/exslt.xml -test/files/exslt.xslt -test/files/foo/foo.xsd -test/files/metacharset.html -test/files/namespace_pressure_test.xml -test/files/noencoding.html -test/files/po.xml -test/files/po.xsd -test/files/saml/saml20assertion_schema.xsd -test/files/saml/saml20protocol_schema.xsd -test/files/saml/xenc_schema.xsd -test/files/saml/xmldsig_schema.xsd -test/files/shift_jis.html -test/files/shift_jis.xml -test/files/shift_jis_no_charset.html -test/files/slow-xpath.xml -test/files/snuggles.xml -test/files/staff.dtd -test/files/staff.xml -test/files/staff.xslt -test/files/test_document_url/bar.xml -test/files/test_document_url/document.dtd -test/files/test_document_url/document.xml -test/files/tlm.html -test/files/to_be_xincluded.xml -test/files/valid_bar.xml -test/files/xinclude.xml -test/helper.rb -test/html/sax/test_parser.rb -test/html/sax/test_parser_context.rb -test/html/sax/test_parser_text.rb -test/html/sax/test_push_parser.rb -test/html/test_attributes.rb -test/html/test_builder.rb -test/html/test_document.rb -test/html/test_document_encoding.rb -test/html/test_document_fragment.rb -test/html/test_element_description.rb -test/html/test_named_characters.rb -test/html/test_node.rb -test/html/test_node_encoding.rb -test/namespaces/test_additional_namespaces_in_builder_doc.rb -test/namespaces/test_namespaces_aliased_default.rb -test/namespaces/test_namespaces_in_builder_doc.rb -test/namespaces/test_namespaces_in_cloned_doc.rb -test/namespaces/test_namespaces_in_created_doc.rb -test/namespaces/test_namespaces_in_parsed_doc.rb -test/namespaces/test_namespaces_preservation.rb -test/test_convert_xpath.rb -test/test_css_cache.rb -test/test_encoding_handler.rb -test/test_memory_leak.rb -test/test_nokogiri.rb -test/test_soap4r_sax.rb -test/test_xslt_transforms.rb -test/xml/node/test_save_options.rb -test/xml/node/test_subclass.rb -test/xml/sax/test_parser.rb -test/xml/sax/test_parser_context.rb -test/xml/sax/test_parser_text.rb -test/xml/sax/test_push_parser.rb -test/xml/test_attr.rb -test/xml/test_attribute_decl.rb -test/xml/test_builder.rb -test/xml/test_c14n.rb -test/xml/test_cdata.rb -test/xml/test_comment.rb -test/xml/test_document.rb -test/xml/test_document_encoding.rb -test/xml/test_document_fragment.rb -test/xml/test_dtd.rb -test/xml/test_dtd_encoding.rb -test/xml/test_element_content.rb -test/xml/test_element_decl.rb -test/xml/test_entity_decl.rb -test/xml/test_entity_reference.rb -test/xml/test_namespace.rb -test/xml/test_node.rb -test/xml/test_node_attributes.rb -test/xml/test_node_encoding.rb -test/xml/test_node_inheritance.rb -test/xml/test_node_reparenting.rb -test/xml/test_node_set.rb -test/xml/test_parse_options.rb -test/xml/test_processing_instruction.rb -test/xml/test_reader.rb -test/xml/test_reader_encoding.rb -test/xml/test_relax_ng.rb -test/xml/test_schema.rb -test/xml/test_syntax_error.rb -test/xml/test_text.rb -test/xml/test_unparented_node.rb -test/xml/test_xinclude.rb -test/xml/test_xpath.rb -test/xslt/test_custom_functions.rb -test/xslt/test_exception_handling.rb diff --git a/Rakefile b/Rakefile index 21b27a17df..f908a5496a 100644 --- a/Rakefile +++ b/Rakefile @@ -115,8 +115,7 @@ HOE = Hoe.spec 'nokogiri' do self.readme_file = "README.md" self.history_file = "CHANGELOG.md" - self.extra_rdoc_files = FileList['*.rdoc','ext/nokogiri/*.c'] - + self.extra_rdoc_files = FileList['ext/nokogiri/*.c'] self.clean_globs += [ 'nokogiri.gemspec', From 985b9fc229792a658c631ba78b6fbd1010a01fec Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 07:53:14 -0500 Subject: [PATCH 170/176] add .hoerc containing excludes so we can double-check the Manifest with `rake check_manifest` --- .hoerc | 40 ++++++++++++++++++++++++++++++++++++++++ Manifest.txt | 7 ++----- 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 .hoerc diff --git a/.hoerc b/.hoerc new file mode 100644 index 0000000000..9ecaeb93a7 --- /dev/null +++ b/.hoerc @@ -0,0 +1,40 @@ +# -*- yaml -*- +--- +# this regex is what `rake check_manifest` should consider excluded from the gem +exclude: !ruby/regexp '/ +(^\.\/ + ((\.git + |concourse + |gems + |ports + |suppressions + |tasks + |test + |tmp + )\/) + |\.(autotest + |codeclimate\.yml + |cross_rubies + |editorconfig + |gemtest + |github + |gitignore + |hoerc + |travis\.yml + ) + |Gemfile.* + |Manifest.txt + |Rakefile + |appveyor\.yml + |build_all + |CHANGELOG.md + |CONTRIBUTING.md + |ROADMAP.md + |SECURITY.md + |STANDARD_RESPONSES.md + |Y_U_NO_GEMSPEC.md + |C_CODING_STYLE.* + |patches/sort-patches-by-date +) +|\.gitkeep +/x' diff --git a/Manifest.txt b/Manifest.txt index 7a97d815bd..92408ccc87 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -63,8 +63,6 @@ ext/java/nokogiri/internals/XalanDTMManagerPatch.java ext/java/nokogiri/internals/XmlDeclHandler.java ext/java/nokogiri/internals/XmlDomParserContext.java ext/java/nokogiri/internals/XmlSaxParser.java -ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java -ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java ext/java/nokogiri/internals/c14n/AttrCompare.java ext/java/nokogiri/internals/c14n/C14nHelper.java ext/java/nokogiri/internals/c14n/CanonicalFilter.java @@ -92,6 +90,8 @@ ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java ext/java/nokogiri/internals/c14n/NodeFilter.java ext/java/nokogiri/internals/c14n/UtfHelpper.java ext/java/nokogiri/internals/c14n/XMLUtils.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java ext/nokogiri/depend ext/nokogiri/extconf.rb ext/nokogiri/html_document.c @@ -236,6 +236,3 @@ lib/xsd/xmlparser/nokogiri.rb patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch patches/libxml2/0002-Fix-nullptr-deref-with-XPath-logic-ops.patch patches/libxml2/0003-Fix-infinite-loop-in-LZMA-decompression.patch -patches/sort-patches-by-date -suppressions/README.txt -suppressions/nokogiri_ruby-2.supp From dd19ddd5ab9ca6c2d7044274eae11e98b645d57e Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 08:09:52 -0500 Subject: [PATCH 171/176] update CHANGELOG for #1711 and #1719 [skip ci] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8936153a3..d2037fbaa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ * [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 to address upstream vulnerability CVE-2012-0881 [#1831] (Thanks @grajagandev for reporting.) +## Notable non-functional changes + +* Decrease installation size by removing many unneeded files (e.g., `/test`) from the packaged gems. [#1719] (Thanks, @stevecrozz!) + + ## Features * `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800] From fff550cbfbfbc7da0ab6f5f16da37fb576afb4c2 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 09:38:23 -0500 Subject: [PATCH 172/176] version bump to v1.9.0 --- CHANGELOG.md | 2 +- lib/nokogiri/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2037fbaa1..7d5769401a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.9.0.rc1 / 2018-12-10 +# 1.9.0 / 2018-12-17 ## Security Notes diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index d421318ebe..14fa5df62e 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.9.0.rc1' + VERSION = '1.9.0' class VersionInfo # :nodoc: def jruby? From ab40787f49fc71d566cd5a2c3a16c21edffd9d2b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 16:06:43 -0500 Subject: [PATCH 173/176] correct CHANGELOG [skip ci] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d5769401a..f013c98b02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,8 +25,8 @@ * `NodeSet#each` now returns `self` instead of zero. [#1822] (Thanks, @olehif!) * [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810] * [MRI] Address a memory leak when unparenting a DTD. [#1784] (Thanks, @stevecheckoway!) -* [MRI] Decrease large memory usage when making nested XPath queries. [#1749] * [MRI] Use RbConfig::CONFIG instead of ::MAKEFILE_CONFIG to fix installations that use Makefile macros. [#1820] (Thanks, @nobu!) +* [JRuby] Decrease large memory usage when making nested XPath queries. [#1749] * [JRuby] Fix failing tests on JRuby 9.2.x * [JRuby] Fix default namespaces in nodes reparented into a different document [#1774] * [JRuby] Fix support for Java 9. [#1759] (Thanks, @Taywee!) From e9ac29275afde6f670a4db64d609a7a07c828ea6 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 23:22:03 -0500 Subject: [PATCH 174/176] Fix XML::DocumentFragment to return an instance of callee's class Fixes #1846. Bug introduced in f2f3a3b. --- CHANGELOG.md | 7 +++++++ lib/nokogiri/xml/document_fragment.rb | 2 +- test/html/test_document_fragment.rb | 7 +++++++ test/xml/test_document_fragment.rb | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f013c98b02..2644710555 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.9.1 / 2018-12-17 + +## Bug fixes + +* Fix a bug introduced in v1.9.0 where `XML::DocumentFragment#dup` no longer returned an instance of the callee's class, instead always returning an `XML::DocumentFragment`. This notably broke any subclass of `XML::DocumentFragment` including `HTML::DocumentFragment` as well as the Loofah gem's `Loofah::HTML::DocumentFragment`. [#1846] + + # 1.9.0 / 2018-12-17 ## Security Notes diff --git a/lib/nokogiri/xml/document_fragment.rb b/lib/nokogiri/xml/document_fragment.rb index cfa826b421..e56886b0d6 100644 --- a/lib/nokogiri/xml/document_fragment.rb +++ b/lib/nokogiri/xml/document_fragment.rb @@ -28,7 +28,7 @@ def initialize document, tags = nil, ctx = nil if Nokogiri.uses_libxml? def dup new_document = document.dup - new_fragment = XML::DocumentFragment.new(new_document) + new_fragment = self.class.new(new_document) children.each do |child| child.dup(1, new_document).parent = new_fragment end diff --git a/test/html/test_document_fragment.rb b/test/html/test_document_fragment.rb index 3a85740b42..1b497b0c6d 100644 --- a/test/html/test_document_fragment.rb +++ b/test/html/test_document_fragment.rb @@ -305,6 +305,13 @@ def test_capturing_nonparse_errors_during_node_copy_between_fragments assert_equal original_errors1, frag1.errors assert_equal original_errors2, frag2.errors end + + def test_dup_should_create_an_html_document_fragment + # https://github.com/sparklemotion/nokogiri/issues/1846 + original = Nokogiri::HTML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_instance_of Nokogiri::HTML::DocumentFragment, duplicate + end end end end diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index 3ff801e847..242bd9e4f1 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -263,6 +263,20 @@ def test_issue_1077_parsing_of_frozen_strings Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised end + def test_dup_should_exist_in_a_new_document + # https://github.com/sparklemotion/nokogiri/issues/1063 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_not_equal original.document, duplicate.document + end + + def test_dup_should_create_an_xml_document_fragment + # https://github.com/sparklemotion/nokogiri/issues/1846 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_instance_of Nokogiri::XML::DocumentFragment, duplicate + end + def test_dup_creates_tree_with_identical_structure original = Nokogiri::XML::DocumentFragment.parse("

hello

") duplicate = original.dup From 2e15c885de3e0669f35dca1f5a1dd047c92e1c7d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 23:26:42 -0500 Subject: [PATCH 175/176] version bump to v1.9.1 [skip ci] --- lib/nokogiri/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb index 14fa5df62e..034c5a6cee 100644 --- a/lib/nokogiri/version.rb +++ b/lib/nokogiri/version.rb @@ -1,6 +1,6 @@ module Nokogiri # The version of Nokogiri you are using - VERSION = '1.9.0' + VERSION = '1.9.1' class VersionInfo # :nodoc: def jruby? From db26a04e3d8f2b30456ae203d6c023b299a8e0f9 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 17 Dec 2018 23:43:22 -0500 Subject: [PATCH 176/176] limit test of libxml-specific DocumentFragment#dup behavior ... to only running when testing the libxml2 impl. Related to #1846 and #1063. --- test/xml/test_document_fragment.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb index 242bd9e4f1..a3cfebdbdf 100644 --- a/test/xml/test_document_fragment.rb +++ b/test/xml/test_document_fragment.rb @@ -263,11 +263,13 @@ def test_issue_1077_parsing_of_frozen_strings Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised end - def test_dup_should_exist_in_a_new_document - # https://github.com/sparklemotion/nokogiri/issues/1063 - original = Nokogiri::XML::DocumentFragment.parse("

hello

") - duplicate = original.dup - assert_not_equal original.document, duplicate.document + if Nokogiri.uses_libxml? + def test_dup_should_exist_in_a_new_document + # https://github.com/sparklemotion/nokogiri/issues/1063 + original = Nokogiri::XML::DocumentFragment.parse("

hello

") + duplicate = original.dup + assert_not_equal original.document, duplicate.document + end end def test_dup_should_create_an_xml_document_fragment