diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb index 28810bfa..342f9482 100644 --- a/lib/rexml/parsers/baseparser.rb +++ b/lib/rexml/parsers/baseparser.rb @@ -548,15 +548,13 @@ def unnormalize( string, entities=nil, filter=nil ) } 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 + if rv.bytesize > Security.entity_expansion_text_limit raise "entity expansion has grown too large" end else diff --git a/test/test_document.rb b/test/test_document.rb index 0764631d..72ec3579 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -33,10 +33,12 @@ def test_new class EntityExpansionLimitTest < Test::Unit::TestCase def setup @default_entity_expansion_limit = REXML::Security.entity_expansion_limit + @default_entity_expansion_text_limit = REXML::Security.entity_expansion_text_limit end def teardown REXML::Security.entity_expansion_limit = @default_entity_expansion_limit + REXML::Security.entity_expansion_text_limit = @default_entity_expansion_text_limit end class GeneralEntityTest < self @@ -126,6 +128,24 @@ def test_with_default_entity doc.root.children.first.value end end + + def test_entity_expansion_text_limit + xml = <<-XML + + + + + + +]> +&a; + XML + + REXML::Security.entity_expansion_text_limit = 90 + doc = REXML::Document.new(xml) + assert_equal(90, doc.root.children.first.value.bytesize) + end end class ParameterEntityTest < self diff --git a/test/test_pullparser.rb b/test/test_pullparser.rb index 55205af8..827fad1d 100644 --- a/test/test_pullparser.rb +++ b/test/test_pullparser.rb @@ -159,10 +159,12 @@ def test_peek class EntityExpansionLimitTest < Test::Unit::TestCase def setup @default_entity_expansion_limit = REXML::Security.entity_expansion_limit + @default_entity_expansion_text_limit = REXML::Security.entity_expansion_text_limit end def teardown REXML::Security.entity_expansion_limit = @default_entity_expansion_limit + REXML::Security.entity_expansion_text_limit = @default_entity_expansion_text_limit end class GeneralEntityTest < self @@ -249,6 +251,34 @@ def test_with_default_entity end end end + + def test_entity_expansion_text_limit + source = <<-XML + + + + + +]> +&a; + XML + + REXML::Security.entity_expansion_text_limit = 90 + parser = REXML::Parsers::PullParser.new(source) + events = {} + element_name = '' + while parser.has_next? + event = parser.pull + case event.event_type + when :start_element + element_name = event[0] + when :text + events[element_name] = event[1] + end + end + assert_equal(90, events['member'].size) + end end end end diff --git a/test/test_sax.rb b/test/test_sax.rb index 5e3ad75b..f452de50 100644 --- a/test/test_sax.rb +++ b/test/test_sax.rb @@ -102,10 +102,12 @@ def test_sax2 class EntityExpansionLimitTest < Test::Unit::TestCase def setup @default_entity_expansion_limit = REXML::Security.entity_expansion_limit + @default_entity_expansion_text_limit = REXML::Security.entity_expansion_text_limit end def teardown REXML::Security.entity_expansion_limit = @default_entity_expansion_limit + REXML::Security.entity_expansion_text_limit = @default_entity_expansion_text_limit end class GeneralEntityTest < self @@ -182,6 +184,28 @@ def test_with_default_entity sax.parse end end + + def test_entity_expansion_text_limit + source = <<-XML + + + + + +]> +&a; + XML + + REXML::Security.entity_expansion_text_limit = 90 + sax = REXML::Parsers::SAX2Parser.new(source) + text_size = nil + sax.listen(:characters, ["member"]) do |text| + text_size = text.size + end + sax.parse + assert_equal(90, text_size) + end end end