new file mode 100644
@@ -0,0 +1,44 @@
+From 2c39c91a65d69357cfbc35dd8079b3606d86bb70 Mon Sep 17 00:00:00 2001
+From: Watson <watson1978@gmail.com>
+Date: Fri, 19 Jul 2024 17:15:15 +0900
+Subject: [PATCH] Fix method scope in test in order to invoke the tests
+ properly and fix exception message (#182)
+
+This PR includes following two fixes.
+
+1. The `test_empty` and `test_linear_performance_gt` were defined as
+private method. Seems that test-unit runner does not invoke private
+methods even if the methods have `test_` prefix.
+2. When parse malformed entity declaration, the exception might have the
+message about `NoMethodError`. The proper exception message will be
+contained by this fix.
+
+CVE: CVE-2024-41123
+
+Upstream-Status: Backport [https://github.com/ruby/rexml/commit/2c39c91a65d69357cfbc35dd8079b3606d86bb70]
+
+Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
+---
+ .bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+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 4864ba1..451fbf8 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
+@@ -308,7 +308,11 @@ module REXML
+ raise REXML::ParseException.new( "Bad ELEMENT declaration!", @source ) if md.nil?
+ return [ :elementdecl, "<!ELEMENT" + md[1] ]
+ elsif @source.match("ENTITY", true)
+- match = [:entitydecl, *@source.match(Private::ENTITYDECL_PATTERN, true, term: Private::ENTITY_TERM).captures.compact]
++ match_data = @source.match(Private::ENTITYDECL_PATTERN, true, term: Private::ENTITY_TERM)
++ unless match_data
++ raise REXML::ParseException.new("Malformed entity declaration", @source)
++ end
++ match = [:entitydecl, *match_data.captures.compact]
+ ref = false
+ if match[1] == '%'
+ ref = true
+--
+2.40.0
+
new file mode 100644
@@ -0,0 +1,37 @@
+From 4444a04ece4c02a7bd51e8c75623f22dc12d882b Mon Sep 17 00:00:00 2001
+From: Sutou Kouhei <kou@clear-code.com>
+Date: Sun, 2 Jun 2024 16:59:16 +0900
+Subject: [PATCH] Add missing encode for custom term
+
+CVE: CVE-2024-41123
+
+Upstream-Status: Backport [https://github.com/ruby/rexml/commit/4444a04ece4c02a7bd51e8c75623f22dc12d882b]
+
+Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
+---
+ .bundle/gems/rexml-3.2.5/lib/rexml/source.rb | 2 ++
+ 1 file changed, 2 insertions(+)
+
+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 08a035c..7be430a 100644
+--- a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
++++ b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
+@@ -160,6 +160,7 @@ module REXML
+ end
+
+ def read(term = nil)
++ term = encode(term) if term
+ begin
+ @scanner << readline(term)
+ true
+@@ -171,6 +172,7 @@ module REXML
+
+ def read_until(term)
+ pattern = Regexp.union(term)
++ term = encode(term)
+ data = []
+ begin
+ until str = @scanner.scan_until(pattern)
+--
+2.40.0
+
new file mode 100644
@@ -0,0 +1,55 @@
+From ebc3e85bfa2796fb4922c1932760bec8390ff87c Mon Sep 17 00:00:00 2001
+From: NAITOH Jun <naitoh@gmail.com>
+Date: Mon, 8 Jul 2024 05:54:06 +0900
+Subject: [PATCH] Add position check for XML declaration (#162)
+
+XML declaration must be the first item.
+
+https://www.w3.org/TR/2006/REC-xml11-20060816/#document
+
+```
+[1] document ::= ( prolog element Misc* ) - ( Char* RestrictedChar Char* )
+```
+
+https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-prolog
+
+```
+[22] prolog ::= XMLDecl Misc* (doctypedecl Misc*)?
+```
+
+https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-XMLDecl
+
+```
+[23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+```
+
+See: https://github.com/ruby/rexml/pull/161#discussion_r1666118193
+
+CVE: CVE-2024-41123
+
+Upstream-Status: Backport [https://github.com/ruby/rexml/commit/ebc3e85bfa2796fb4922c1932760bec8390ff87c]
+
+Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
+---
+ .bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+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 451fbf8..71fce99 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
+@@ -670,7 +670,10 @@ module REXML
+ @source.position = start_position
+ raise REXML::ParseException.new(message, @source)
+ end
+- if @document_status.nil? and match_data[1] == "xml"
++ if match_data[1] == "xml"
++ if @document_status
++ raise ParseException.new("Malformed XML: XML declaration is not at the start", @source)
++ end
+ content = match_data[2]
+ version = VERSION.match(content)
+ version = version[1] unless version.nil?
+--
+2.40.0
+
new file mode 100644
@@ -0,0 +1,163 @@
+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
+
new file mode 100644
@@ -0,0 +1,111 @@
+From e2546e6ecade16b04c9ee528e5be8509fe16c2d6 Mon Sep 17 00:00:00 2001
+From: Sutou Kouhei <kou@clear-code.com>
+Date: Thu, 1 Aug 2024 11:23:43 +0900
+Subject: [PATCH] parse pi: improve invalid case detection
+
+CVE: CVE-2024-41123
+
+Upstream-Status: Backport [https://github.com/ruby/rexml/commit/e2546e6ecade16b04c9ee528e5be8509fe16c2d6]
+
+Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
+---
+ .../lib/rexml/parsers/baseparser.rb | 35 +++++++++++--------
+ 1 file changed, 20 insertions(+), 15 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 c1a22b8..0ece9b5 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,11 +124,10 @@ module REXML
+ }
+
+ module Private
+- INSTRUCTION_END = /#{NAME}(\s+.*?)?\?>/um
+ TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um
+ CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um
+ ATTLISTDECL_END = /\s+#{NAME}(?:#{ATTDEF})*\s*>/um
+- NAME_PATTERN = /\s*#{NAME}/um
++ NAME_PATTERN = /#{NAME}/um
+ GEDECL_PATTERN = "\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
+ PEDECL_PATTERN = "\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
+ ENTITYDECL_PATTERN = /(?:#{GEDECL_PATTERN})|(?:#{PEDECL_PATTERN})/um
+@@ -233,7 +232,7 @@ module REXML
+ if @document_status == nil
+ start_position = @source.position
+ if @source.match("<?", true)
+- return process_instruction(start_position)
++ return process_instruction
+ elsif @source.match("<!", true)
+ if @source.match("--", true)
+ md = @source.match(/(.*?)-->/um, true)
+@@ -424,7 +423,7 @@ module REXML
+ raise REXML::ParseException.new( "Declarations can only occur "+
+ "in the doctype declaration.", @source)
+ elsif @source.match("?", true)
+- return process_instruction(start_position)
++ return process_instruction
+ else
+ # Get the next tag
+ md = @source.match(TAG_PATTERN, true)
+@@ -579,14 +578,14 @@ module REXML
+ def parse_name(base_error_message)
+ md = @source.match(NAME_PATTERN, true)
+ unless md
+- if @source.match(/\s*\S/um)
++ if @source.match(/\S/um)
+ message = "#{base_error_message}: invalid name"
+ else
+ message = "#{base_error_message}: name is missing"
+ end
+ raise REXML::ParseException.new(message, @source)
+ end
+- md[1]
++ md[0]
+ end
+
+ def parse_id(base_error_message,
+@@ -655,18 +654,24 @@ module REXML
+ end
+ end
+
+- def process_instruction(start_position)
+- match_data = @source.match(Private::INSTRUCTION_END, true)
+- unless match_data
+- message = "Invalid processing instruction node"
+- @source.position = start_position
+- raise REXML::ParseException.new(message, @source)
++ def process_instruction
++ name = parse_name("Malformed XML: Invalid processing instruction node")
++ if @source.match(/\s+/um, true)
++ match_data = @source.match(/(.*?)\?>/um, true)
++ unless match_data
++ raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
++ end
++ content = match_data[1]
++ else
++ content = nil
++ unless @source.match("?>", true)
++ raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
++ end
+ end
+- if match_data[1] == "xml"
++ if name == "xml"
+ if @document_status
+ raise ParseException.new("Malformed XML: XML declaration is not at the start", @source)
+ end
+- content = match_data[2]
+ version = VERSION.match(content)
+ version = version[1] unless version.nil?
+ encoding = ENCODING.match(content)
+@@ -681,7 +686,7 @@ module REXML
+ standalone = standalone[1] unless standalone.nil?
+ return [ :xmldecl, version, encoding, standalone ]
+ end
+- [:processing_instruction, match_data[1], match_data[2]]
++ [:processing_instruction, name, content]
+ end
+
+ def parse_attributes(prefixes)
+--
+2.40.0
+
@@ -66,6 +66,11 @@ SRC_URI = "http://cache.ruby-lang.org/pub/ruby/${SHRT_VER}/ruby-${PV}.tar.gz \
file://CVE-2024-39908-0010.patch \
file://CVE-2024-39908-0011.patch \
file://CVE-2024-39908-0012.patch \
+ file://CVE-2024-41123-0001.patch \
+ file://CVE-2024-41123-0002.patch \
+ file://CVE-2024-41123-0003.patch \
+ file://CVE-2024-41123-0004.patch \
+ file://CVE-2024-41123-0005.patch \
"
UPSTREAM_CHECK_URI = "https://www.ruby-lang.org/en/downloads/"