Skip to content

Commit f086964

Browse files
committed
Fix error handling when parsing XML via IO.pipe
## Why? If via IO.pipe, `IOError` exception is not raised, but `Errno::ESPIPE` or `Errno::EPIPE` or `Errno::EINVAL` exception is raised. - CRuby ``` @er_source.pos #=> Errno::ESPIPE Exception: Illegal seek ``` - CRuby (Windows (Ruby 2.6 or earlier)) ``` @er_source.pos #=> Errno::EINVAL: Invalid argument ``` - JRuby ``` @er_source.pos #=> Errno::EPIPE: Broken pipe - No message available ```
1 parent 20562ec commit f086964

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

lib/rexml/source.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def current_line
321321
rescue
322322
end
323323
@er_source.seek(pos)
324-
rescue IOError
324+
rescue IOError, Errno::EPIPE, Errno::ESPIPE, Errno::EINVAL
325325
pos = -1
326326
line = -1
327327
end

test/parse/test_text.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ class TestParseText < Test::Unit::TestCase
66
class TestInvalid < self
77
def test_text_only
88
exception = assert_raise(REXML::ParseException) do
9-
parser = REXML::Parsers::BaseParser.new('a')
10-
while parser.has_next?
11-
parser.pull
12-
end
9+
REXML::Parsers::BaseParser.new('a').pull
1310
end
1411

1512
assert_equal(<<~DETAIL.chomp, exception.to_s)
@@ -21,6 +18,25 @@ def test_text_only
2118
DETAIL
2219
end
2320

21+
def test_text_only_with_io_pipe
22+
IO.pipe do |reader, writer|
23+
writer.write('a')
24+
writer.close
25+
26+
exception = assert_raise(REXML::ParseException) do
27+
REXML::Parsers::BaseParser.new(reader).pull
28+
end
29+
30+
assert_equal(<<~DETAIL.chomp, exception.to_s)
31+
Malformed XML: Content at the start of the document (got 'a')
32+
Line: -1
33+
Position: -1
34+
Last 80 unconsumed characters:
35+
36+
DETAIL
37+
end
38+
end
39+
2440
def test_before_root
2541
exception = assert_raise(REXML::ParseException) do
2642
parser = REXML::Parsers::BaseParser.new('b<a></a>')

0 commit comments

Comments
 (0)