Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
49c1c30b31
!245 fix CVE-2025-27219 CVE-2025-27220 CVE-2025-27221
From: @tong_1001 
Reviewed-by: @shenyangyang01 
Signed-off-by: @shenyangyang01
2025-03-07 03:22:02 +00:00
shixuantong
08c26fba6c fix CVE-2025-27219 CVE-2025-27220 CVE-2025-27221 2025-03-07 09:46:06 +08:00
openeuler-ci-bot
7b054b4a3c
!236 [sync] PR-234: fix CVE-2025-25186
From: @openeuler-sync-bot 
Reviewed-by: @shenyangyang01 
Signed-off-by: @shenyangyang01
2025-02-25 08:17:33 +00:00
shixuantong
7c15f8745c fix CVE-2025-25186
(cherry picked from commit 9d1564fe1e9cd5db7988e1bd4a6a902a930e16b8)
2025-02-25 15:09:36 +08:00
openeuler-ci-bot
903b11a397
!223 fix CVE-2024-49761
From: @tong_1001 
Reviewed-by: @shinwell_hu 
Signed-off-by: @shinwell_hu
2024-10-30 10:04:27 +00:00
shixuantong
1c2d20f9fb fix CVE-2024-49761 2024-10-29 19:25:06 +08:00
openeuler-ci-bot
2c685aa253
!218 [sync] PR-217: fix CVE-2024-47220
From: @openeuler-sync-bot 
Reviewed-by: @shinwell_hu 
Signed-off-by: @shinwell_hu
2024-10-08 10:31:48 +00:00
shixuantong
1542b4ca44 fix CVE-2024-47220
(cherry picked from commit 39817c21d36696bc945f8e42fdde789a38c3dbdb)
2024-10-08 18:05:18 +08:00
openeuler-ci-bot
d9ba86fcea
!206 [sync] PR-204: upgrade rexml to fix CVE-2024-39908 CVE-2024-41123 CVE-2024-43398
From: @openeuler-sync-bot 
Reviewed-by: @small_leek 
Signed-off-by: @small_leek
2024-09-02 08:13:57 +00:00
shixuantong
e04b61b380 upgrade rexml to fix CVE-2024-39908 CVE-2024-41123 CVE-2024-43398
(cherry picked from commit b3848293a70017a11aebbd45e3f7db6be5dea235)
2024-08-29 14:47:41 +08:00
10 changed files with 1370 additions and 1 deletions

View File

@ -0,0 +1,53 @@
From 4263c0d15a582b46d75aac57cd26a47d33941a53 Mon Sep 17 00:00:00 2001
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
Date: Fri, 21 Feb 2025 16:29:36 +0900
Subject: [PATCH] Truncate userinfo with URI#join, URI#merge and URI#+
---
lib/uri/generic.rb | 6 +++++-
test/uri/test_generic.rb | 11 +++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index 69698c4..7d0b889 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -1141,7 +1141,11 @@ module URI
end
# RFC2396, Section 5.2, 7)
- base.set_userinfo(rel.userinfo) if rel.userinfo
+ if rel.userinfo
+ base.set_userinfo(rel.userinfo)
+ else
+ base.set_userinfo(nil)
+ end
base.set_host(rel.host) if rel.host
base.set_port(rel.port) if rel.port
base.query = rel.query if rel.query
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index 3897c3d..30f9cbf 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -164,6 +164,17 @@ class URI::TestGeneric < Test::Unit::TestCase
# must be empty string to identify as path-abempty, not path-absolute
assert_equal('', url.host)
assert_equal('http:////example.com', url.to_s)
+
+ # sec-2957667
+ url = URI.parse('http://user:pass@example.com').merge('//example.net')
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
+ url = URI.join('http://user:pass@example.com', '//example.net')
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
+ url = URI.parse('http://user:pass@example.com') + '//example.net'
+ assert_equal('http://example.net', url.to_s)
+ assert_nil(url.userinfo)
end
def test_parse_scheme_with_symbols
--
2.33.0

View File

@ -0,0 +1,68 @@
From 58adef476ef4b5e6deefaf92e7594ab29396c624 Mon Sep 17 00:00:00 2001
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
Date: Fri, 21 Feb 2025 18:16:28 +0900
Subject: [PATCH] Fix merger of URI with authority component
https://hackerone.com/reports/2957667
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
---
lib/uri/generic.rb | 19 +++++++------------
test/uri/test_generic.rb | 7 +++++++
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index 7d0b889..f7eed57 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -1133,21 +1133,16 @@ module URI
base.fragment=(nil)
# RFC2396, Section 5.2, 4)
- if !authority
- base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
- else
- # RFC2396, Section 5.2, 4)
- base.set_path(rel.path) if rel.path
+ if authority
+ base.set_userinfo(rel.userinfo)
+ base.set_host(rel.host)
+ base.set_port(rel.port || base.default_port)
+ base.set_path(rel.path)
+ elsif base.path && rel.path
+ base.set_path(merge_path(base.path, rel.path))
end
# RFC2396, Section 5.2, 7)
- if rel.userinfo
- base.set_userinfo(rel.userinfo)
- else
- base.set_userinfo(nil)
- end
- base.set_host(rel.host) if rel.host
- base.set_port(rel.port) if rel.port
base.query = rel.query if rel.query
base.fragment=(rel.fragment) if rel.fragment
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index 30f9cbf..4b5e12c 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -267,6 +267,13 @@ class URI::TestGeneric < Test::Unit::TestCase
assert_equal(u0, u1)
end
+ def test_merge_authority
+ u = URI.parse('http://user:pass@example.com:8080')
+ u0 = URI.parse('http://new.example.org/path')
+ u1 = u.merge('//new.example.org/path')
+ assert_equal(u0, u1)
+ end
+
def test_route
url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')
assert_equal('b.html', url.to_s)
--
2.33.0

View File

@ -0,0 +1,372 @@
From e4a067e11235a2ec7a00616d41350485e384ec05 Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@clear-code.com>
Date: Thu, 1 Aug 2024 11:51:33 +0900
Subject: [PATCH] Add 3.3.3 entry
---
.../lib/rexml/formatters/pretty.rb | 2 +-
.../lib/rexml/parsers/baseparser.rb | 67 ++++++++++++++-----
.../lib/rexml/parsers/sax2parser.rb | 21 +-----
.../lib/rexml/parsers/streamparser.rb | 4 +-
.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb | 2 +-
.bundle/gems/rexml-3.2.5/lib/rexml/source.rb | 22 ++++--
.bundle/gems/rexml-3.2.5/lib/rexml/text.rb | 48 +++++++++----
7 files changed, 105 insertions(+), 61 deletions(-)
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb
index a1198b7..a838d83 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb
@@ -111,7 +111,7 @@ module REXML
# itself, then we don't need a carriage return... which makes this
# logic more complex.
node.children.each { |child|
- next if child == node.children[-1] and child.instance_of?(Text)
+ next if child.instance_of?(Text)
unless child == node.children[0] or child.instance_of?(Text) or
(child == node.children[1] and !node.children[0].writethis)
output << "\n"
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 617a3d5..44dc658 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
@@ -159,6 +158,7 @@ module REXML
def stream=( source )
@source = SourceFactory.create_from( source )
@closed = nil
+ @have_root = false
@document_status = nil
@tags = []
@stack = []
@@ -241,7 +241,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)
@@ -311,7 +311,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).captures.compact]
+ match_data = @source.match(Private::ENTITYDECL_PATTERN, true)
+ 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
@@ -343,7 +347,7 @@ module REXML
contents = md[0]
pairs = {}
- values = md[0].scan( ATTDEF_RE )
+ values = md[0].strip.scan( ATTDEF_RE )
values.each do |attdef|
unless attdef[3] == "#IMPLIED"
attdef.compact!
@@ -437,7 +441,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(Private::TAG_PATTERN, true)
@@ -462,8 +466,12 @@ module REXML
@closed = tag
@nsstack.shift
else
+ if @tags.empty? and @have_root
+ raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source)
+ end
@tags.push( tag )
end
+ @have_root = true
return [ :start_element, tag, attributes ]
end
else
@@ -471,6 +479,16 @@ module REXML
if text.chomp!("<")
@source.position -= "<".bytesize
end
+ if @tags.empty?
+ unless /\A\s*\z/.match?(text)
+ if @have_root
+ raise ParseException.new("Malformed XML: Extra content at the end of the document (got '#{text}')", @source)
+ else
+ raise ParseException.new("Malformed XML: Content at the start of the document (got '#{text}')", @source)
+ end
+ end
+ return pull_event if @have_root
+ end
return [ :text, text ]
end
rescue REXML::UndefinedNamespaceException
@@ -515,7 +533,11 @@ module REXML
# Unescapes all possible entities
def unnormalize( string, entities=nil, filter=nil )
- rv = string.gsub( Private::CARRIAGE_RETURN_NEWLINE_PATTERN, "\n" )
+ if string.include?("\r")
+ rv = string.gsub( Private::CARRIAGE_RETURN_NEWLINE_PATTERN, "\n" )
+ else
+ rv = string.dup
+ end
matches = rv.scan( REFERENCE_RE )
return rv if matches.size == 0
rv.gsub!( Private::CHARACTER_REFERENCES ) {
@@ -565,14 +587,14 @@ module REXML
def parse_name(base_error_message)
md = @source.match(Private::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,
@@ -641,15 +663,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 @document_status.nil? and match_data[1] == "xml"
- content = match_data[2]
+ if name == "xml"
+ if @document_status
+ raise ParseException.new("Malformed XML: XML declaration is not at the start", @source)
+ end
version = VERSION.match(content)
version = version[1] unless version.nil?
encoding = ENCODING.match(content)
@@ -664,7 +695,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, curr_ns)
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb
index 01cb469..cec9d2f 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb
@@ -161,25 +161,8 @@ module REXML
end
end
when :text
- #normalized = @parser.normalize( event[1] )
- #handle( :characters, normalized )
- copy = event[1].clone
-
- esub = proc { |match|
- if @entities.has_key?($1)
- @entities[$1].gsub(Text::REFERENCE, &esub)
- else
- match
- end
- }
-
- copy.gsub!( Text::REFERENCE, &esub )
- copy.gsub!( Text::NUMERICENTITY ) {|m|
- m=$1
- m = "0#{m}" if m[0] == ?x
- [Integer(m)].pack('U*')
- }
- handle( :characters, copy )
+ unnormalized = @parser.unnormalize( event[1], @entities )
+ handle( :characters, unnormalized )
when :entitydecl
handle_entitydecl( event )
when :processing_instruction, :comment, :attlistdecl,
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
index 9e0eb0b..fa3ac49 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
@@ -36,8 +36,8 @@ module REXML
@listener.tag_end( event[1] )
@tag_stack.pop
when :text
- normalized = @parser.unnormalize( event[1] )
- @listener.text( normalized )
+ unnormalized = @parser.unnormalize( event[1] )
+ @listener.text( unnormalized )
when :processing_instruction
@listener.instruction( *event[1,2] )
when :start_doctype
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
index 3af03ec..39e92a5 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
@@ -31,7 +31,7 @@
module REXML
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
DATE = "2008/019"
- VERSION = "3.3.1"
+ VERSION = "3.3.3"
REVISION = ""
Copyright = COPYRIGHT
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 5715c35..ff887fc 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
@@ -204,10 +204,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
@@ -237,10 +247,9 @@ module REXML
read if @scanner.eos? && @source
end
- # Note: When specifying a string for 'pattern', it must not include '>' except in the following formats:
- # - ">"
- # - "XXX>" (X is any string excluding '>')
def match( pattern, cons=false )
+ # To avoid performance issue, we need to increase bytes to read per scan
+ min_bytes = 1
while true
if cons
md = @scanner.scan(pattern)
@@ -250,7 +259,8 @@ module REXML
break if md
return nil if pattern.is_a?(String)
return nil if @source.nil?
- return nil unless read
+ return nil unless read(nil, min_bytes)
+ min_bytes *= 2
end
md.nil? ? nil : @scanner
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/text.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/text.rb
index b47bad3..7e0befe 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/text.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/text.rb
@@ -151,25 +151,45 @@ module REXML
end
end
- # context sensitive
- string.scan(pattern) do
- if $1[-1] != ?;
- raise "Illegal character #{$1.inspect} in raw string #{string.inspect}"
- elsif $1[0] == ?&
- if $5 and $5[0] == ?#
- case ($5[1] == ?x ? $5[2..-1].to_i(16) : $5[1..-1].to_i)
- when *VALID_CHAR
+ pos = 0
+ while (index = string.index(/<|&/, pos))
+ if string[index] == "<"
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
+ end
+
+ unless (end_index = string.index(/[^\s];/, index + 1))
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
+ end
+
+ value = string[(index + 1)..end_index]
+ if /\s/.match?(value)
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
+ end
+
+ if value[0] == "#"
+ character_reference = value[1..-1]
+
+ unless (/\A(\d+|x[0-9a-fA-F]+)\z/.match?(character_reference))
+ if character_reference[0] == "x" || character_reference[-1] == "x"
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
else
- raise "Illegal character #{$1.inspect} in raw string #{string.inspect}"
+ raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
end
- # FIXME: below can't work but this needs API change.
- # elsif @parent and $3 and !SUBSTITUTES.include?($1)
- # if !doctype or !doctype.entities.has_key?($3)
- # raise "Undeclared entity '#{$1}' in raw string \"#{string}\""
- # end
end
+
+ case (character_reference[0] == "x" ? character_reference[1..-1].to_i(16) : character_reference[0..-1].to_i)
+ when *VALID_CHAR
+ else
+ raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
+ end
+ elsif !(/\A#{Entity::NAME}\z/um.match?(value))
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
end
+
+ pos = end_index + 1
end
+
+ string
end
def node_type
--
2.27.0

View File

@ -0,0 +1,524 @@
From 95871f399eda642a022b03550479b7994895c742 Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@clear-code.com>
Date: Thu, 22 Aug 2024 09:54:49 +0900
Subject: [PATCH] Add 3.3.6 entry
---
.bundle/gems/rexml-3.2.5/lib/rexml/element.rb | 30 ++--
.bundle/gems/rexml-3.2.5/lib/rexml/entity.rb | 52 +------
.../lib/rexml/parsers/baseparser.rb | 139 +++++++++++++-----
.../lib/rexml/parsers/streamparser.rb | 16 +-
.../lib/rexml/parsers/treeparser.rb | 7 -
.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb | 2 +-
6 files changed, 131 insertions(+), 115 deletions(-)
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/element.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/element.rb
index a5808d7..4e3a60b 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/element.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/element.rb
@@ -441,9 +441,14 @@ module REXML
# Related: #root_node, #document.
#
def root
- return elements[1] if self.kind_of? Document
- return self if parent.kind_of? Document or parent.nil?
- return parent.root
+ target = self
+ while target
+ return target.elements[1] if target.kind_of? Document
+ parent = target.parent
+ return target if parent.kind_of? Document or parent.nil?
+ target = parent
+ end
+ nil
end
# :call-seq:
@@ -619,8 +624,12 @@ module REXML
else
prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
end
- ns = attributes[ prefix ]
- ns = parent.namespace(prefix) if ns.nil? and parent
+ ns = nil
+ target = self
+ while ns.nil? and target
+ ns = target.attributes[prefix]
+ target = target.parent
+ end
ns = '' if ns.nil? and prefix == 'xmlns'
return ns
end
@@ -2375,17 +2384,6 @@ module REXML
elsif old_attr.kind_of? Hash
old_attr[value.prefix] = value
elsif old_attr.prefix != value.prefix
- # Check for conflicting namespaces
- if value.prefix != "xmlns" and old_attr.prefix != "xmlns"
- old_namespace = old_attr.namespace
- new_namespace = value.namespace
- if old_namespace == new_namespace
- raise ParseException.new(
- "Namespace conflict in adding attribute \"#{value.name}\": "+
- "Prefix \"#{old_attr.prefix}\" = \"#{old_namespace}\" and "+
- "prefix \"#{value.prefix}\" = \"#{new_namespace}\"")
- end
- end
store value.name, {old_attr.prefix => old_attr,
value.prefix => value}
else
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/entity.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/entity.rb
index 573db69..12bbad3 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/entity.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/entity.rb
@@ -12,6 +12,7 @@ module REXML
EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
NDATADECL = "\\s+NDATA\\s+#{NAME}"
PEREFERENCE = "%#{NAME};"
+ PEREFERENCE_RE = /#{PEREFERENCE}/um
ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
@@ -19,7 +20,7 @@ module REXML
GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
- attr_reader :name, :external, :ref, :ndata, :pubid
+ attr_reader :name, :external, :ref, :ndata, :pubid, :value
# Create a new entity. Simple entities can be constructed by passing a
# name, value to the constructor; this creates a generic, plain entity
@@ -68,14 +69,11 @@ module REXML
end
# Evaluates to the unnormalized value of this entity; that is, replacing
- # all entities -- both %ent; and &ent; entities. This differs from
- # +value()+ in that +value+ only replaces %ent; entities.
+ # &ent; entities.
def unnormalized
document.record_entity_expansion unless document.nil?
- v = value()
- return nil if v.nil?
- @unnormalized = Text::unnormalize(v, parent)
- @unnormalized
+ return nil if @value.nil?
+ @unnormalized = Text::unnormalize(@value, parent)
end
#once :unnormalized
@@ -121,46 +119,6 @@ module REXML
write rv
rv
end
-
- PEREFERENCE_RE = /#{PEREFERENCE}/um
- # Returns the value of this entity. At the moment, only internal entities
- # are processed. If the value contains internal references (IE,
- # %blah;), those are replaced with their values. IE, if the doctype
- # contains:
- # <!ENTITY % foo "bar">
- # <!ENTITY yada "nanoo %foo; nanoo>
- # then:
- # doctype.entity('yada').value #-> "nanoo bar nanoo"
- def value
- @resolved_value ||= resolve_value
- end
-
- def parent=(other)
- @resolved_value = nil
- super
- end
-
- private
- def resolve_value
- return nil if @value.nil?
- return @value unless @value.match?(PEREFERENCE_RE)
-
- matches = @value.scan(PEREFERENCE_RE)
- rv = @value.clone
- if @parent
- sum = 0
- matches.each do |entity_reference|
- entity_value = @parent.entity( entity_reference[0] )
- if sum + entity_value.bytesize > Security.entity_expansion_text_limit
- raise "entity expansion has grown too large"
- else
- sum += entity_value.bytesize
- end
- rv.gsub!( /%#{entity_reference.join};/um, entity_value )
- end
- end
- rv
- end
end
# This is a set of entity constants -- the ones defined in the XML
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 44dc658..d11c276 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
@@ -1,12 +1,29 @@
# frozen_string_literal: true
require_relative '../parseexception'
require_relative '../undefinednamespaceexception'
+require_relative '../security'
require_relative '../source'
require 'set'
require "strscan"
module REXML
module Parsers
+ unless [].respond_to?(:tally)
+ module EnumerableTally
+ refine Enumerable do
+ def tally
+ counts = {}
+ each do |item|
+ counts[item] ||= 0
+ counts[item] += 1
+ end
+ counts
+ end
+ end
+ end
+ using EnumerableTally
+ end
+
if StringScanner::Version < "3.0.8"
module StringScannerCaptures
refine StringScanner do
@@ -124,6 +141,7 @@ module REXML
}
module Private
+ PEREFERENCE_PATTERN = /#{PEREFERENCE}/um
TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um
CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um
ATTLISTDECL_END = /\s+#{NAME}(?:#{ATTDEF})*\s*>/um
@@ -163,7 +181,8 @@ module REXML
@tags = []
@stack = []
@entities = []
- @nsstack = []
+ @namespaces = {}
+ @namespaces_restore_stack = []
end
def position
@@ -231,6 +250,10 @@ module REXML
if @document_status == :in_doctype
raise ParseException.new("Malformed DOCTYPE: unclosed", @source)
end
+ unless @tags.empty?
+ path = "/" + @tags.join("/")
+ raise ParseException.new("Missing end tag for '#{path}'", @source)
+ end
return [ :end_document ]
end
return @stack.shift if @stack.size > 0
@@ -263,7 +286,6 @@ module REXML
@source.position = start_position
raise REXML::ParseException.new(message, @source)
end
- @nsstack.unshift(Set.new)
name = parse_name(base_error_message)
if @source.match(/\s*\[/um, true)
id = [nil, nil, nil]
@@ -333,6 +355,8 @@ module REXML
match[4] = match[4][1..-2] # HREF
match.delete_at(5) if match.size > 5 # Chop out NDATA decl
# match is [ :entity, name, PUBLIC, pubid, href(, ndata)? ]
+ elsif Private::PEREFERENCE_PATTERN.match?(match[2])
+ raise REXML::ParseException.new("Parameter entity references forbidden in internal subset: #{match[2]}", @source)
else
match[2] = match[2][1..-2]
match.pop if match.size == 4
@@ -355,7 +379,7 @@ module REXML
val = attdef[4] if val == "#FIXED "
pairs[attdef[0]] = val
if attdef[0] =~ /^xmlns:(.*)/
- @nsstack[0] << $1
+ @namespaces[$1] = val
end
end
end
@@ -408,7 +432,7 @@ module REXML
# here explicitly.
@source.ensure_buffer
if @source.match("/", true)
- @nsstack.shift
+ @namespaces_restore_stack.pop
last_tag = @tags.pop
md = @source.match(Private::CLOSE_PATTERN, true)
if md and !last_tag
@@ -453,18 +477,18 @@ module REXML
@document_status = :in_element
@prefixes.clear
@prefixes << md[2] if md[2]
- @nsstack.unshift(curr_ns=Set.new)
- attributes, closed = parse_attributes(@prefixes, curr_ns)
+ push_namespaces_restore
+ attributes, closed = parse_attributes(@prefixes)
# Verify that all of the prefixes have been defined
for prefix in @prefixes
- unless @nsstack.find{|k| k.member?(prefix)}
+ unless @namespaces.key?(prefix)
raise UndefinedNamespaceException.new(prefix,@source,self)
end
end
if closed
@closed = tag
- @nsstack.shift
+ pop_namespaces_restore
else
if @tags.empty? and @have_root
raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source)
@@ -504,15 +528,13 @@ module REXML
private :pull_event
def entity( reference, entities )
- value = nil
- value = entities[ reference ] if entities
- if value
- record_entity_expansion
- else
- value = DEFAULT_ENTITIES[ reference ]
- value = value[2] if value
- end
- unnormalize( value, entities ) if value
+ return unless entities
+
+ value = entities[ reference ]
+ return if value.nil?
+
+ record_entity_expansion
+ unnormalize( value, entities )
end
# Escapes all possible entities
@@ -546,22 +568,29 @@ module REXML
[Integer(m)].pack('U*')
}
matches.collect!{|x|x[0]}.compact!
+ if filter
+ matches.reject! do |entity_reference|
+ filter.include?(entity_reference)
+ end
+ end
if matches.size > 0
- sum = 0
- matches.each do |entity_reference|
- unless filter and filter.include?(entity_reference)
- entity_value = entity( entity_reference, entities )
- if entity_value
- re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/
- rv.gsub!( re, entity_value )
- sum += rv.bytesize
- if sum > Security.entity_expansion_text_limit
- raise "entity expansion has grown too large"
- end
- else
- er = DEFAULT_ENTITIES[entity_reference]
- rv.gsub!( er[0], er[2] ) if er
+ matches.tally.each do |entity_reference, n|
+ entity_expansion_count_before = @entity_expansion_count
+ entity_value = entity( entity_reference, entities )
+ if entity_value
+ if n > 1
+ entity_expansion_count_delta =
+ @entity_expansion_count - entity_expansion_count_before
+ record_entity_expansion(entity_expansion_count_delta * (n - 1))
end
+ re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/
+ rv.gsub!( re, entity_value )
+ if rv.bytesize > Security.entity_expansion_text_limit
+ raise "entity expansion has grown too large"
+ end
+ else
+ er = DEFAULT_ENTITIES[entity_reference]
+ rv.gsub!( er[0], er[2] ) if er
end
end
rv.gsub!( Private::DEFAULT_ENTITIES_PATTERNS['amp'], '&' )
@@ -570,9 +599,34 @@ module REXML
end
private
+ def add_namespace(prefix, uri)
+ @namespaces_restore_stack.last[prefix] = @namespaces[prefix]
+ if uri.nil?
+ @namespaces.delete(prefix)
+ else
+ @namespaces[prefix] = uri
+ end
+ end
+
+ def push_namespaces_restore
+ namespaces_restore = {}
+ @namespaces_restore_stack.push(namespaces_restore)
+ namespaces_restore
+ end
- def record_entity_expansion
- @entity_expansion_count += 1
+ def pop_namespaces_restore
+ namespaces_restore = @namespaces_restore_stack.pop
+ namespaces_restore.each do |prefix, uri|
+ if uri.nil?
+ @namespaces.delete(prefix)
+ else
+ @namespaces[prefix] = uri
+ end
+ end
+ end
+
+ def record_entity_expansion(delta=1)
+ @entity_expansion_count += delta
if @entity_expansion_count > Security.entity_expansion_limit
raise "number of entity expansions exceeded, processing aborted."
end
@@ -698,8 +752,9 @@ module REXML
[:processing_instruction, name, content]
end
- def parse_attributes(prefixes, curr_ns)
+ def parse_attributes(prefixes)
attributes = {}
+ expanded_names = {}
closed = false
while true
if @source.match(">", true)
@@ -741,7 +796,7 @@ module REXML
"(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
raise REXML::ParseException.new( msg, @source, self)
end
- curr_ns << local_part
+ add_namespace(local_part, value)
elsif prefix
prefixes << prefix unless prefix == "xml"
end
@@ -751,6 +806,20 @@ module REXML
raise REXML::ParseException.new(msg, @source, self)
end
+ unless prefix == "xmlns"
+ uri = @namespaces[prefix]
+ expanded_name = [uri, local_part]
+ existing_prefix = expanded_names[expanded_name]
+ if existing_prefix
+ message = "Namespace conflict in adding attribute " +
+ "\"#{local_part}\": " +
+ "Prefix \"#{existing_prefix}\" = \"#{uri}\" and " +
+ "prefix \"#{prefix}\" = \"#{uri}\""
+ raise REXML::ParseException.new(message, @source, self)
+ end
+ expanded_names[expanded_name] = prefix
+ end
+
attributes[name] = value
else
message = "Invalid attribute name: <#{@source.buffer.split(%r{[/>\s]}).first}>"
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
index fa3ac49..7781fe4 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb
@@ -7,36 +7,33 @@ module REXML
def initialize source, listener
@listener = listener
@parser = BaseParser.new( source )
- @tag_stack = []
+ @entities = {}
end
def add_listener( listener )
@parser.add_listener( listener )
end
+ def entity_expansion_count
+ @parser.entity_expansion_count
+ end
+
def parse
# entity string
while true
event = @parser.pull
case event[0]
when :end_document
- unless @tag_stack.empty?
- tag_path = "/" + @tag_stack.join("/")
- raise ParseException.new("Missing end tag for '#{tag_path}'",
- @parser.source)
- end
return
when :start_element
- @tag_stack << event[1]
attrs = event[2].each do |n, v|
event[2][n] = @parser.unnormalize( v )
end
@listener.tag_start( event[1], attrs )
when :end_element
@listener.tag_end( event[1] )
- @tag_stack.pop
when :text
- unnormalized = @parser.unnormalize( event[1] )
+ unnormalized = @parser.unnormalize( event[1], @entities )
@listener.text( unnormalized )
when :processing_instruction
@listener.instruction( *event[1,2] )
@@ -48,6 +45,7 @@ module REXML
when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl
@listener.send( event[0].to_s, *event[1..-1] )
when :entitydecl, :notationdecl
+ @entities[ event[1] ] = event[2] if event.size == 3
@listener.send( event[0].to_s, event[1..-1] )
when :externalentity
entity_reference = event[1]
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb
index 0cb6f7c..4565a40 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb
@@ -15,7 +15,6 @@ module REXML
end
def parse
- tag_stack = []
entities = nil
begin
while true
@@ -23,19 +22,13 @@ module REXML
#STDERR.puts "TREEPARSER GOT #{event.inspect}"
case event[0]
when :end_document
- unless tag_stack.empty?
- raise ParseException.new("No close tag for #{@build_context.xpath}",
- @parser.source, @parser)
- end
return
when :start_element
- tag_stack.push(event[1])
el = @build_context = @build_context.add_element( event[1] )
event[2].each do |key, value|
el.attributes[key]=Attribute.new(key,value,self)
end
when :end_element
- tag_stack.pop
@build_context = @build_context.parent
when :text
if @build_context[-1].instance_of? Text
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
index 39e92a5..99d574b 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/rexml.rb
@@ -31,7 +31,7 @@
module REXML
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
DATE = "2008/019"
- VERSION = "3.3.3"
+ VERSION = "3.3.6"
REVISION = ""
Copyright = COPYRIGHT
--
2.27.0

View File

@ -0,0 +1,62 @@
From f5faca9222541591e1a7c3c97552ebb0c92733c7 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@jeremyevans.net>
Date: Wed, 18 Sep 2024 14:11:49 -0700
Subject: [PATCH] Prevent request smuggling
If a request has both a content-length and transfer-encoding
headers, return a 400 response. This is allowed by RFC 7230
section 3.3.3.3.
Fixes #145
---
tool/lib/webrick/httprequest.rb | 4 ++++
tool/test/webrick/test_httprequest.rb | 18 ++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/tool/lib/webrick/httprequest.rb b/tool/lib/webrick/httprequest.rb
index 5cf5844..820acb2 100644
--- a/tool/lib/webrick/httprequest.rb
+++ b/tool/lib/webrick/httprequest.rb
@@ -474,6 +474,10 @@ module WEBrick
def read_body(socket, block)
return unless socket
if tc = self['transfer-encoding']
+ if self['content-length']
+ raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
+ end
+
case tc
when /\Achunked\z/io then read_chunked(socket, block)
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
diff --git a/tool/test/webrick/test_httprequest.rb b/tool/test/webrick/test_httprequest.rb
index 855ff9d..cce9b91 100644
--- a/tool/test/webrick/test_httprequest.rb
+++ b/tool/test/webrick/test_httprequest.rb
@@ -81,6 +81,24 @@ GET /
}
end
+ def test_content_length_and_transfer_encoding_headers_smuggling
+ msg = <<~HTTP.gsub("\n", "\r\n")
+ POST /user HTTP/1.1
+ Content-Length: 28
+ Transfer-Encoding: chunked
+
+ 0
+
+ GET /admin HTTP/1.1
+
+ HTTP
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg))
+ assert_raise(WEBrick::HTTPStatus::BadRequest){
+ req.body
+ }
+ end
+
def test_parse_headers
msg = <<-_end_of_message_
GET /path HTTP/1.1
--
2.27.0

View File

@ -0,0 +1,38 @@
From ce59f2eb1aeb371fe1643414f06618dbe031979f Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@clear-code.com>
Date: Thu, 24 Oct 2024 14:45:31 +0900
Subject: [PATCH] parser: fix a bug that &#0x...; is accepted as a character
reference
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 7bd8adf..b4547ba 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
@@ -150,7 +150,7 @@ module REXML
PEDECL_PATTERN = "\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
ENTITYDECL_PATTERN = /(?:#{GEDECL_PATTERN})|(?:#{PEDECL_PATTERN})/um
CARRIAGE_RETURN_NEWLINE_PATTERN = /\r\n?/
- CHARACTER_REFERENCES = /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/
+ CHARACTER_REFERENCES = /&#((?:\d+)|(?:x[a-fA-F0-9]+));/
DEFAULT_ENTITIES_PATTERNS = {}
default_entities = ['gt', 'lt', 'quot', 'apos', 'amp']
default_entities.each do |term|
@@ -570,8 +570,12 @@ module REXML
return rv if matches.size == 0
rv.gsub!( Private::CHARACTER_REFERENCES ) {
m=$1
- m = "0#{m}" if m[0] == ?x
- [Integer(m)].pack('U*')
+ if m.start_with?("x")
+ code_point = Integer(m[1..-1], 16)
+ else
+ code_point = Integer(m, 10)
+ end
+ [code_point].pack('U*')
}
matches.collect!{|x|x[0]}.compact!
if filter
--
2.27.0

View File

@ -0,0 +1,123 @@
From 0dbb8eb72aa78b7ed0b01533388e69722d16b821 Mon Sep 17 00:00:00 2001
From: nick evans <nick@rubinick.dev>
Date: Wed, 8 Jan 2025 22:06:47 -0500
Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=92=20Prevent=20runaway=20memory?=
=?UTF-8?q?=20use=20when=20parsing=20uid-set?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reference:https://github.com/ruby/net-imap/commit/0dbb8eb72aa78b7ed0b01533388e69722d16b821
Conflict:not change test, the test/net/imap/ directory doesn't exist.
Problem
=========
The UID sets in UIDPlusData are stored as arrays of UIDs. In common
scenarios, copying between one and a few hundred emails at a time, this
is barely noticable. But the memory use expands _exponentially_.
This should not be an issue for _trusted_ servers, and (I assume)
compromised servers will be more interested in evading detection and
stealing your credentials and your email than in causing client Denial
of Service. Nevertheless, this is a very simple DoS attack against
clients connecting to untrusted servers (for example, a service that
connects to user-specified servers).
For example, assuming a 64-bit architecture, considering only the data
in the two arrays, assuming the arrays' internal capacity is no more
than needed, and ignoring the fixed cost of the response structs:
* 32 bytes expands to ~160KB (about 5000 times more):
`"* OK [COPYUID 1 1:9999 1:9999]\r\n"`
* 40 bytes expands to ~1.6GB (about 50 million times more):
`"* OK [COPYUID 1 1:99999999 1:99999999]\r\n"`
* In the worst scenario (uint32 max), 44 bytes expands to 64GiB in
memory, using over 1.5 billion times more to store than to send:
`"* OK [COPYUID 1 1:4294967295 1:4294967295]\r\n"`
Preferred fix
===============
The preferred fix is to store `uid-set` as a SequenceSet, not an array.
Unfortunately, this is not fully backwards compatible. For v0.4 and
v0.5, use `Config#parser_use_deprecated_uidplus_data` to false to use
AppendUIDData and CopyUIDData instead of UIDPlusData. Unless you are
_using_ UIDPLUS, this is completely safe. v0.6 will drop UIDPlusData.
Workaround
============
The simplest _partial_ fix (preserving full backward compatibility) is
to raise an error when the number of UIDs goes over some threshold, and
continue using arrays inside UIDPlusData.
For v0.3 (this commit) the maximum count is hard-coded to 10,000. This
is high enough that it should almost never be triggered by normal usage,
and low enough to be a less extreme problem. For v0.4 and v0.5, the
maximum array size is configurable, with a much lower default: 1000 for
v0.4 and 100 for v0.5. These are low enough that they are _unlikely_ to
cause a problem, but v0.4 and v0.5 can also use the newer AppendUIDData
and CopyUIDData classes.
However, because unhandled responses are stored on the `#responses`
hash, this can still be a problem. A malicious server could repeatedly
use 160Kb of client memory by sending only 32 bytes in a loop. To fully
solve this problem, a response handler must be added to prune excessive
APPENDUID/COPYUID responses as they are received.
Because unhandled responses have always been retained, managing
unhandled responses is already documented as necessary for long-lived
connections.
---
.../lib/net/imap/response_parser.rb | 26 ++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb b/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
index be1a849..0341356 100644
--- a/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
+++ b/.bundle/gems/net-imap-0.3.4/lib/net/imap/response_parser.rb
@@ -7,6 +7,8 @@ module Net
# Parses an \IMAP server response.
class ResponseParser
+ MAX_UID_SET_SIZE = 10_000
+
# :call-seq: Net::IMAP::ResponseParser.new -> Net::IMAP::ResponseParser
def initialize
@str = nil
@@ -1379,11 +1381,29 @@ module Net
case token.symbol
when T_NUMBER then [Integer(token.value)]
when T_ATOM
- token.value.split(",").flat_map {|range|
- range = range.split(":").map {|uniqueid| Integer(uniqueid) }
- range.size == 1 ? range : Range.new(range.min, range.max).to_a
+ entries = uid_set__ranges(token.value)
+ if (count = entries.sum(&:count)) > MAX_UID_SET_SIZE
+ parse_error("uid-set is too large: %d > 10k", count)
+ end
+ entries.flat_map(&:to_a)
+ end
+ end
+
+ # returns an array of ranges
+ def uid_set__ranges(uidset)
+ entries = []
+ uidset.split(",") do |entry|
+ uids = entry.split(":", 2).map {|uid|
+ unless uid =~ /\A[1-9][0-9]*\z/
+ parse_error("invalid uid-set uid: %p", uid)
+ end
+ uid = Integer(uid)
+ NumValidator.ensure_nz_number(uid)
+ uid
}
+ entries << Range.new(*uids.minmax)
end
+ entries
end
def nil_atom
--
2.27.0

View File

@ -0,0 +1,32 @@
From 2c2d89e7cce0c81d9e63bb29c0e65b0436885af1 Mon Sep 17 00:00:00 2001
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
Date: Fri, 21 Feb 2025 16:01:17 +0900
Subject: [PATCH 1/2] Use String#concat instead of String#+ for reducing cpu
usage
Co-authored-by: "Yusuke Endoh" <mame@ruby-lang.org>
---
lib/cgi/cookie.rb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index 9498e2f..1c4ef6a 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -190,9 +190,10 @@ class CGI
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
- values = cookies[name].value + values
+ cookies[name].concat(values)
+ else
+ cookies[name] = Cookie.new(name, *values)
end
- cookies[name] = Cookie.new(name, *values)
end
cookies
--
2.33.0

View File

@ -0,0 +1,73 @@
From da7aadf928d85ffdf594d7e77aed4a441f7c3ebb Mon Sep 17 00:00:00 2001
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
Date: Fri, 21 Feb 2025 15:53:31 +0900
Subject: [PATCH 2/2] Escape/unescape unclosed tags as well
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
---
lib/cgi/util.rb | 4 ++--
test/cgi/test_cgi_util.rb | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 5a5c77a..ce77a0c 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -178,7 +178,7 @@ module CGI::Util
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
+ string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
CGI.escapeHTML($&)
end
else
@@ -198,7 +198,7 @@ module CGI::Util
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/&lt;\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?&gt;/i) do
+ string.gsub(/&lt;\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:&gt;)?/im) do
unescapeHTML($&)
end
else
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index a3be193..d058ccc 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -244,6 +244,14 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]))
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', "A", "IMG"))
assert_equal("<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<BR><A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escapeElement('<A <A HREF="url"></A>', ["A", "IMG"]))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', "A", "IMG"))
+ assert_equal("&lt;A &lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;", escape_element('<A <A HREF="url"></A>', ["A", "IMG"]))
+
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', "A", "IMG"))
+ assert_equal("&lt;A &lt;A ", escapeElement('<A <A ', ["A", "IMG"]))
end
@@ -252,6 +260,16 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescapeElement(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG"))
assert_equal('&lt;BR&gt;<A HREF="url"></A>', unescape_element(escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescapeElement(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), "A", "IMG"))
+ assert_equal('<A <A HREF="url"></A>', unescape_element(escapeHTML('<A <A HREF="url"></A>'), ["A", "IMG"]))
+
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescapeElement(escapeHTML('<A <A '), ["A", "IMG"]))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), "A", "IMG"))
+ assert_equal('<A <A ', unescape_element(escapeHTML('<A <A '), ["A", "IMG"]))
end
end
--
2.33.0

View File

@ -33,7 +33,7 @@
Name: ruby
Version: %{ruby_version}
Release: 144
Release: 149
Summary: Object-oriented scripting language interpreter
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
URL: https://www.ruby-lang.org/en/
@ -99,6 +99,15 @@ Patch6022: backport-0004-CVE-2024-35221.patch
Patch6023: backport-0005-CVE-2024-35221.patch
Patch6024: upgrade-lib-rexml-to-3.3.1.patch
Patch6025: backport-CVE-2024-41946.patch
Patch6026: backport-CVE-2024-39908-CVE-2024-41123-upgrade-lib-rexml-to-3.3.3.patch
Patch6027: backport-CVE-2024-43398-upgrade-lib-rexml-to-3.3.6.patch
Patch6028: backport-CVE-2024-47220.patch
Patch6029: backport-CVE-2024-49761.patch
Patch6030: backport-CVE-2025-25186.patch
Patch6031: backport-CVE-2025-27219.patch
Patch6032: backport-CVE-2025-27220.patch
Patch6033: backport-0001-CVE-2025-27221.patch
Patch6034: backport-0002-CVE-2025-27221.patch
Provides: %{name}-libs = %{version}-%{release}
Obsoletes: %{name}-libs < %{version}-%{release}
@ -884,6 +893,21 @@ make runruby TESTRUN_SCRIPT=%{SOURCE13}
%{gem_dir}/specifications/matrix-%{matrix_version}.gemspec
%changelog
* Fri Feb 28 2025 shixuantong <shixuantong1@huawei.com> - 3.2.2-149
- fix CVE-2025-27219 CVE-2025-27220 CVE-2025-27221
* Sat Feb 22 2025 shixuantong <shixuantong1@huawei.com> - 3.2.2-148
- fix CVE-2025-25186
* Tue Oct 29 2024 shixuantong <shixuantong1@huawei.com> - 3.2.2-147
- fix CVE-2024-49761
* Tue Oct 08 2024 shixuantong <shixuantong1@huawei.com> - 3.2.2-146
- fix CVE-2024-47220
* Thu Aug 29 2024 shixuantong <shixuantong1@huawei.com> - 3.2.2-145
- upgrade rexml to fix CVE-2024-39908 CVE-2024-41123 CVE-2024-43398
* Wed Aug 14 2024 wangjiang <wangjiang37@h-partners.com> - 3.2.2-144
- License compliance rectification