mirror of
https://git.yoctoproject.org/poky
synced 2026-03-10 09:19:41 +01:00
REXML is an XML toolkit for Ruby. The REXML gem before 3.3.2 has some DoS vulnerabilities when it parses an XML that has many specific characters such as whitespace character, `>]` and `]>`. The REXML gem 3.3.3 or later include the patches to fix these vulnerabilities. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-41123 Upstream-patches:2c39c91a654444a04eceebc3e85bfa6cac15d458e2546e6eca(From OE-Core rev: 6b2a2e689a69deef6098f6c266542234e46fb24b) Signed-off-by: Divya Chellam <divya.chellam@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
164 lines
6.4 KiB
Diff
164 lines
6.4 KiB
Diff
From 6cac15d45864c8d70904baa5cbfcc97181000960 Mon Sep 17 00:00:00 2001
|
|
From: tomoya ishida <tomoyapenguin@gmail.com>
|
|
Date: Thu, 1 Aug 2024 09:21:19 +0900
|
|
Subject: [PATCH] Fix source.match performance without specifying term string
|
|
(#186)
|
|
|
|
Performance problem of `source.match(regexp)` was recently fixed by
|
|
specifying terminator string. However, I think maintaining appropriate
|
|
terminator string for a regexp is hard.
|
|
I propose solving this performance issue by increasing bytes to read in
|
|
each iteration.
|
|
|
|
CVE: CVE-2024-41123
|
|
|
|
Upstream-Status: Backport [https://github.com/ruby/rexml/commit/6cac15d45864c8d70904baa5cbfcc97181000960]
|
|
|
|
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
|
---
|
|
.../lib/rexml/parsers/baseparser.rb | 22 ++++++------------
|
|
.bundle/gems/rexml-3.2.5/lib/rexml/source.rb | 23 +++++++++++++++----
|
|
2 files changed, 25 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
|
|
index 71fce99..c1a22b8 100644
|
|
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
|
|
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
|
|
@@ -124,14 +124,6 @@ module REXML
|
|
}
|
|
|
|
module Private
|
|
- # Terminal requires two or more letters.
|
|
- INSTRUCTION_TERM = "?>"
|
|
- COMMENT_TERM = "-->"
|
|
- CDATA_TERM = "]]>"
|
|
- DOCTYPE_TERM = "]>"
|
|
- # Read to the end of DOCTYPE because there is no proper ENTITY termination
|
|
- ENTITY_TERM = DOCTYPE_TERM
|
|
-
|
|
INSTRUCTION_END = /#{NAME}(\s+.*?)?\?>/um
|
|
TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um
|
|
CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um
|
|
@@ -244,7 +236,7 @@ module REXML
|
|
return process_instruction(start_position)
|
|
elsif @source.match("<!", true)
|
|
if @source.match("--", true)
|
|
- md = @source.match(/(.*?)-->/um, true, term: Private::COMMENT_TERM)
|
|
+ md = @source.match(/(.*?)-->/um, true)
|
|
if md.nil?
|
|
raise REXML::ParseException.new("Unclosed comment", @source)
|
|
end
|
|
@@ -308,7 +300,7 @@ module REXML
|
|
raise REXML::ParseException.new( "Bad ELEMENT declaration!", @source ) if md.nil?
|
|
return [ :elementdecl, "<!ELEMENT" + md[1] ]
|
|
elsif @source.match("ENTITY", true)
|
|
- match_data = @source.match(Private::ENTITYDECL_PATTERN, true, term: Private::ENTITY_TERM)
|
|
+ match_data = @source.match(Private::ENTITYDECL_PATTERN, true)
|
|
unless match_data
|
|
raise REXML::ParseException.new("Malformed entity declaration", @source)
|
|
end
|
|
@@ -377,14 +369,14 @@ module REXML
|
|
raise REXML::ParseException.new(message, @source)
|
|
end
|
|
return [:notationdecl, name, *id]
|
|
- elsif md = @source.match(/--(.*?)-->/um, true, term: Private::COMMENT_TERM)
|
|
+ elsif md = @source.match(/--(.*?)-->/um, true)
|
|
case md[1]
|
|
when /--/, /-\z/
|
|
raise REXML::ParseException.new("Malformed comment", @source)
|
|
end
|
|
return [ :comment, md[1] ] if md
|
|
end
|
|
- elsif match = @source.match(/(%.*?;)\s*/um, true, term: Private::DOCTYPE_TERM)
|
|
+ elsif match = @source.match(/(%.*?;)\s*/um, true)
|
|
return [ :externalentity, match[1] ]
|
|
elsif @source.match(/\]\s*>/um, true)
|
|
@document_status = :after_doctype
|
|
@@ -417,7 +409,7 @@ module REXML
|
|
#STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
|
|
raise REXML::ParseException.new("Malformed node", @source) unless md
|
|
if md[0][0] == ?-
|
|
- md = @source.match(/--(.*?)-->/um, true, term: Private::COMMENT_TERM)
|
|
+ md = @source.match(/--(.*?)-->/um, true)
|
|
|
|
case md[1]
|
|
when /--/, /-\z/
|
|
@@ -426,7 +418,7 @@ module REXML
|
|
|
|
return [ :comment, md[1] ] if md
|
|
else
|
|
- md = @source.match(/\[CDATA\[(.*?)\]\]>/um, true, term: Private::CDATA_TERM)
|
|
+ md = @source.match(/\[CDATA\[(.*?)\]\]>/um, true)
|
|
return [ :cdata, md[1] ] if md
|
|
end
|
|
raise REXML::ParseException.new( "Declarations can only occur "+
|
|
@@ -664,7 +656,7 @@ module REXML
|
|
end
|
|
|
|
def process_instruction(start_position)
|
|
- match_data = @source.match(Private::INSTRUCTION_END, true, term: Private::INSTRUCTION_TERM)
|
|
+ match_data = @source.match(Private::INSTRUCTION_END, true)
|
|
unless match_data
|
|
message = "Invalid processing instruction node"
|
|
@source.position = start_position
|
|
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
|
|
index 7be430a..7c05cb5 100644
|
|
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
|
|
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
|
|
@@ -72,7 +72,7 @@ module REXML
|
|
@scanner.scan_until(Regexp.union(term)) or @scanner.rest
|
|
end
|
|
|
|
- def match(pattern, cons=false, term: nil)
|
|
+ def match(pattern, cons=false)
|
|
if cons
|
|
@scanner.scan(pattern).nil? ? nil : @scanner
|
|
else
|
|
@@ -159,10 +159,20 @@ module REXML
|
|
end
|
|
end
|
|
|
|
- def read(term = nil)
|
|
+ def read(term = nil, min_bytes = 1)
|
|
term = encode(term) if term
|
|
begin
|
|
- @scanner << readline(term)
|
|
+ str = readline(term)
|
|
+ @scanner << str
|
|
+ read_bytes = str.bytesize
|
|
+ begin
|
|
+ while read_bytes < min_bytes
|
|
+ str = readline(term)
|
|
+ @scanner << str
|
|
+ read_bytes += str.bytesize
|
|
+ end
|
|
+ rescue IOError
|
|
+ end
|
|
true
|
|
rescue Exception, NameError
|
|
@source = nil
|
|
@@ -186,7 +196,9 @@ module REXML
|
|
end
|
|
end
|
|
|
|
- def match( pattern, cons=false, term: nil )
|
|
+ def match( pattern, cons=false )
|
|
+ # To avoid performance issue, we need to increase bytes to read per scan
|
|
+ min_bytes = 1
|
|
read if @scanner.eos? && @source
|
|
while true
|
|
if cons
|
|
@@ -197,7 +209,8 @@ module REXML
|
|
break if md
|
|
return nil if pattern.is_a?(String) && pattern.bytesize <= @scanner.rest_size
|
|
return nil if @source.nil?
|
|
- return nil unless read(term)
|
|
+ return nil unless read(nil, min_bytes)
|
|
+ min_bytes *= 2
|
|
end
|
|
|
|
md.nil? ? nil : @scanner
|
|
--
|
|
2.40.0
|
|
|