Repository navigation
Closed
Description
Describe the bug
I'm not completely familiar with this repo so please enlighten me if I'm wrong. I suspect sum is calculated incorrectly in #unnormalize. rv.bytesize is added multiple times over, even for matches that has already been substituted.
rexml/lib/rexml/parsers/baseparser.rb
Lines 550 to 569 in e3f747f
| 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 | |
| end | |
| end | |
| end | |
| rv.gsub!( Private::DEFAULT_ENTITIES_PATTERNS['amp'], '&' ) | |
| end |
How to reproduce
require "rexml/parsers/baseparser"
entity_less_than = "<"
entitiy_length = 100
filler_text = "A"
filler_length = 100
feed = "#{entity_less_than * entitiy_length}#{filler_text * filler_length}"
base_parser = REXML::Parsers::BaseParser.new("")
base_parser.unnormalize(feed) # => "<" * 100 + "A" * 100Error:
❯ bundle exec ruby test.rb
/Users/vikiv/.gem/ruby/3.1.2/gems/rexml-3.3.4/lib/rexml/parsers/baseparser.rb:560:in `block in unnormalize': entity expansion has grown too large (RuntimeError)
from /Users/vikiv/.gem/ruby/3.1.2/gems/rexml-3.3.4/lib/rexml/parsers/baseparser.rb:552:in `each'
from /Users/vikiv/.gem/ruby/3.1.2/gems/rexml-3.3.4/lib/rexml/parsers/baseparser.rb:552:in `unnormalize'
from test.rb:13:in `<main>'
Suggestion/fix
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
index 28810bf..e6d6ae6 100644
--- a/lib/rexml/parsers/baseparser.rb
+++ b/lib/rexml/parsers/baseparser.rb
@@ -549,7 +549,7 @@ module REXML
matches.collect!{|x|x[0]}.compact!
if matches.size > 0
sum = 0
- matches.each do |entity_reference|
+ matches.uniq.each do |entity_reference|
unless filter and filter.include?(entity_reference)
entity_value = entity( entity_reference, entities )
if entity_value
@@ -557,7 +557,7 @@ module REXML
rv.gsub!( re, entity_value )
sum += rv.bytesize
if sum > Security.entity_expansion_text_limit
- raise "entity expansion has grown too large"
+ # raise "entity expansion has grown too large"
end
else
er = DEFAULT_ENTITIES[entity_reference]
@@ -566,6 +566,7 @@ module REXML
end
end
rv.gsub!( Private::DEFAULT_ENTITIES_PATTERNS['amp'], '&' )
+ puts "Sum of entity expansions: #{sum}"
end
rv
endResult:
# Before change
❯ bundle exec ruby test.rb
Sum of entity expansions: 20000
# After change
❯ bundle exec ruby test.rb
Sum of entity expansions: 200Reacted by Dan Starner, Pontus4 and jaaechou
Reacted by Dan Starner, NAITOH Jun and jaaechou
Metadata
Metadata
Assignees
Labels
No labels
Activity
dstarner commentedon Aug 6, 2024
We are also encountering the
entity expansion has grown too largeexception on 3.3.4. Reverting back to 3.3.2 resolved the issue for us.Improve `#unnormalize` and fix `sum` calculation
otegami commentedon Aug 8, 2024
Below is an example of a problem you might encounter while using
REXML::Parsers::BaseParserto parse XML data. If this helps in any way, I'd be delighted.Fix calculation of Security.entity_expansion_text_limit in SAX/pull p…