PageRenderTime 28ms CodeModel.GetById 1ms RepoModel.GetById 4ms app.codeStats 0ms

/test/rexml/test_entity.rb

http://github.com/ruby/ruby
Ruby | 206 lines | 174 code | 23 blank | 9 comment | 1 complexity | 1ad6eff85b894f10c7c5589e0caea4f0 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require "test/unit/testcase"
  3. require 'rexml/document'
  4. require 'rexml/entity'
  5. require 'rexml/source'
  6. module REXMLTests
  7. class EntityTester < Test::Unit::TestCase
  8. def test_parse_general_decl
  9. simple = "<!ENTITY foo 'bar'>"
  10. simple =~ /#{REXML::Entity::GEDECL}/
  11. assert $&
  12. assert_equal simple, $&
  13. REXML::Entity::ENTITYDECL =~ simple
  14. assert REXML::Entity::matches?(simple)
  15. match = REXML::Entity::ENTITYDECL.match(simple)
  16. assert_equal 'foo', match[1]
  17. assert_equal "'bar'", match[2]
  18. simple = '<!ENTITY Pub-Status
  19. "This is a pre-release of the specification.">'
  20. assert REXML::Entity::matches?(simple)
  21. match = REXML::Entity::ENTITYDECL.match(simple)
  22. assert_equal 'Pub-Status', match[1]
  23. assert_equal '"This is a pre-release of the specification."', match[2]
  24. txt = '"This is a
  25. pre-release of <the> specification."'
  26. simple = "<!ENTITY Pub-Status
  27. #{txt}>"
  28. assert REXML::Entity::matches?(simple)
  29. match = REXML::Entity::ENTITYDECL.match(simple)
  30. assert_equal 'Pub-Status', match[1]
  31. assert_equal txt, match[2]
  32. end
  33. def test_parse_external_decl
  34. zero = '<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml" >'
  35. one = '<!ENTITY open-hatch
  36. SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">'
  37. two = '<!ENTITY open-hatch
  38. PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
  39. "http://www.textuality.com/boilerplate/OpenHatch.xml">'
  40. three = '<!ENTITY hatch-pic
  41. SYSTEM "../grafix/OpenHatch.gif"
  42. NDATA gif >'
  43. assert REXML::Entity::matches?(zero)
  44. assert REXML::Entity::matches?(one)
  45. assert REXML::Entity::matches?(two)
  46. assert REXML::Entity::matches?(three)
  47. end
  48. def test_parse_entity
  49. one = %q{<!ENTITY % YN '"Yes"'>}
  50. two = %q{<!ENTITY WhatHeSaid "He said %YN;">}
  51. assert REXML::Entity::matches?(one)
  52. assert REXML::Entity::matches?(two)
  53. end
  54. def test_constructor
  55. one = [ %q{<!ENTITY % YN '"Yes"'>},
  56. %q{<!ENTITY % YN2 "Yes">},
  57. %q{<!ENTITY WhatHeSaid "He said %YN;">},
  58. '<!ENTITY open-hatch
  59. SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">',
  60. '<!ENTITY open-hatch2
  61. PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
  62. "http://www.textuality.com/boilerplate/OpenHatch.xml">',
  63. '<!ENTITY hatch-pic
  64. SYSTEM "../grafix/OpenHatch.gif"
  65. NDATA gif>' ]
  66. source = %q{<!DOCTYPE foo [
  67. <!ENTITY % YN '"Yes"'>
  68. <!ENTITY % YN2 "Yes">
  69. <!ENTITY WhatHeSaid "He said %YN;">
  70. <!ENTITY open-hatch
  71. SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
  72. <!ENTITY open-hatch2
  73. PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
  74. "http://www.textuality.com/boilerplate/OpenHatch.xml">
  75. <!ENTITY hatch-pic
  76. SYSTEM "../grafix/OpenHatch.gif"
  77. NDATA gif>
  78. ]>}
  79. d = REXML::Document.new( source )
  80. dt = d.doctype
  81. c = 0
  82. dt.each do |child|
  83. if child.kind_of? REXML::Entity
  84. str = one[c].tr("\r\n\t", ' ').squeeze(" ")
  85. assert_equal str, child.to_s
  86. c+=1
  87. end
  88. end
  89. end
  90. def test_replace_entities
  91. source = "<!DOCTYPE blah [\n<!ENTITY foo \"bar\">\n]><a>&foo;</a>"
  92. doc = REXML::Document.new(source)
  93. assert_equal 'bar', doc.root.text
  94. out = ''
  95. doc.write out
  96. assert_equal source, out
  97. end
  98. def test_entity_string_limit
  99. template = '<!DOCTYPE bomb [ <!ENTITY a "^" > ]> <bomb>$</bomb>'
  100. len = 5120 # 5k per entity
  101. template.sub!(/\^/, "B" * len)
  102. # 10k is OK
  103. entities = '&a;' * 2 # 5k entity * 2 = 10k
  104. xmldoc = REXML::Document.new(template.sub(/\$/, entities))
  105. assert_equal(len * 2, xmldoc.root.text.bytesize)
  106. # above 10k explodes
  107. entities = '&a;' * 3 # 5k entity * 2 = 15k
  108. xmldoc = REXML::Document.new(template.sub(/\$/, entities))
  109. assert_raise(RuntimeError) do
  110. xmldoc.root.text
  111. end
  112. end
  113. def test_entity_string_limit_for_parameter_entity
  114. template = '<!DOCTYPE bomb [ <!ENTITY % a "^" > <!ENTITY bomb "$" > ]><root/>'
  115. len = 5120 # 5k per entity
  116. template.sub!(/\^/, "B" * len)
  117. # 10k is OK
  118. entities = '%a;' * 2 # 5k entity * 2 = 10k
  119. REXML::Document.new(template.sub(/\$/, entities))
  120. # above 10k explodes
  121. entities = '%a;' * 3 # 5k entity * 2 = 15k
  122. assert_raise(REXML::ParseException) do
  123. REXML::Document.new(template.sub(/\$/, entities))
  124. end
  125. end
  126. def test_raw
  127. source = '<!DOCTYPE foo [
  128. <!ENTITY ent "replace">
  129. ]><a>replace &ent;</a>'
  130. doc = REXML::Document.new( source, {:raw=>:all})
  131. assert_equal('replace &ent;', doc.root.get_text.to_s)
  132. assert_equal(source, doc.to_s)
  133. end
  134. def test_lazy_evaluation
  135. source = '<!DOCTYPE foo [
  136. <!ENTITY ent "replace">
  137. ]><a>replace &ent;</a>'
  138. doc = REXML::Document.new( source )
  139. assert_equal(source, doc.to_s)
  140. assert_equal("replace replace", doc.root.text)
  141. assert_equal(source, doc.to_s)
  142. end
  143. # Contributed (not only test, but bug fix!!) by Kouhei Sutou
  144. def test_entity_replacement
  145. source = %q{<!DOCTYPE foo [
  146. <!ENTITY % YN '"Yes"'>
  147. <!ENTITY WhatHeSaid "He said %YN;">]>
  148. <a>&WhatHeSaid;</a>}
  149. d = REXML::Document.new( source )
  150. dt = d.doctype
  151. assert_equal( '"Yes"', dt.entities[ "YN" ].value )
  152. assert_equal( 'He said "Yes"', dt.entities[ "WhatHeSaid" ].value )
  153. assert_equal( 'He said "Yes"', d.elements[1].text )
  154. end
  155. # More unit tests from Kouhei. I looove users who give me unit tests.
  156. def test_entity_insertions
  157. assert_equal("&amp;", REXML::Text.new("&amp;", false, nil, true).to_s)
  158. #assert_equal("&", REXML::Text.new("&amp;", false, false).to_s)
  159. end
  160. def test_single_pass_unnormalization # ticket 123
  161. assert_equal '&amp;&', REXML::Text::unnormalize('&#38;amp;&amp;')
  162. end
  163. def test_entity_filter
  164. document = REXML::Document.new(<<-XML)
  165. <!DOCTYPE root [
  166. <!ENTITY copy "(c)">
  167. <!ENTITY release-year "2013">
  168. ]>
  169. <root/>
  170. XML
  171. respect_whitespace = false
  172. parent = document.root
  173. raw = false
  174. entity_filter = ["copy"]
  175. assert_equal("(c) &release-year;",
  176. REXML::Text.new("(c) 2013",
  177. respect_whitespace,
  178. parent,
  179. raw,
  180. entity_filter).to_s)
  181. end
  182. end
  183. end