Skip to content

Commit

Permalink
* lib/net/ftp.rb (makeport): close the TCPServer
Browse files Browse the repository at this point in the history
  when sending the port fails.
* test/net/ftp/test_ftp.rb: test for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
eregon committed Jun 27, 2015
1 parent b8d5448 commit 6cdc55f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
@@ -1,3 +1,10 @@
Sun Jun 14 19:02:03 2015 Benoit Daloze <eregontp@gmail.com>

* lib/net/ftp.rb (makeport): close the TCPServer
when sending the port fails.

* test/net/ftp/test_ftp.rb: test for above.

Fri Jun 26 12:48:37 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>

* transcode.c (load_transcoder_entry): fix transcoder loading race
Expand Down
11 changes: 3 additions & 8 deletions lib/net/ftp.rb
Expand Up @@ -377,15 +377,9 @@ def sendport(host, port) # :nodoc:
end
private :sendport

# Constructs a TCPServer socket, and sends it the PORT command
#
# Returns the constructed TCPServer socket
# Constructs a TCPServer socket
def makeport # :nodoc:
sock = TCPServer.open(@sock.addr[3], 0)
port = sock.addr[1]
host = sock.addr[3]
sendport(host, port)
return sock
TCPServer.open(@sock.addr[3], 0)
end
private :makeport

Expand Down Expand Up @@ -421,6 +415,7 @@ def transfercmd(cmd, rest_offset = nil) # :nodoc:
else
sock = makeport
begin
sendport(sock.addr[3], sock.addr[1])
if @resume and rest_offset
resp = sendcmd("REST " + rest_offset.to_s)
if resp[0] != ?3
Expand Down
40 changes: 40 additions & 0 deletions test/net/ftp/test_ftp.rb
Expand Up @@ -469,6 +469,46 @@ def test_list_fail
end
end

def test_open_data_port_fail_no_leak
commands = []
server = create_ftp_server { |sock|
sock.print("220 (test_ftp).\r\n")
commands.push(sock.gets)
sock.print("331 Please specify the password.\r\n")
commands.push(sock.gets)
sock.print("230 Login successful.\r\n")
commands.push(sock.gets)
sock.print("200 Switching to Binary mode.\r\n")
commands.push(sock.gets)
sock.print("200 Switching to ASCII mode.\r\n")
line = sock.gets
commands.push(line)
sock.print("421 Service not available, closing control connection.\r\n")
commands.push(sock.gets)
sock.print("200 Switching to Binary mode.\r\n")
}
begin
begin
ftp = Net::FTP.new
ftp.read_timeout = 0.2
ftp.connect(SERVER_ADDR, server.port)
ftp.login
assert_match(/\AUSER /, commands.shift)
assert_match(/\APASS /, commands.shift)
assert_equal("TYPE I\r\n", commands.shift)
assert_raise(Net::FTPTempError){ ftp.list }
assert_equal("TYPE A\r\n", commands.shift)
assert_match(/\APORT /, commands.shift)
assert_equal("TYPE I\r\n", commands.shift)
assert_equal(nil, commands.shift)
ensure
ftp.close if ftp
end
ensure
server.close
end
end

def test_retrbinary_read_timeout_exceeded
commands = []
binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
Expand Down

0 comments on commit 6cdc55f

Please sign in to comment.