Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
Mamoru TASAKA
cc56a27505 Make test suite pass with libxml2 2.9.14 2022-06-03 16:41:29 +09:00
Mamoru TASAKA
58706a84c8 apply ppc64le gc compact issue 2022-05-10 18:03:27 +09:00
Mamoru TASAKA
7984adc4e9 Backport CVE-2022-29181 from between 1.13.5 and 1.13.6 2022-05-10 17:48:50 +09:00
Mamoru TASAKA
653b4da6c7 Backport CVE-2022-24836 from between 1.13.3 and 1.13.4 2022-04-14 16:47:39 +09:00
4 changed files with 320 additions and 1 deletions

View file

@ -0,0 +1,42 @@
commit e444525ef1634b675cd1cf52d39f4320ef0aecfd
Author: Mike Dalessio <mike.dalessio@gmail.com>
Date: Sun Apr 10 14:42:04 2022 -0400
fix(perf): HTML4::EncodingReader detection
diff --git a/lib/nokogiri/html4/document.rb b/lib/nokogiri/html4/document.rb
index 177efc04..fbc22d20 100644
--- a/lib/nokogiri/html4/document.rb
+++ b/lib/nokogiri/html4/document.rb
@@ -268,7 +268,7 @@ module Nokogiri
end
def self.detect_encoding(chunk)
- (m = chunk.match(/\A(<\?xml[ \t\r\n]+[^>]*>)/)) &&
+ (m = chunk.match(/\A(<\?xml[ \t\r\n][^>]*>)/)) &&
(return Nokogiri.XML(m[1]).encoding)
if Nokogiri.jruby?
diff --git a/test/html4/test_document_encoding.rb b/test/html4/test_document_encoding.rb
index 61153017..ecb4aa9a 100644
--- a/test/html4/test_document_encoding.rb
+++ b/test/html4/test_document_encoding.rb
@@ -155,6 +155,18 @@ class TestNokogiriHtmlDocument < Nokogiri::TestCase
end
end
end
+
+ it "does not start backtracking during detection of XHTML encoding" do
+ # this test is a quick and dirty version
+ # of the more complete perf test that is on main.
+ n = 40_000
+ redos_string = "<?xml " + (" " * n)
+ redos_string.encode!("ASCII-8BIT")
+ start_time = Time.now
+ Nokogiri::HTML4(redos_string)
+ elapsed_time = Time.now - start_time
+ assert_operator(elapsed_time, :<, 1)
+ end
end
end
end

View file

