add patch for rubygem-rexml CVE-2024-35176 (#9242)

Co-authored-by: minghe <rmhsawyer>
This commit is contained in:
Minghe Ren 2024-05-29 14:11:36 -07:00 committed by GitHub
parent fea7c96a84
commit 222de009ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 196 additions and 2 deletions

View File

@ -0,0 +1,190 @@
diff -ruN a/Gemfile b/Gemfile
--- a/Gemfile 2021-04-05 04:43:38.000000000 -0700
+++ b/Gemfile 2024-05-29 00:06:13.851182285 -0700
@@ -4,3 +4,7 @@
# Specify your gem's dependencies in rexml.gemspec
gemspec
+
+group :development do
+ gem "test-unit-ruby-core"
+end
diff -ruN a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
--- a/lib/rexml/parsers/baseparser.rb 2021-04-05 04:43:38.000000000 -0700
+++ b/lib/rexml/parsers/baseparser.rb 2024-05-28 18:53:32.656078157 -0700
@@ -589,60 +589,41 @@
def parse_attributes(prefixes, curr_ns)
attributes = {}
closed = false
- match_data = @source.match(/^(.*?)(\/)?>/um, true)
- if match_data.nil?
- message = "Start tag isn't ended"
- raise REXML::ParseException.new(message, @source)
- end
-
- raw_attributes = match_data[1]
- closed = !match_data[2].nil?
- return attributes, closed if raw_attributes.nil?
- return attributes, closed if raw_attributes.empty?
-
- scanner = StringScanner.new(raw_attributes)
- until scanner.eos?
- if scanner.scan(/\s+/)
- break if scanner.eos?
- end
-
- pos = scanner.pos
- loop do
- break if scanner.scan(ATTRIBUTE_PATTERN)
- unless scanner.scan(QNAME)
- message = "Invalid attribute name: <#{scanner.rest}>"
- raise REXML::ParseException.new(message, @source)
- end
- name = scanner[0]
- unless scanner.scan(/\s*=\s*/um)
+ while true
+ if @source.match(">", true)
+ return attributes, closed
+ elsif @source.match("/>", true)
+ closed = true
+ return attributes, closed
+ elsif match = @source.match(QNAME, true)
+ name = match[1]
+ prefix = match[2]
+ local_part = match[3]
+ unless @source.match(/\s*=\s*/um, true)
message = "Missing attribute equal: <#{name}>"
raise REXML::ParseException.new(message, @source)
end
- quote = scanner.scan(/['"]/)
- unless quote
+ unless match = @source.match(/(['"])(.*?)\1\s*/um, true)
+ if match = @source.match(/(['"])/, true)
+ message =
+ "Missing attribute value end quote: <#{name}>: <#{match[1]}>"
+ raise REXML::ParseException.new(message, @source)
+ else
+ message = "Missing attribute value start quote: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ unless match = @source.match(/(['"])/, true)
message = "Missing attribute value start quote: <#{name}>"
raise REXML::ParseException.new(message, @source)
end
- unless scanner.scan(/.*#{Regexp.escape(quote)}/um)
- match_data = @source.match(/^(.*?)(\/)?>/um, true)
- if match_data
- scanner << "/" if closed
- scanner << ">"
- scanner << match_data[1]
- scanner.pos = pos
- closed = !match_data[2].nil?
- next
- end
- message =
- "Missing attribute value end quote: <#{name}>: <#{quote}>"
+ quote = match[1]
+ value = @source.read_until(quote)
+ unless value.chomp!(quote)
+ message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
raise REXML::ParseException.new(message, @source)
end
- end
- name = scanner[1]
- prefix = scanner[2]
- local_part = scanner[3]
- # quote = scanner[4]
- value = scanner[5]
+ value = match[2]
+ @source.match(/\s*/um, true)
if prefix == "xmlns"
if local_part == "xml"
if value != "http://www.w3.org/XML/1998/namespace"
diff -ruN a/lib/rexml/source.rb b/lib/rexml/source.rb
--- a/lib/rexml/source.rb 2021-04-05 04:43:38.000000000 -0700
+++ b/lib/rexml/source.rb 2024-05-28 17:10:36.356913505 -0700
@@ -81,7 +81,11 @@
rv
end
- def read
+ def read(term = nil)
+ end
+
+ def read_until(term)
+ @scanner.scan_until(Regexp.union(term)) or @scanner.rest
end
def consume( pattern )
@@ -204,11 +208,28 @@
rv
end
- def read
+ def read(term = nil)
begin
- @buffer << readline
+ @scanner << readline(term)
+ true
rescue Exception, NameError
@source = nil
+ false
+ end
+ end
+
+ def read_until(term)
+ pattern = Regexp.union(term)
+ data = []
+ begin
+ until str = @scanner.scan_until(pattern)
+ @scanner << readline(term)
+ end
+ rescue EOFError
+ @scanner.rest
+ else
+ read if @scanner.eos? and !@source.eof?
+ str
end
end
@@ -263,8 +284,8 @@
end
private
- def readline
- str = @source.readline(@line_break)
+ def readline(term = nil)
+ str = @source.readline(term || @line_break)
if @pending_buffer
if str.nil?
str = @pending_buffer
diff -ruN a/test/test_document.rb b/test/test_document.rb
--- a/test/test_document.rb 2021-04-05 04:43:38.000000000 -0700
+++ b/test/test_document.rb 2024-05-29 00:08:01.164345808 -0700
@@ -1,8 +1,12 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: false
+require 'core_assertions'
+
module REXMLTests
class TestDocument < Test::Unit::TestCase
+ include Test::Unit::CoreAssertions
+
def test_version_attributes_to_s
doc = REXML::Document.new(<<-eoxml)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
@@ -200,6 +204,13 @@
assert_equal('no', doc.stand_alone?, bug2539)
end
+ def test_gt_linear_performance
+ seq = [10000, 50000, 100000, 150000, 200000]
+ assert_linear_performance(seq) do |n|
+ REXML::Document.new('<test testing="' + ">" * n + '"></test>')
+ end
+ end
+
class WriteTest < Test::Unit::TestCase
def setup
@document = REXML::Document.new(<<-EOX)

View File

@ -3,13 +3,14 @@
Summary: REXML is an XML toolkit for Ruby
Name: rubygem-%{gem_name}
Version: 3.2.5
Release: 1%{?dist}
Release: 2%{?dist}
License: BSD
Vendor: Microsoft Corporation
Distribution: Mariner
Group: Development/Languages
URL: https://github.com/ruby/rexml
Source0: https://github.com/ruby/rexml/archive/refs/tags/v%{version}.tar.gz#/%{gem_name}-%{version}.tar.gz
Patch0: CVE-2024-35176.patch
BuildRequires: git
BuildRequires: ruby
Requires: ruby(release)
@ -20,7 +21,7 @@ REXML was inspired by the Electric XML library for Java, which features an easy-
REXML supports both tree and stream document parsing. Stream parsing is faster (about 1.5 times as fast). However, with stream parsing, you don't get access to features such as XPath.
%prep
%setup -q -n %{gem_name}-%{version}
%autosetup -p1 -n %{gem_name}-%{version}
%build
gem build %{gem_name}
@ -34,6 +35,9 @@ gem install -V --local --force --install-dir %{buildroot}/%{gemdir} %{gem_name}-
%{gemdir}
%changelog
* Tue May 28 2024 Minghe Ren <mingheren@microsoft.com> - 3.2.5-2
- Add patch for CVE-2024-35176
* Mon Jun 13 2022 Neha Agarwal <nehaagarwal@microsoft.com> - 3.2.5-1
- License verified
- Original version for CBL-Mariner