Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RuntimeError in REXML::Parsers::BaseParser for valid feeds #199

Merged
merged 6 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions lib/rexml/parsers/baseparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,13 @@ def pull_event
private :pull_event

def entity( reference, entities )
value = nil
vikiv480 marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
30 changes: 30 additions & 0 deletions test/test_pullparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,36 @@ def test_with_default_entity
end
end

def test_with_only_default_entities
member_value = "<p>#{'A' * @default_entity_expansion_text_limit}</p>"
source = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
<member>
#{member_value}
</member>
XML

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

expected_value = "<p>#{'A' * @default_entity_expansion_text_limit}</p>"
assert_equal(expected_value, events['member'].strip)
assert_equal(0, parser.entity_expansion_count)
assert do
events['member'].bytesize > @default_entity_expansion_text_limit
end
end

def test_entity_expansion_text_limit
source = <<-XML
<!DOCTYPE member [
Expand Down
24 changes: 24 additions & 0 deletions test/test_sax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,30 @@ def test_with_default_entity
end
end

def test_with_only_default_entities
member_value = "&lt;p&gt;#{'A' * @default_entity_expansion_text_limit}&lt;/p&gt;"
source = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
<member>
#{member_value}
</member>
XML

sax = REXML::Parsers::SAX2Parser.new(source)
text_value = nil
sax.listen(:characters, ["member"]) do |text|
text_value = text
end
sax.parse

expected_value = "<p>#{'A' * @default_entity_expansion_text_limit}</p>"
assert_equal(expected_value, text_value.strip)
assert_equal(0, sax.entity_expansion_count)
assert do
text_value.bytesize > @default_entity_expansion_text_limit
end
end

def test_entity_expansion_text_limit
source = <<-XML
<!DOCTYPE member [
Expand Down
38 changes: 38 additions & 0 deletions test/test_stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,44 @@ def entity(content)
end
end

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

def test_with_only_default_entities
member_value = "&lt;p&gt;#{'A' * @default_entity_expansion_text_limit}&lt;/p&gt;"
source = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
<member>
#{member_value}
</member>
XML

listener = MyListener.new
class << listener
attr_accessor :text_value
def text(text)
@text_value << text
end
end
listener.text_value = ""
REXML::Document.parse_stream(source, listener)

expected_value = "<p>#{'A' * @default_entity_expansion_text_limit}</p>"
assert_equal(expected_value, listener.text_value.strip)
assert do
listener.text_value.bytesize > @default_entity_expansion_text_limit
end
end
end

kou marked this conversation as resolved.
Show resolved Hide resolved

# For test_listener
class RequestReader
Expand Down