Skip to content

Commit

Permalink
Reject unclosed DOCTYPE on parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
makenowjust committed Jun 18, 2024
1 parent d906ae2 commit 4af4265
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 11 deletions.
32 changes: 21 additions & 11 deletions lib/rexml/parsers/treeparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,20 @@ def parse
#STDERR.puts "TREEPARSER GOT #{event.inspect}"
case event[0]
when :end_document
if in_doctype
raise ParseException.new("Malformed DOCTYPE: unclosed",
@parser.source, @parser)
end
unless tag_stack.empty?
raise ParseException.new("No close tag for #{@build_context.xpath}",
@parser.source, @parser)
end
return
when :start_element
if in_doctype
raise ParseException.new("Malformed DOCTYPE: unclosed",
@parser.source, @parser)
end
tag_stack.push(event[1])
el = @build_context = @build_context.add_element( event[1] )
event[2].each do |key, value|
Expand All @@ -39,17 +47,19 @@ def parse
tag_stack.pop
@build_context = @build_context.parent
when :text
if not in_doctype
if @build_context[-1].instance_of? Text
@build_context[-1] << event[1]
else
@build_context.add(
Text.new(event[1], @build_context.whitespace, nil, true)
) unless (
@build_context.ignore_whitespace_nodes and
event[1].strip.size==0
)
end
if in_doctype
raise ParseException.new("Malformed DOCTYPE: unclosed",
@parser.source, @parser)
end
if @build_context[-1].instance_of? Text
@build_context[-1] << event[1]
else
@build_context.add(
Text.new(event[1], @build_context.whitespace, nil, true)
) unless (
@build_context.ignore_whitespace_nodes and
event[1].strip.size==0
)
end
when :comment
c = Comment.new( event[1] )
Expand Down
47 changes: 47 additions & 0 deletions test/parse/test_document_type_declaration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,53 @@ def test_no_name
end
end

class TestUnclosed < self
def test_unclosed_doctype_only
exception = assert_raise(REXML::ParseException) do
REXML::Document.new(<<~DOCTYPE)
<!DOCTYPE foo [
DOCTYPE
end
assert_equal(<<~DETAIL.chomp, exception.to_s)
Malformed DOCTYPE: unclosed
Line: 1
Position: 16
Last 80 unconsumed characters:
DETAIL
end

def test_unclosed_doctype_plus_start_element
exception = assert_raise(REXML::ParseException) do
REXML::Document.new(<<~DOCTYPE)
<!DOCTYPE foo [ <r>
DOCTYPE
end
assert_equal(<<~DETAIL.chomp, exception.to_s)
Malformed DOCTYPE: unclosed
Line: 1
Position: 20
Last 80 unconsumed characters:
#{' '}
DETAIL
end

def test_unclosed_doctype_plus_text
exception = assert_raise(REXML::ParseException) do
REXML::Document.new(<<~DOCTYPE)
<!DOCTYPE foo [ text
DOCTYPE
end
assert_equal(<<~DETAIL.chomp, exception.to_s)
Malformed DOCTYPE: unclosed
Line: 1
Position: 21
Last 80 unconsumed characters:
DETAIL
end
end

class TestExternalID < self
class TestSystem < self
def test_left_bracket_in_system_literal
Expand Down

0 comments on commit 4af4265

Please sign in to comment.