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

/test/rexml/test_document.rb

http://github.com/ruby/ruby
Ruby | 416 lines | 376 code | 38 blank | 2 comment | 0 complexity | 9a01a84d311cc5e29ad24ef1531af78f MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # -*- coding: utf-8 -*-
  2. # frozen_string_literal: false
  3. require "rexml/document"
  4. require "test/unit"
  5. module REXMLTests
  6. class TestDocument < Test::Unit::TestCase
  7. def test_version_attributes_to_s
  8. doc = REXML::Document.new(<<-eoxml)
  9. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  10. <svg id="svg2"
  11. xmlns:sodipodi="foo"
  12. xmlns:inkscape="bar"
  13. sodipodi:version="0.32"
  14. inkscape:version="0.44.1"
  15. >
  16. </svg>
  17. eoxml
  18. string = doc.to_s
  19. assert_match('xmlns:sodipodi', string)
  20. assert_match('xmlns:inkscape', string)
  21. assert_match('sodipodi:version', string)
  22. assert_match('inkscape:version', string)
  23. end
  24. def test_new
  25. doc = REXML::Document.new(<<EOF)
  26. <?xml version="1.0" encoding="UTF-8"?>
  27. <message>Hello world!</message>
  28. EOF
  29. assert_equal("Hello world!", doc.root.children.first.value)
  30. end
  31. class EntityExpansionLimitTest < Test::Unit::TestCase
  32. def setup
  33. @default_entity_expansion_limit = REXML::Security.entity_expansion_limit
  34. end
  35. def teardown
  36. REXML::Security.entity_expansion_limit = @default_entity_expansion_limit
  37. end
  38. class GeneralEntityTest < self
  39. def test_have_value
  40. xml = <<EOF
  41. <?xml version="1.0" encoding="UTF-8"?>
  42. <!DOCTYPE member [
  43. <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
  44. <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
  45. <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
  46. <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
  47. <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
  48. <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
  49. <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
  50. ]>
  51. <member>
  52. &a;
  53. </member>
  54. EOF
  55. doc = REXML::Document.new(xml)
  56. assert_raise(RuntimeError) do
  57. doc.root.children.first.value
  58. end
  59. REXML::Security.entity_expansion_limit = 100
  60. assert_equal(100, REXML::Security.entity_expansion_limit)
  61. doc = REXML::Document.new(xml)
  62. assert_raise(RuntimeError) do
  63. doc.root.children.first.value
  64. end
  65. assert_equal(101, doc.entity_expansion_count)
  66. end
  67. def test_empty_value
  68. xml = <<EOF
  69. <?xml version="1.0" encoding="UTF-8"?>
  70. <!DOCTYPE member [
  71. <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
  72. <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
  73. <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
  74. <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
  75. <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
  76. <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
  77. <!ENTITY g "">
  78. ]>
  79. <member>
  80. &a;
  81. </member>
  82. EOF
  83. doc = REXML::Document.new(xml)
  84. assert_raise(RuntimeError) do
  85. doc.root.children.first.value
  86. end
  87. REXML::Security.entity_expansion_limit = 100
  88. assert_equal(100, REXML::Security.entity_expansion_limit)
  89. doc = REXML::Document.new(xml)
  90. assert_raise(RuntimeError) do
  91. doc.root.children.first.value
  92. end
  93. assert_equal(101, doc.entity_expansion_count)
  94. end
  95. def test_with_default_entity
  96. xml = <<EOF
  97. <?xml version="1.0" encoding="UTF-8"?>
  98. <!DOCTYPE member [
  99. <!ENTITY a "a">
  100. <!ENTITY a2 "&a; &a;">
  101. ]>
  102. <member>
  103. &a;
  104. &a2;
  105. &lt;
  106. </member>
  107. EOF
  108. REXML::Security.entity_expansion_limit = 4
  109. doc = REXML::Document.new(xml)
  110. assert_equal("\na\na a\n<\n", doc.root.children.first.value)
  111. REXML::Security.entity_expansion_limit = 3
  112. doc = REXML::Document.new(xml)
  113. assert_raise(RuntimeError) do
  114. doc.root.children.first.value
  115. end
  116. end
  117. end
  118. class ParameterEntityTest < self
  119. def test_have_value
  120. xml = <<EOF
  121. <!DOCTYPE root [
  122. <!ENTITY % a "BOOM.BOOM.BOOM.BOOM.BOOM.BOOM.BOOM.BOOM.BOOM.">
  123. <!ENTITY % b "%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;">
  124. <!ENTITY % c "%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;">
  125. <!ENTITY % d "%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;">
  126. <!ENTITY % e "%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;">
  127. <!ENTITY % f "%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;">
  128. <!ENTITY % g "%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;">
  129. <!ENTITY test "test %g;">
  130. ]>
  131. <cd></cd>
  132. EOF
  133. assert_raise(REXML::ParseException) do
  134. REXML::Document.new(xml)
  135. end
  136. REXML::Security.entity_expansion_limit = 100
  137. assert_equal(100, REXML::Security.entity_expansion_limit)
  138. assert_raise(REXML::ParseException) do
  139. REXML::Document.new(xml)
  140. end
  141. end
  142. def test_empty_value
  143. xml = <<EOF
  144. <!DOCTYPE root [
  145. <!ENTITY % a "">
  146. <!ENTITY % b "%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;%a;">
  147. <!ENTITY % c "%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;%b;">
  148. <!ENTITY % d "%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;%c;">
  149. <!ENTITY % e "%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;">
  150. <!ENTITY % f "%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;%e;">
  151. <!ENTITY % g "%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;">
  152. <!ENTITY test "test %g;">
  153. ]>
  154. <cd></cd>
  155. EOF
  156. assert_raise(REXML::ParseException) do
  157. REXML::Document.new(xml)
  158. end
  159. REXML::Security.entity_expansion_limit = 100
  160. assert_equal(100, REXML::Security.entity_expansion_limit)
  161. assert_raise(REXML::ParseException) do
  162. REXML::Document.new(xml)
  163. end
  164. end
  165. end
  166. end
  167. def test_tag_in_cdata_with_not_ascii_only_but_ascii8bit_encoding_source
  168. tag = "<b>...</b>"
  169. message = "こんにちは、世界!" # Hello world! in Japanese
  170. xml = <<EOX
  171. <?xml version="1.0" encoding="UTF-8"?>
  172. <message><![CDATA[#{tag}#{message}]]></message>
  173. EOX
  174. xml.force_encoding(Encoding::ASCII_8BIT)
  175. doc = REXML::Document.new(xml)
  176. assert_equal("#{tag}#{message}", doc.root.children.first.value)
  177. end
  178. def test_xml_declaration_standalone
  179. bug2539 = '[ruby-core:27345]'
  180. doc = REXML::Document.new('<?xml version="1.0" standalone="no" ?>')
  181. assert_equal('no', doc.stand_alone?, bug2539)
  182. doc = REXML::Document.new('<?xml version="1.0" standalone= "no" ?>')
  183. assert_equal('no', doc.stand_alone?, bug2539)
  184. doc = REXML::Document.new('<?xml version="1.0" standalone= "no" ?>')
  185. assert_equal('no', doc.stand_alone?, bug2539)
  186. end
  187. class WriteTest < Test::Unit::TestCase
  188. def setup
  189. @document = REXML::Document.new(<<-EOX)
  190. <?xml version="1.0" encoding="UTF-8"?>
  191. <message>Hello world!</message>
  192. EOX
  193. end
  194. class ArgumentsTest < self
  195. def test_output
  196. output = ""
  197. @document.write(output)
  198. assert_equal(<<-EOX, output)
  199. <?xml version='1.0' encoding='UTF-8'?>
  200. <message>Hello world!</message>
  201. EOX
  202. end
  203. def test_indent
  204. output = ""
  205. indent = 2
  206. @document.write(output, indent)
  207. assert_equal(<<-EOX.chomp, output)
  208. <?xml version='1.0' encoding='UTF-8'?>
  209. <message>
  210. Hello world!
  211. </message>
  212. EOX
  213. end
  214. def test_transitive
  215. output = ""
  216. indent = 2
  217. transitive = true
  218. @document.write(output, indent, transitive)
  219. assert_equal(<<-EOX, output)
  220. <?xml version='1.0' encoding='UTF-8'?>
  221. <message
  222. >Hello world!</message
  223. >
  224. EOX
  225. end
  226. def test_ie_hack
  227. output = ""
  228. indent = -1
  229. transitive = false
  230. ie_hack = true
  231. document = REXML::Document.new("<empty/>")
  232. document.write(output, indent, transitive, ie_hack)
  233. assert_equal("<empty />", output)
  234. end
  235. def test_encoding
  236. output = ""
  237. indent = -1
  238. transitive = false
  239. ie_hack = false
  240. encoding = "Windows-31J"
  241. @document.xml_decl.encoding = "Shift_JIS"
  242. japanese_text = "こんにちは"
  243. @document.root.text = japanese_text
  244. @document.write(output, indent, transitive, ie_hack, encoding)
  245. assert_equal(<<-EOX.encode(encoding), output)
  246. <?xml version='1.0' encoding='SHIFT_JIS'?>
  247. <message>#{japanese_text}</message>
  248. EOX
  249. end
  250. end
  251. class OptionsTest < self
  252. def test_output
  253. output = ""
  254. @document.write(:output => output)
  255. assert_equal(<<-EOX, output)
  256. <?xml version='1.0' encoding='UTF-8'?>
  257. <message>Hello world!</message>
  258. EOX
  259. end
  260. def test_indent
  261. output = ""
  262. @document.write(:output => output, :indent => 2)
  263. assert_equal(<<-EOX.chomp, output)
  264. <?xml version='1.0' encoding='UTF-8'?>
  265. <message>
  266. Hello world!
  267. </message>
  268. EOX
  269. end
  270. def test_transitive
  271. output = ""
  272. @document.write(:output => output, :indent => 2, :transitive => true)
  273. assert_equal(<<-EOX, output)
  274. <?xml version='1.0' encoding='UTF-8'?>
  275. <message
  276. >Hello world!</message
  277. >
  278. EOX
  279. end
  280. def test_ie_hack
  281. output = ""
  282. document = REXML::Document.new("<empty/>")
  283. document.write(:output => output, :ie_hack => true)
  284. assert_equal("<empty />", output)
  285. end
  286. def test_encoding
  287. output = ""
  288. encoding = "Windows-31J"
  289. @document.xml_decl.encoding = "Shift_JIS"
  290. japanese_text = "こんにちは"
  291. @document.root.text = japanese_text
  292. @document.write(:output => output, :encoding => encoding)
  293. assert_equal(<<-EOX.encode(encoding), output)
  294. <?xml version='1.0' encoding='SHIFT_JIS'?>
  295. <message>#{japanese_text}</message>
  296. EOX
  297. end
  298. end
  299. end
  300. class BomTest < Test::Unit::TestCase
  301. class HaveEncodingTest < self
  302. def test_utf_8
  303. xml = <<-EOX.force_encoding("ASCII-8BIT")
  304. <?xml version="1.0" encoding="UTF-8"?>
  305. <message>Hello world!</message>
  306. EOX
  307. bom = "\ufeff".force_encoding("ASCII-8BIT")
  308. document = REXML::Document.new(bom + xml)
  309. assert_equal("UTF-8", document.encoding)
  310. end
  311. def test_utf_16le
  312. xml = <<-EOX.encode("UTF-16LE").force_encoding("ASCII-8BIT")
  313. <?xml version="1.0" encoding="UTF-16"?>
  314. <message>Hello world!</message>
  315. EOX
  316. bom = "\ufeff".encode("UTF-16LE").force_encoding("ASCII-8BIT")
  317. document = REXML::Document.new(bom + xml)
  318. assert_equal("UTF-16", document.encoding)
  319. end
  320. def test_utf_16be
  321. xml = <<-EOX.encode("UTF-16BE").force_encoding("ASCII-8BIT")
  322. <?xml version="1.0" encoding="UTF-16"?>
  323. <message>Hello world!</message>
  324. EOX
  325. bom = "\ufeff".encode("UTF-16BE").force_encoding("ASCII-8BIT")
  326. document = REXML::Document.new(bom + xml)
  327. assert_equal("UTF-16", document.encoding)
  328. end
  329. end
  330. class NoEncodingTest < self
  331. def test_utf_8
  332. xml = <<-EOX.force_encoding("ASCII-8BIT")
  333. <?xml version="1.0"?>
  334. <message>Hello world!</message>
  335. EOX
  336. bom = "\ufeff".force_encoding("ASCII-8BIT")
  337. document = REXML::Document.new(bom + xml)
  338. assert_equal("UTF-8", document.encoding)
  339. end
  340. def test_utf_16le
  341. xml = <<-EOX.encode("UTF-16LE").force_encoding("ASCII-8BIT")
  342. <?xml version="1.0"?>
  343. <message>Hello world!</message>
  344. EOX
  345. bom = "\ufeff".encode("UTF-16LE").force_encoding("ASCII-8BIT")
  346. document = REXML::Document.new(bom + xml)
  347. assert_equal("UTF-16", document.encoding)
  348. end
  349. def test_utf_16be
  350. xml = <<-EOX.encode("UTF-16BE").force_encoding("ASCII-8BIT")
  351. <?xml version="1.0"?>
  352. <message>Hello world!</message>
  353. EOX
  354. bom = "\ufeff".encode("UTF-16BE").force_encoding("ASCII-8BIT")
  355. document = REXML::Document.new(bom + xml)
  356. assert_equal("UTF-16", document.encoding)
  357. end
  358. end
  359. class WriteTest < self
  360. def test_utf_16
  361. xml = <<-EOX.encode("UTF-16LE").force_encoding("ASCII-8BIT")
  362. <?xml version="1.0"?>
  363. <message>Hello world!</message>
  364. EOX
  365. bom = "\ufeff".encode("UTF-16LE").force_encoding("ASCII-8BIT")
  366. document = REXML::Document.new(bom + xml)
  367. actual_xml = ""
  368. document.write(actual_xml)
  369. expected_xml = <<-EOX.encode("UTF-16BE")
  370. \ufeff<?xml version='1.0' encoding='UTF-16'?>
  371. <message>Hello world!</message>
  372. EOX
  373. assert_equal(expected_xml, actual_xml)
  374. end
  375. end
  376. end
  377. end
  378. end