ruby/test/rexml/test_entity.rb

207 строки
6.7 KiB
Ruby

# frozen_string_literal: false
require "test/unit/testcase"
require 'rexml/document'
require 'rexml/entity'
require 'rexml/source'
module REXMLTests
class EntityTester < Test::Unit::TestCase
def test_parse_general_decl
simple = "<!ENTITY foo 'bar'>"
simple =~ /#{REXML::Entity::GEDECL}/
assert $&
assert_equal simple, $&
REXML::Entity::ENTITYDECL =~ simple
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'foo', match[1]
assert_equal "'bar'", match[2]
simple = '<!ENTITY Pub-Status
"This is a pre-release of the specification.">'
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'Pub-Status', match[1]
assert_equal '"This is a pre-release of the specification."', match[2]
txt = '"This is a
pre-release of <the> specification."'
simple = "<!ENTITY Pub-Status
#{txt}>"
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'Pub-Status', match[1]
assert_equal txt, match[2]
end
def test_parse_external_decl
zero = '<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml" >'
one = '<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">'
two = '<!ENTITY open-hatch
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">'
three = '<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif >'
assert REXML::Entity::matches?(zero)
assert REXML::Entity::matches?(one)
assert REXML::Entity::matches?(two)
assert REXML::Entity::matches?(three)
end
def test_parse_entity
one = %q{<!ENTITY % YN '"Yes"'>}
two = %q{<!ENTITY WhatHeSaid "He said %YN;">}
assert REXML::Entity::matches?(one)
assert REXML::Entity::matches?(two)
end
def test_constructor
one = [ %q{<!ENTITY % YN '"Yes"'>},
%q{<!ENTITY % YN2 "Yes">},
%q{<!ENTITY WhatHeSaid "He said %YN;">},
'<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">',
'<!ENTITY open-hatch2
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">',
'<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif>' ]
source = %q{<!DOCTYPE foo [
<!ENTITY % YN '"Yes"'>
<!ENTITY % YN2 "Yes">
<!ENTITY WhatHeSaid "He said %YN;">
<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY open-hatch2
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif>
]>}
d = REXML::Document.new( source )
dt = d.doctype
c = 0
dt.each do |child|
if child.kind_of? REXML::Entity
str = one[c].tr("\r\n\t", ' ').squeeze(" ")
assert_equal str, child.to_s
c+=1
end
end
end
def test_replace_entities
source = "<!DOCTYPE blah [\n<!ENTITY foo \"bar\">\n]><a>&foo;</a>"
doc = REXML::Document.new(source)
assert_equal 'bar', doc.root.text
out = ''
doc.write out
assert_equal source, out
end
def test_entity_string_limit
template = '<!DOCTYPE bomb [ <!ENTITY a "^" > ]> <bomb>$</bomb>'
len = 5120 # 5k per entity
template.sub!(/\^/, "B" * len)
# 10k is OK
entities = '&a;' * 2 # 5k entity * 2 = 10k
xmldoc = REXML::Document.new(template.sub(/\$/, entities))
assert_equal(len * 2, xmldoc.root.text.bytesize)
# above 10k explodes
entities = '&a;' * 3 # 5k entity * 2 = 15k
xmldoc = REXML::Document.new(template.sub(/\$/, entities))
assert_raise(RuntimeError) do
xmldoc.root.text
end
end
def test_entity_string_limit_for_parameter_entity
template = '<!DOCTYPE bomb [ <!ENTITY % a "^" > <!ENTITY bomb "$" > ]><root/>'
len = 5120 # 5k per entity
template.sub!(/\^/, "B" * len)
# 10k is OK
entities = '%a;' * 2 # 5k entity * 2 = 10k
REXML::Document.new(template.sub(/\$/, entities))
# above 10k explodes
entities = '%a;' * 3 # 5k entity * 2 = 15k
assert_raise(REXML::ParseException) do
REXML::Document.new(template.sub(/\$/, entities))
end
end
def test_raw
source = '<!DOCTYPE foo [
<!ENTITY ent "replace">
]><a>replace &ent;</a>'
doc = REXML::Document.new( source, {:raw=>:all})
assert_equal('replace &ent;', doc.root.get_text.to_s)
assert_equal(source, doc.to_s)
end
def test_lazy_evaluation
source = '<!DOCTYPE foo [
<!ENTITY ent "replace">
]><a>replace &ent;</a>'
doc = REXML::Document.new( source )
assert_equal(source, doc.to_s)
assert_equal("replace replace", doc.root.text)
assert_equal(source, doc.to_s)
end
# Contributed (not only test, but bug fix!!) by Kouhei Sutou
def test_entity_replacement
source = %q{<!DOCTYPE foo [
<!ENTITY % YN '"Yes"'>
<!ENTITY WhatHeSaid "He said %YN;">]>
<a>&WhatHeSaid;</a>}
d = REXML::Document.new( source )
dt = d.doctype
assert_equal( '"Yes"', dt.entities[ "YN" ].value )
assert_equal( 'He said "Yes"', dt.entities[ "WhatHeSaid" ].value )
assert_equal( 'He said "Yes"', d.elements[1].text )
end
# More unit tests from Kouhei. I looove users who give me unit tests.
def test_entity_insertions
assert_equal("&amp;", REXML::Text.new("&amp;", false, nil, true).to_s)
#assert_equal("&", REXML::Text.new("&amp;", false, false).to_s)
end
def test_single_pass_unnormalization # ticket 123
assert_equal '&amp;&', REXML::Text::unnormalize('&#38;amp;&amp;')
end
def test_entity_filter
document = REXML::Document.new(<<-XML)
<!DOCTYPE root [
<!ENTITY copy "(c)">
<!ENTITY release-year "2013">
]>
<root/>
XML
respect_whitespace = false
parent = document.root
raw = false
entity_filter = ["copy"]
assert_equal("(c) &release-year;",
REXML::Text.new("(c) 2013",
respect_whitespace,
parent,
raw,
entity_filter).to_s)
end
end
end