diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
index bbdcfc6c..54014e57 100644
--- a/lib/rexml/parsers/baseparser.rb
+++ b/lib/rexml/parsers/baseparser.rb
@@ -486,11 +486,15 @@ def pull_event
if text.chomp!("<")
@source.position -= "<".bytesize
end
- if @tags.empty? and @have_root
+ if @tags.empty?
unless /\A\s*\z/.match?(text)
- raise ParseException.new("Malformed XML: Extra content at the end of the document (got '#{text}')", @source)
+ if @have_root
+ raise ParseException.new("Malformed XML: Extra content at the end of the document (got '#{text}')", @source)
+ else
+ raise ParseException.new("Malformed XML: Content at the start of the document (got '#{text}')", @source)
+ end
end
- return pull_event
+ return pull_event if @have_root
end
return [ :text, text ]
end
diff --git a/test/parse/test_comment.rb b/test/parse/test_comment.rb
index b7892232..4475dca7 100644
--- a/test/parse/test_comment.rb
+++ b/test/parse/test_comment.rb
@@ -110,6 +110,18 @@ def test_after_doctype_malformed_comment_end
end
end
+ def test_before_root
+ parser = REXML::Parsers::BaseParser.new('')
+
+ events = {}
+ while parser.has_next?
+ event = parser.pull
+ events[event[0]] = event[1]
+ end
+
+ assert_equal(" ok comment ", events[:comment])
+ end
+
def test_after_root
parser = REXML::Parsers::BaseParser.new('')
diff --git a/test/parse/test_processing_instruction.rb b/test/parse/test_processing_instruction.rb
index 7943cd3c..8d42e964 100644
--- a/test/parse/test_processing_instruction.rb
+++ b/test/parse/test_processing_instruction.rb
@@ -25,25 +25,6 @@ def test_no_name
DETAIL
end
- def test_garbage_text
- # TODO: This should be parse error.
- # Create test/parse/test_document.rb or something and move this to it.
- doc = parse(<<-XML)
-x?>
-
- XML
- pi = doc.children[1]
- assert_equal([
- "x",
- "y\n?>
+
+ XML
+ assert_equal([["x", "y\n"]],
+ [[doc.children[0].target, doc.children[0].content],
+ [doc.children[1].target, doc.children[1].content]])
+ end
+
+ def test_before_root
+ parser = REXML::Parsers::BaseParser.new('')
+
+ events = {}
+ while parser.has_next?
+ event = parser.pull
+ events[event[0]] = event[1]
+ end
+
+ assert_equal("abc", events[:processing_instruction])
+ end
+
def test_after_root
parser = REXML::Parsers::BaseParser.new('')
diff --git a/test/parse/test_text.rb b/test/parse/test_text.rb
index 1acefc40..04f553ae 100644
--- a/test/parse/test_text.rb
+++ b/test/parse/test_text.rb
@@ -4,6 +4,23 @@
module REXMLTests
class TestParseText < Test::Unit::TestCase
class TestInvalid < self
+ def test_before_root
+ exception = assert_raise(REXML::ParseException) do
+ parser = REXML::Parsers::BaseParser.new('b')
+ while parser.has_next?
+ parser.pull
+ end
+ end
+
+ assert_equal(<<~DETAIL.chomp, exception.to_s)
+ Malformed XML: Content at the start of the document (got 'b')
+ Line: 1
+ Position: 4
+ Last 80 unconsumed characters:
+
+ DETAIL
+ end
+
def test_after_root
exception = assert_raise(REXML::ParseException) do
parser = REXML::Parsers::BaseParser.new('c')