add patch for rubygem-rexml CVE-2024-35176 (#9242)
Co-authored-by: minghe <rmhsawyer>
This commit is contained in:
parent
fea7c96a84
commit
222de009ea
|
@ -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)
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue