From 033d1909a8f259d5a7c53681bcaf14f13bcf0368 Mon Sep 17 00:00:00 2001
From: NAITOH Jun <naitoh@gmail.com>
Date: Thu, 1 Aug 2024 09:20:31 +0900
Subject: [PATCH] Add support for XML entity expansion limitation in SAX and
 pull parsers (#187)
https://github.com/ruby/rexml/commit/033d1909a8f259d5a7c53681bcaf14f13bcf0368

- Supported `REXML::Security.entity_expansion_limit=` in SAX and pull parsers
- Supported `REXML::Security.entity_expansion_text_limit=` in SAX and pull parsers
---
 .bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb | 19 ++++++-
 .bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb |  4 ++
 .bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb |  4 ++
 3 files changed, 26 insertions(+), 1 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 54014e5..c4ddee3 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
@@ -154,6 +154,7 @@ module REXML
         self.stream = source
         @listeners = []
         @prefixes = Set.new
+        @entity_expansion_count = 0
       end
 
       def add_listener( listener )
@@ -161,6 +162,7 @@ module REXML
       end
 
       attr_reader :source
+      attr_reader :entity_expansion_count
 
       def stream=( source )
         @source = SourceFactory.create_from( source )
@@ -513,7 +515,9 @@ module REXML
       def entity( reference, entities )
         value = nil
         value = entities[ reference ] if entities
-        if not value
+        if value
+          record_entity_expansion
+        else
           value = DEFAULT_ENTITIES[ reference ]
           value = value[2] if value
         end
@@ -552,12 +556,17 @@ module REXML
         }
         matches.collect!{|x|x[0]}.compact!
         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
@@ -570,6 +579,14 @@ module REXML
       end
 
       private
+
+      def record_entity_expansion
+        @entity_expansion_count += 1
+        if @entity_expansion_count > Security.entity_expansion_limit
+          raise "number of entity expansions exceeded, processing aborted."
+        end
+      end
+
       def need_source_encoding_update?(xml_declaration_encoding)
         return false if xml_declaration_encoding.nil?
         return false if /\AUTF-16\z/i =~ xml_declaration_encoding
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb
index f8b232a..36b4595 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb
@@ -47,6 +47,10 @@ module REXML
         @listeners << listener
       end
 
+      def entity_expansion_count
+        @parser.entity_expansion_count
+      end
+
       def each
         while has_next?
           yield self.pull
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 36f98c2..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
@@ -22,6 +22,10 @@ module REXML
         @parser.source
       end
 
+      def entity_expansion_count
+        @parser.entity_expansion_count
+      end
+
       def add_listener( listener )
         @parser.add_listener( listener )
       end
-- 
2.20.1

