diff -Nur ruby-2.5.8/test/rexml/parse/test_document_type_declaration.rb ruby-2.5.9/test/rexml/parse/test_document_type_declaration.rb --- ruby-2.5.8/test/rexml/parse/test_document_type_declaration.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/parse/test_document_type_declaration.rb 2021-04-05 11:46:35.000000000 +0000 @@ -5,17 +5,187 @@ module REXMLTests class TestParseDocumentTypeDeclaration < Test::Unit::TestCase private - def xml(internal_subset) - <<-XML - + def parse(doctype) + REXML::Document.new(<<-XML).doctype +#{doctype} XML end - def parse(internal_subset) - REXML::Document.new(xml(internal_subset)).doctype + class TestName < self + def test_valid + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("r", doctype.name) + end + + def test_garbage_plus_before_name_at_line_start + exception = assert_raise(REXML::ParseException) do + parse(<<-DOCTYPE) + + DOCTYPE + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed DOCTYPE: invalid name +Line: 5 +Position: 51 +Last 80 unconsumed characters: ++ r SYSTEM "urn:x-rexml:test" [ ]> + DETAIL + end + end + + class TestExternalID < self + class TestSystem < self + def test_left_bracket_in_system_literal + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal([ + "r", + "SYSTEM", + nil, + "urn:x-rexml:[test", + ], + [ + doctype.name, + doctype.external_id, + doctype.public, + doctype.system, + ]) + end + + def test_greater_than_in_system_literal + doctype = parse(<<-DOCTYPE) +test" [ +]> + DOCTYPE + assert_equal([ + "r", + "SYSTEM", + nil, + "urn:x-rexml:>test", + ], + [ + doctype.name, + doctype.external_id, + doctype.public, + doctype.system, + ]) + end + + def test_no_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-DOCTYPE) + + DOCTYPE + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed DOCTYPE: system literal is missing +Line: 3 +Position: 26 +Last 80 unconsumed characters: + SYSTEM> + DETAIL + end + + def test_garbage_after_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-DOCTYPE) + + DOCTYPE + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed DOCTYPE: garbage after external ID +Line: 3 +Position: 36 +Last 80 unconsumed characters: +x'> + DETAIL + end + + def test_single_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("r\".dtd", doctype.system) + end + + def test_double_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("r'.dtd", doctype.system) + end + end + + class TestPublic < self + class TestPublicIDLiteral < self + def test_content_double_quote + exception = assert_raise(REXML::ParseException) do + parse(<<-DOCTYPE) + + DOCTYPE + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed DOCTYPE: invalid public ID literal +Line: 3 +Position: 62 +Last 80 unconsumed characters: + PUBLIC 'double quote " is invalid' "r.dtd"> + DETAIL + end + + def test_single_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("public-id-literal", doctype.public) + end + + def test_double_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("public'-id-literal", doctype.public) + end + end + + class TestSystemLiteral < self + def test_garbage_after_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-DOCTYPE) + + DOCTYPE + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed DOCTYPE: garbage after external ID +Line: 3 +Position: 65 +Last 80 unconsumed characters: +x'> + DETAIL + end + + def test_single_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("system\"-literal", doctype.system) + end + + def test_double_quote + doctype = parse(<<-DOCTYPE) + + DOCTYPE + assert_equal("system'-literal", doctype.system) + end + end + end end class TestMixed < self @@ -45,6 +215,15 @@ assert_equal([REXML::NotationDecl, REXML::AttlistDecl], doctype.children.collect(&:class)) end + + private + def parse(internal_subset) + super(<<-DOCTYPE) + + DOCTYPE + end end end end diff -Nur ruby-2.5.8/test/rexml/parse/test_element.rb ruby-2.5.9/test/rexml/parse/test_element.rb --- ruby-2.5.8/test/rexml/parse/test_element.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-2.5.9/test/rexml/parse/test_element.rb 2021-04-05 11:46:35.000000000 +0000 @@ -0,0 +1,77 @@ +require "test/unit" +require "rexml/document" + +module REXMLTests + class TestParseElement < Test::Unit::TestCase + def parse(xml) + REXML::Document.new(xml) + end + + class TestInvalid < self + def test_top_level_end_tag + exception = assert_raise(REXML::ParseException) do + parse("") + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Unexpected top-level end tag (got 'a') +Line: 1 +Position: 4 +Last 80 unconsumed characters: + + DETAIL + end + + def test_no_end_tag + exception = assert_raise(REXML::ParseException) do + parse("") + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Invalid attribute name: <:a=""> +Line: 1 +Position: 13 +Last 80 unconsumed characters: + + DETAIL + end + + def test_garbage_less_than_before_root_element_at_line_start + exception = assert_raise(REXML::ParseException) do + parse("<\n") + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +malformed XML: missing tag start +Line: 2 +Position: 6 +Last 80 unconsumed characters: +< + DETAIL + end + + def test_garbage_less_than_slash_before_end_tag_at_line_start + exception = assert_raise(REXML::ParseException) do + parse("") + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Missing end tag for 'x' +Line: 2 +Position: 10 +Last 80 unconsumed characters: + + DETAIL + end + end + end +end diff -Nur ruby-2.5.8/test/rexml/parse/test_notation_declaration.rb ruby-2.5.9/test/rexml/parse/test_notation_declaration.rb --- ruby-2.5.8/test/rexml/parse/test_notation_declaration.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/parse/test_notation_declaration.rb 2021-04-05 11:46:35.000000000 +0000 @@ -23,10 +23,100 @@ doctype = parse("") assert_equal("name", doctype.notation("name").name) end + + def test_no_name + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: name is missing +Line: 5 +Position: 72 +Last 80 unconsumed characters: + ]> + DETAIL + end + + def test_invalid_name + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: invalid name +Line: 5 +Position: 74 +Last 80 unconsumed characters: +'> ]> + DETAIL + end + + def test_no_id_type + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: invalid ID type +Line: 5 +Position: 77 +Last 80 unconsumed characters: +> ]> + DETAIL + end + + def test_invalid_id_type + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: invalid ID type +Line: 5 +Position: 85 +Last 80 unconsumed characters: + INVALID> ]> + DETAIL + end end class TestExternalID < self class TestSystem < self + def test_no_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: system literal is missing +Line: 5 +Position: 84 +Last 80 unconsumed characters: + SYSTEM> ]> + DETAIL + end + + def test_garbage_after_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: garbage before end > +Line: 5 +Position: 103 +Last 80 unconsumed characters: +x'> ]> + DETAIL + end + def test_single_quote doctype = parse(<<-INTERNAL_SUBSET) @@ -44,6 +134,21 @@ class TestPublic < self class TestPublicIDLiteral < self + def test_content_double_quote + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: invalid public ID literal +Line: 5 +Position: 129 +Last 80 unconsumed characters: + PUBLIC 'double quote " is invalid' "system-literal"> ]> + DETAIL + end + def test_single_quote doctype = parse(<<-INTERNAL_SUBSET) @@ -60,6 +165,21 @@ end class TestSystemLiteral < self + def test_garbage_after_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: garbage before end > +Line: 5 +Position: 123 +Last 80 unconsumed characters: +x'> ]> + DETAIL + end + def test_single_quote doctype = parse(<<-INTERNAL_SUBSET) @@ -96,5 +216,66 @@ end end end + + class TestPublicID < self + def test_no_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: public ID literal is missing +Line: 5 +Position: 84 +Last 80 unconsumed characters: + PUBLIC> ]> + DETAIL + end + + def test_literal_content_double_quote + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: invalid public ID literal +Line: 5 +Position: 128 +Last 80 unconsumed characters: + PUBLIC 'double quote \" is invalid in PubidLiteral'> ]> + DETAIL + end + + def test_garbage_after_literal + exception = assert_raise(REXML::ParseException) do + parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + end + assert_equal(<<-DETAIL.chomp, exception.to_s) +Malformed notation declaration: garbage before end > +Line: 5 +Position: 106 +Last 80 unconsumed characters: +x'> ]> + DETAIL + end + + def test_literal_single_quote + doctype = parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + assert_equal("public-id-literal", doctype.notation("name").public) + end + + def test_literal_double_quote + doctype = parse(<<-INTERNAL_SUBSET) + + INTERNAL_SUBSET + assert_equal("public-id-literal", doctype.notation("name").public) + end + end end end diff -Nur ruby-2.5.8/test/rexml/parser/test_tree.rb ruby-2.5.9/test/rexml/parser/test_tree.rb --- ruby-2.5.8/test/rexml/parser/test_tree.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/parser/test_tree.rb 2021-04-05 11:46:35.000000000 +0000 @@ -12,7 +12,7 @@ parse(xml) end assert_equal(<<-MESSAGE, exception.to_s) -Missing end tag for 'root' (got "not-root") +Missing end tag for 'root' (got 'not-root') Line: 1 Position: #{xml.bytesize} Last 80 unconsumed characters: diff -Nur ruby-2.5.8/test/rexml/parser/test_ultra_light.rb ruby-2.5.9/test/rexml/parser/test_ultra_light.rb --- ruby-2.5.8/test/rexml/parser/test_ultra_light.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/parser/test_ultra_light.rb 2021-04-05 11:46:35.000000000 +0000 @@ -16,7 +16,6 @@ nil, [:entitydecl, "name", "value"] ], - [:text, "\n"], [:start_element, :parent, "root", {}], [:text, "\n"], ], diff -Nur ruby-2.5.8/test/rexml/test_core.rb ruby-2.5.9/test/rexml/test_core.rb --- ruby-2.5.8/test/rexml/test_core.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/test_core.rb 2021-04-05 11:46:35.000000000 +0000 @@ -1,4 +1,4 @@ -# coding: binary +# coding: utf-8 # frozen_string_literal: false require_relative "rexml_test_utils" @@ -995,7 +995,7 @@ document.write(s) ## XML Doctype - str = '' + str = '' source = REXML::Source.new(str) doctype = REXML::DocType.new(source) document.add(doctype) @@ -1274,14 +1274,15 @@ def test_ticket_21 src = "" - assert_raise( ParseException, "invalid XML should be caught" ) { + exception = assert_raise(ParseException) do Document.new(src) - } - begin - Document.new(src) - rescue - assert_match( /missing attribute quote/, $!.message ) end + assert_equal(<<-DETAIL, exception.to_s) +Missing attribute value start quote: +Line: 1 +Position: 16 +Last 80 unconsumed characters: + DETAIL end def test_ticket_63 diff -Nur ruby-2.5.8/test/rexml/test_doctype.rb ruby-2.5.9/test/rexml/test_doctype.rb --- ruby-2.5.8/test/rexml/test_doctype.rb 2020-03-31 12:15:56.000000000 +0000 +++ ruby-2.5.9/test/rexml/test_doctype.rb 2021-04-05 11:46:35.000000000 +0000 @@ -4,65 +4,111 @@ module REXMLTests class TestDocTypeAccessor < Test::Unit::TestCase - def setup @sysid = "urn:x-test:sysid1" - @notid1 = "urn:x-test:notation1" - @notid2 = "urn:x-test:notation2" - document_string1 = <<-"XMLEND" - - + @notation_id1 = "urn:x-test:notation1" + @notation_id2 = "urn:x-test:notation2" + xml_system = <<-XML + + ]> - - XMLEND - @doctype1 = REXML::Document.new(document_string1).doctype + + XML + @doc_type_system = REXML::Document.new(xml_system).doctype @pubid = "TEST_ID" - document_string2 = <<-"XMLEND" - - - XMLEND - @doctype2 = REXML::Document.new(document_string2).doctype - - document_string3 = <<-"XMLEND" - - - XMLEND - @doctype3 = REXML::Document.new(document_string3).doctype - + xml_public_system = <<-XML + + + XML + @doc_type_public_system = REXML::Document.new(xml_public_system).doctype end def test_public - assert_equal(nil, @doctype1.public) - assert_equal(@pubid, @doctype2.public) - assert_equal(@pubid, @doctype3.public) + assert_equal([ + nil, + @pubid, + ], + [ + @doc_type_system.public, + @doc_type_public_system.public, + ]) + end + + def test_to_s + assert_equal("", + @doc_type_public_system.to_s) end def test_system - assert_equal(@sysid, @doctype1.system) - assert_equal(nil, @doctype2.system) - assert_equal(@sysid, @doctype3.system) + assert_equal([ + @sysid, + @sysid, + ], + [ + @doc_type_system.system, + @doc_type_public_system.system, + ]) end def test_notation - assert_equal(@notid1, @doctype1.notation("n1").system) - assert_equal(@notid2, @doctype1.notation("n2").system) + assert_equal([ + @notation_id1, + @notation_id2, + ], + [ + @doc_type_system.notation("n1").system, + @doc_type_system.notation("n2").system, + ]) end def test_notations - notations = @doctype1.notations - assert_equal(2, notations.length) - assert_equal(@notid1, find_notation(notations, "n1").system) - assert_equal(@notid2, find_notation(notations, "n2").system) + notations = @doc_type_system.notations + assert_equal([ + @notation_id1, + @notation_id2, + ], + notations.collect(&:system)) end + end - def find_notation(notations, name) - notations.find { |notation| - name == notation.name - } + class TestDocType < Test::Unit::TestCase + class TestExternalID < self + class TestSystem < self + class TestSystemLiteral < self + def test_to_s + doctype = REXML::DocType.new(["root", "SYSTEM", nil, "root.dtd"]) + assert_equal("", + doctype.to_s) + end + end + end + + class TestPublic < self + class TestPublicIDLiteral < self + def test_to_s + doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root.dtd"]) + assert_equal("", + doctype.to_s) + end + end + + class TestSystemLiteral < self + def test_to_s + doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root.dtd"]) + assert_equal("", + doctype.to_s) + end + + def test_to_s_double_quote + doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root\".dtd"]) + assert_equal("", + doctype.to_s) + end + end + end end - end class TestNotationDeclPublic < Test::Unit::TestCase @@ -77,11 +123,26 @@ decl(@id, nil).to_s) end + def test_to_s_pubid_literal_include_apostrophe + assert_equal("", + decl("#{@id}'", nil).to_s) + end + def test_to_s_with_uri assert_equal("", decl(@id, @uri).to_s) end + def test_to_s_system_literal_include_apostrophe + assert_equal("", + decl(@id, "system'literal").to_s) + end + + def test_to_s_system_literal_include_double_quote + assert_equal("", + decl(@id, "system\"literal").to_s) + end + private def decl(id, uri) REXML::NotationDecl.new(@name, "PUBLIC", id, uri) @@ -99,9 +160,19 @@ decl(@id).to_s) end + def test_to_s_include_apostrophe + assert_equal("", + decl("#{@id}'").to_s) + end + + def test_to_s_include_double_quote + assert_equal("", + decl("#{@id}\"").to_s) + end + private def decl(id) - REXML::NotationDecl.new(@name, "SYSTEM", id, nil) + REXML::NotationDecl.new(@name, "SYSTEM", nil, id) end end end