@ -0,0 +1,182 @@
From db05ba9a1bd4b90aa6c76742cf6102a7c7297267 Mon Sep 17 00:00:00 2001
From: Mike Dalessio <mike.dalessio@gmail.com>
Date: Fri, 6 May 2022 21:57:41 -0400
Subject: [PATCH] fix: {HTML4,XML}::SAX::{Parser,ParserContext} check arg types
Previously, arguments of the wrong type might cause segfault on CRuby.
---
CHANGELOG.md | 3 ++-
ext/java/nokogiri/Html4SaxParserContext.java | 11 +++++++++++
ext/java/nokogiri/XmlSaxParserContext.java | 7 +++++--
ext/java/nokogiri/internals/ParserContext.java | 8 +++++++-
ext/nokogiri/html4_sax_parser_context.c | 5 ++---
ext/nokogiri/xml_sax_parser_context.c | 13 ++++++++++---
lib/nokogiri/html4/sax/parser.rb | 2 +-
test/html4/sax/test_parser.rb | 8 +++++++-
test/html4/sax/test_parser_context.rb | 9 +++++++++
test/xml/sax/test_parser.rb | 8 +++++++-
test/xml/sax/test_parser_context.rb | 7 +++++++
11 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/ext/nokogiri/html4_sax_parser_context.c b/ext/nokogiri/html4_sax_parser_context.c
index dec0d88fe..54adca4cb 100644
--- a/ext/nokogiri/html4_sax_parser_context.c
+++ b/ext/nokogiri/html4_sax_parser_context.c
@@ -19,9 +19,8 @@ parse_memory(VALUE klass, VALUE data, VALUE encoding)
{
htmlParserCtxtPtr ctxt;
- if (NIL_P(data)) {
- rb_raise(rb_eArgError, "data cannot be nil");
- }
+ Check_Type(data, T_STRING);
+
if (!(int)RSTRING_LEN(data)) {
rb_raise(rb_eRuntimeError, "data cannot be empty");
}
diff --git a/ext/nokogiri/xml_sax_parser_context.c b/ext/nokogiri/xml_sax_parser_context.c
index 60449347a..60c491984 100644
--- a/ext/nokogiri/xml_sax_parser_context.c
+++ b/ext/nokogiri/xml_sax_parser_context.c
@@ -2,6 +2,8 @@
VALUE cNokogiriXmlSaxParserContext ;
+static ID id_read;
+
static void
deallocate(xmlParserCtxtPtr ctxt)
{
@@ -26,6 +28,10 @@ parse_io(VALUE klass, VALUE io, VALUE encoding)
xmlParserCtxtPtr ctxt;
xmlCharEncoding enc = (xmlCharEncoding)NUM2INT(encoding);
+ if (!rb_respond_to(io, id_read)) {
+ rb_raise(rb_eTypeError, "argument expected to respond to :read");
+ }
+
ctxt = xmlCreateIOParserCtxt(NULL, NULL,
(xmlInputReadCallback)noko_io_read,
(xmlInputCloseCallback)noko_io_close,
@@ -62,9 +68,8 @@ parse_memory(VALUE klass, VALUE data)
{
xmlParserCtxtPtr ctxt;
- if (NIL_P(data)) {
- rb_raise(rb_eArgError, "data cannot be nil");
- }
+ Check_Type(data, T_STRING);
+
if (!(int)RSTRING_LEN(data)) {
rb_raise(rb_eRuntimeError, "data cannot be empty");
}
@@ -278,4 +283,6 @@ noko_init_xml_sax_parser_context()
rb_define_method(cNokogiriXmlSaxParserContext, "recovery", get_recovery, 0);
rb_define_method(cNokogiriXmlSaxParserContext, "line", line, 0);
rb_define_method(cNokogiriXmlSaxParserContext, "column", column, 0);
+
+ id_read = rb_intern("read");
}
diff --git a/lib/nokogiri/html4/sax/parser.rb b/lib/nokogiri/html4/sax/parser.rb
index 2a074b6b9..1f8c03af6 100644
--- a/lib/nokogiri/html4/sax/parser.rb
+++ b/lib/nokogiri/html4/sax/parser.rb
@@ -28,7 +28,7 @@ class Parser < Nokogiri::XML::SAX::Parser
###
# Parse html stored in +data+ using +encoding+
def parse_memory(data, encoding = "UTF-8")
- raise ArgumentError unless data
+ raise TypeError unless String === data
return if data.empty?
ctx = ParserContext.memory(data, encoding)
yield ctx if block_given?
diff --git a/test/html4/sax/test_parser.rb b/test/html4/sax/test_parser.rb
index 3917dce2e..4dc6ac61f 100644
--- a/test/html4/sax/test_parser.rb
+++ b/test/html4/sax/test_parser.rb
@@ -54,7 +54,7 @@ def test_parse_file_with_dir
end
def test_parse_memory_nil
- assert_raises(ArgumentError) do
+ assert_raises(TypeError) do
@parser.parse_memory(nil)
end
end
@@ -161,6 +161,12 @@ def test_parsing_dom_error_from_io
def test_empty_processing_instruction
@parser.parse_memory("<strong>this will segfault<?strong>")
end
+
+ it "handles invalid types gracefully" do
+ assert_raises(TypeError) { Nokogiri::HTML::SAX::Parser.new.parse(0xcafecafe) }
+ assert_raises(TypeError) { Nokogiri::HTML::SAX::Parser.new.parse_memory(0xcafecafe) }
+ assert_raises(TypeError) { Nokogiri::HTML::SAX::Parser.new.parse_io(0xcafecafe) }
+ end
end
end
end
diff --git a/test/html4/sax/test_parser_context.rb b/test/html4/sax/test_parser_context.rb
index 0a0eda64c..594a3ac82 100644
--- a/test/html4/sax/test_parser_context.rb
+++ b/test/html4/sax/test_parser_context.rb
@@ -40,6 +40,15 @@ def test_from_file
ctx.parse_with(parser)
# end
end
+
+ def test_graceful_handling_of_invalid_types
+ assert_raises(TypeError) { ParserContext.new(0xcafecafe) }
+ assert_raises(TypeError) { ParserContext.memory(0xcafecafe, "UTF-8") }
+ assert_raises(TypeError) { ParserContext.io(0xcafecafe, 1) }
+ assert_raises(TypeError) { ParserContext.io(StringIO.new("asdf"), "should be an index into ENCODINGS") }
+ assert_raises(TypeError) { ParserContext.file(0xcafecafe, "UTF-8") }
+ assert_raises(TypeError) { ParserContext.file("path/to/file", 0xcafecafe) }
+ end
end
end
end
diff --git a/test/xml/sax/test_parser.rb b/test/xml/sax/test_parser.rb
index 6c0f1fc88..ac7d4ead0 100644
--- a/test/xml/sax/test_parser.rb
+++ b/test/xml/sax/test_parser.rb
@@ -73,6 +73,12 @@ class TestCase
end
end
+ it "handles invalid types gracefully" do
+ assert_raises(TypeError) { Nokogiri::XML::SAX::Parser.new.parse(0xcafecafe) }
+ assert_raises(TypeError) { Nokogiri::XML::SAX::Parser.new.parse_memory(0xcafecafe) }
+ assert_raises(TypeError) { Nokogiri::XML::SAX::Parser.new.parse_io(0xcafecafe) }
+ end
+
it :test_namespace_declaration_order_is_saved do
parser.parse(<<~EOF)
<root xmlns:foo='http://foo.example.com/' xmlns='http://example.com/'>
@@ -263,7 +269,7 @@ def call_parse_io_with_encoding(encoding)
end
it :test_render_parse_nil_param do
- assert_raises(ArgumentError) { parser.parse_memory(nil) }
+ assert_raises(TypeError) { parser.parse_memory(nil) }
end
it :test_bad_encoding_args do
diff --git a/test/xml/sax/test_parser_context.rb b/test/xml/sax/test_parser_context.rb
index e38efd271..ba9857943 100644
--- a/test/xml/sax/test_parser_context.rb
+++ b/test/xml/sax/test_parser_context.rb
@@ -80,6 +80,13 @@ def test_recovery
assert(pc.recovery)
end
+ def test_graceful_handling_of_invalid_types
+ assert_raises(TypeError) { ParserContext.new(0xcafecafe) }
+ assert_raises(TypeError) { ParserContext.memory(0xcafecafe) }
+ assert_raises(TypeError) { ParserContext.io(0xcafecafe, 1) }
+ assert_raises(TypeError) { ParserContext.io(StringIO.new("asdf"), "should be an index into ENCODINGS") }
+ end
+
def test_from_io
ctx = ParserContext.new(StringIO.new("fo"), "UTF-8")
assert(ctx)

View file

@ -0,0 +1,63 @@
From 520f4e7d64eab9b862b7fe9c683d348be9f4eb0a Mon Sep 17 00:00:00 2001
From: Mike Dalessio <mike.dalessio@gmail.com>
Date: Mon, 2 May 2022 18:04:39 -0400
Subject: [PATCH] dep: update libxml2 to v2.9.14
from v2.9.13
https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.9.14
---
dependencies.yml | 6 +--
...t-approach-to-fix-quadratic-behavior.patch | 45 -------------------
test/html4/test_comments.rb | 25 ++++++++++-
test/html4/test_document.rb | 25 +++++++----
4 files changed, 43 insertions(+), 58 deletions(-)
delete mode 100644 patches/libxml2/0010-Revert-Different-approach-to-fix-quadratic-behavior.patch
diff --git a/test/html4/test_comments.rb b/test/html4/test_comments.rb
index 32d7a8785..56fd50682 100644
--- a/test/html4/test_comments.rb
+++ b/test/html4/test_comments.rb
@@ -173,7 +173,7 @@ class TestComment < Nokogiri::TestCase
let(:body) { doc.at_css("body") }
let(:subject) { doc.at_css("div#under-test") }
- if Nokogiri.uses_libxml?
+ if Nokogiri.uses_libxml?("<=2.9.13")
it "ignores up to the next '>'" do # NON-COMPLIANT
assert_equal 2, body.children.length
assert_equal body.children[0], subject
@@ -183,10 +183,33 @@ class TestComment < Nokogiri::TestCase
assert body.children[1].text?
assert_equal "-->hello", body.children[1].content
end
+ elsif Nokogiri.uses_libxml?
+ it "parses as pcdata" do # NON-COMPLIANT
+ assert_equal 1, body.children.length
+ assert_equal subject, body.children.first
+
+ assert_equal 3, subject.children.length
+ subject.children[0].tap do |child|
+ assert_predicate(child, :text?)
+ assert_equal("<! comment ", child.content)
+ end
+ subject.children[1].tap do |child|
+ assert_predicate(child, :element?)
+ assert_equal("div", child.name)
+ assert_equal("inner content", child.content)
+ end
+ subject.children[2].tap do |child|
+ assert_predicate(child, :text?)
+ assert_equal("-->hello", child.content)
+ end
+ end
end
if Nokogiri.jruby?
it "ignores up to the next '-->'" do # NON-COMPLIANT
+ assert_equal 1, body.children.length
+ assert_equal subject, body.children.first
+
assert_equal 1, subject.children.length
assert subject.children[0].text?
assert_equal "hello", subject.children[0].content

View file

@ -1,7 +1,7 @@
%global mainver 1.13.1
#%%global prever .rc4
%global mainrel 1
%global mainrel 4
%global prerpmver %(echo "%{?prever}" | sed -e 's|\\.||g')
%global gem_name nokogiri
@ -32,6 +32,15 @@ Source2: nokogiri-create-full-tarball.sh
#Patch0: rubygem-nokogiri-1.5.0-allow-non-crosscompile.patch
# Shut down libxml2 version unmatching warning
Patch0: %{name}-1.11.0.rc4-shutdown-libxml2-warning.patch
# https://github.com/sparklemotion/nokogiri/commit/e444525ef1634b675cd1cf52d39f4320ef0aecfd
# Fix for CVE-2022-24836
Patch1: %{name}-1.13.3-CVE-2022-24836.patch
# https://github.com/sparklemotion/nokogiri/commit/db05ba9a1bd4b90aa6c76742cf6102a7c7297267
# Fix for CVE-2022-24836, backported
Patch2: %{name}-1.13.5-6-CVE-2022-29181-backport.patch
# Test suite for libxml2 2.9.14
# https://github.com/sparklemotion/nokogiri/commit/520f4e7d64eab9b862b7fe9c683d348be9f4eb0a
Patch3: %{name}-1.13.x-testsuite-libxml2-2-9-14.patch
BuildRequires: ruby(release)
BuildRequires: ruby(rubygems)
##
@ -91,7 +100,15 @@ This package provides non-Gem support for %{gem_name}.
mv ../%{gem_name}-%{version}.gemspec .
# patches
(
cd %{gem_name}-%{version}/
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
cd ..
cp -a %{gem_name}-%{version}/{lib,ext} .
)
# remove bundled external libraries
sed -i \
@ -222,6 +239,12 @@ sed -i test/helper.rb \
sed -i '/require..minitest.reporters./ s/^/#/' test/helper.rb
sed -i '/Minitest::Reporters/ s/^/#/' test/helper.rb
# PPC64LE with ruby3.1 does not seem to support GC.compact
# (On Fedora, the above is backported to 3.0 branch)
%ifarch ppc64le
export NOKOGIRI_TEST_GC_LEVEL=major
%endif
# Need investigation. For now anyway build
env \
RUBYLIB=".:lib:test:ext" \
@ -260,6 +283,15 @@ popd
%{gem_dir}/doc/%{gem_name}-%{mainver}%{?prever}/
%changelog
* Fri Jun 3 2022 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.13.1-4
- Make test suite pass with libxml2 2.9.14
* Tue May 10 2022 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.13.1-3
- Backport CVE-2022-29181 from between 1.13.5 and 1.13.6
* Thu Apr 14 2022 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.13.1-2
- Backport CVE-2022-24836 from between 1.13.3 and 1.13.4
* Fri Jan 14 2022 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.13.1-1
- 1.13.1