diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index cca06e6..3bbbd66 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -973,8 +973,11 @@ def data(msgstr = nil, &block) #:yield: stream @socket.write_message_by_block(&block) end ensure - @socket.io.flush - @socket.io.sync = socket_sync_bak + begin + @socket.io.flush + ensure + @socket.io.sync = socket_sync_bak + end end recv_response() } diff --git a/test/net/smtp/test_smtp.rb b/test/net/smtp/test_smtp.rb index 3b9e245..8d84fb3 100644 --- a/test/net/smtp/test_smtp.rb +++ b/test/net/smtp/test_smtp.rb @@ -253,6 +253,30 @@ def server.data assert_equal "250", err.response.status end + def test_data_restores_sync_when_flush_fails + io = Object.new + class << io + attr_accessor :sync + + def flush + raise IOError, "flush failed" + end + end + io.sync = true + socket = Object.new + socket.define_singleton_method(:io) { io } + socket.define_singleton_method(:write_message) { |_| } + + smtp = Net::SMTP.new("example.invalid", starttls: false) + smtp.instance_variable_set(:@socket, socket) + smtp.define_singleton_method(:get_response) do |_| + Net::SMTP::Response.parse("354 continue") + end + + assert_raise(IOError) { smtp.data("message") } + assert_equal true, io.sync + end + def test_crlf_injection server = FakeServer.new smtp = Net::SMTP.new 'localhost', server.port