summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-30 12:04:22 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-30 12:04:22 +0000
commit75c84da28c5e9169a4d48efd1a542d8278b1d436 (patch)
treeaba4151f60973be87e2af5bf752b2f670ad9b015
parent1bd12d78c79c1194363f7755acab0a31109b935a (diff)
downloadruby-75c84da28c5e9169a4d48efd1a542d8278b1d436.tar.gz
merge revision(s) 44184: [Backport #9247]
* ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because it may be set before the body. Reported by ko1 and mrkn. [ruby-core:59088] [Bug #9247] * lib/cgi/core.rb: Ditto. * lib/drb/ssl.rb: Ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@44767 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--ext/socket/lib/socket.rb79
-rw-r--r--lib/cgi/core.rb11
-rw-r--r--lib/drb/ssl.rb5
-rw-r--r--test/socket/test_socket.rb71
-rw-r--r--version.h2
6 files changed, 145 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index bcebe4280b..43a6da490b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Thu Jan 30 20:53:42 2014 Tanaka Akira <akr@fsij.org>
+
+ * ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because
+ it may be set before the body.
+ Reported by ko1 and mrkn. [ruby-core:59088] [Bug #9247]
+
+ * lib/cgi/core.rb: Ditto.
+
+ * lib/drb/ssl.rb: Ditto.
+
Thu Jan 30 20:31:32 2014 NARUSE, Yui <naruse@ruby-lang.org>
* process.c (rb_daemon): daemon(3) is implemented with fork(2).
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index 66ff548270..ee6e9eabe1 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -41,13 +41,18 @@ class Addrinfo
sock.ipv6only! if self.ipv6?
sock.bind local_addrinfo if local_addrinfo
sock.connect(self)
- if block_given?
+ rescue Exception
+ sock.close
+ raise
+ end
+ if block_given?
+ begin
yield sock
- else
- sock
+ ensure
+ sock.close if !sock.closed?
end
- ensure
- sock.close if !sock.closed? && (block_given? || $!)
+ else
+ sock
end
end
private :connect_internal
@@ -123,13 +128,18 @@ class Addrinfo
sock.ipv6only! if self.ipv6?
sock.setsockopt(:SOCKET, :REUSEADDR, 1)
sock.bind(self)
- if block_given?
+ rescue Exception
+ sock.close
+ raise
+ end
+ if block_given?
+ begin
yield sock
- else
- sock
+ ensure
+ sock.close if !sock.closed?
end
- ensure
- sock.close if !sock.closed? && (block_given? || $!)
+ else
+ sock
end
end
@@ -141,13 +151,18 @@ class Addrinfo
sock.setsockopt(:SOCKET, :REUSEADDR, 1)
sock.bind(self)
sock.listen(backlog)
- if block_given?
+ rescue Exception
+ sock.close
+ raise
+ end
+ if block_given?
+ begin
yield sock
- else
- sock
+ ensure
+ sock.close if !sock.closed?
end
- ensure
- sock.close if !sock.closed? && (block_given? || $!)
+ else
+ sock
end
end
@@ -278,8 +293,9 @@ class Socket < BasicSocket
# :stopdoc:
def self.ip_sockets_port0(ai_list, reuseaddr)
+ sockets = []
begin
- sockets = []
+ sockets.clear
port = nil
ai_list.each {|ai|
begin
@@ -300,14 +316,13 @@ class Socket < BasicSocket
end
}
rescue Errno::EADDRINUSE
- sockets.each {|s|
- s.close
- }
+ sockets.each {|s| s.close }
retry
+ rescue Exception
+ sockets.each {|s| s.close }
+ raise
end
sockets
- ensure
- sockets.each {|s| s.close if !s.closed? } if $!
end
class << self
private :ip_sockets_port0
@@ -316,12 +331,15 @@ class Socket < BasicSocket
def self.tcp_server_sockets_port0(host)
ai_list = Addrinfo.getaddrinfo(host, 0, nil, :STREAM, nil, Socket::AI_PASSIVE)
sockets = ip_sockets_port0(ai_list, true)
- sockets.each {|s|
- s.listen(5)
- }
+ begin
+ sockets.each {|s|
+ s.listen(5)
+ }
+ rescue Exception
+ sockets.each {|s| s.close }
+ raise
+ end
sockets
- ensure
- sockets.each {|s| s.close if !s.closed? } if $! && sockets
end
class << self
private :tcp_server_sockets_port0
@@ -365,9 +383,9 @@ class Socket < BasicSocket
if port == 0
sockets = tcp_server_sockets_port0(host)
else
+ last_error = nil
+ sockets = []
begin
- last_error = nil
- sockets = []
Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai|
begin
s = ai.listen
@@ -380,8 +398,9 @@ class Socket < BasicSocket
if sockets.empty?
raise last_error
end
- ensure
- sockets.each {|s| s.close if !s.closed? } if $!
+ rescue Exception
+ sockets.each {|s| s.close }
+ raise
end
end
if block_given?
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
index e961b16474..d7ec8981d7 100644
--- a/lib/cgi/core.rb
+++ b/lib/cgi/core.rb
@@ -478,10 +478,12 @@ class CGI
bufsize = 10 * 1024
max_count = MAX_MULTIPART_COUNT
n = 0
+ tempfiles = []
while true
(n += 1) < max_count or raise StandardError.new("too many parameters.")
## create body (StringIO or Tempfile)
body = create_body(bufsize < content_length)
+ tempfiles << body if defined?(Tempfile) && body.kind_of?(Tempfile)
class << body
if method_defined?(:path)
alias local_path path
@@ -562,6 +564,15 @@ class CGI
raise EOFError, "bad boundary end of body part" unless boundary_end =~ /--/
params.default = []
params
+ rescue Exception
+ if tempfiles
+ tempfiles.each {|t|
+ if t.path
+ t.unlink
+ end
+ }
+ end
+ raise
end # read_multipart
private :read_multipart
def create_body(is_large) #:nodoc:
diff --git a/lib/drb/ssl.rb b/lib/drb/ssl.rb
index 2b6a2376ef..a680594d80 100644
--- a/lib/drb/ssl.rb
+++ b/lib/drb/ssl.rb
@@ -179,8 +179,9 @@ module DRb
end
begin
ssl = @config.accept(soc)
- ensure
- soc.close if $!
+ rescue Exception
+ soc.close
+ raise
end
self.class.new(uri, ssl, @config, true)
rescue OpenSSL::SSL::SSLError
diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb
index f693a62e4b..548288817f 100644
--- a/test/socket/test_socket.rb
+++ b/test/socket/test_socket.rb
@@ -454,4 +454,75 @@ class TestSocket < Test::Unit::TestCase
ensure
server.close
end
+
+ def test_connect_in_rescue
+ serv = Addrinfo.tcp(nil, 0).listen
+ addr = serv.connect_address
+ begin
+ raise "dummy error"
+ rescue
+ s = addr.connect
+ assert(!s.closed?)
+ end
+ ensure
+ serv.close if serv && !serv.closed?
+ s.close if s && !s.closed?
+ end
+
+ def test_bind_in_rescue
+ begin
+ raise "dummy error"
+ rescue
+ s = Addrinfo.tcp(nil, 0).bind
+ assert(!s.closed?)
+ end
+ ensure
+ s.close if s && !s.closed?
+ end
+
+ def test_listen_in_rescue
+ begin
+ raise "dummy error"
+ rescue
+ s = Addrinfo.tcp(nil, 0).listen
+ assert(!s.closed?)
+ end
+ ensure
+ s.close if s && !s.closed?
+ end
+
+ def test_udp_server_sockets_in_rescue
+ begin
+ raise "dummy error"
+ rescue
+ ss = Socket.udp_server_sockets(0)
+ ss.each {|s|
+ assert(!s.closed?)
+ }
+ end
+ ensure
+ if ss
+ ss.each {|s|
+ s.close if !s.closed?
+ }
+ end
+ end
+
+ def test_tcp_server_sockets_in_rescue
+ begin
+ raise "dummy error"
+ rescue
+ ss = Socket.tcp_server_sockets(0)
+ ss.each {|s|
+ assert(!s.closed?)
+ }
+ end
+ ensure
+ if ss
+ ss.each {|s|
+ s.close if !s.closed?
+ }
+ end
+ end
+
end if defined?(Socket)
diff --git a/version.h b/version.h
index ad3b0dbef5..4f92408e40 100644
--- a/version.h
+++ b/version.h
@@ -1,5 +1,5 @@
#define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 509
+#define RUBY_PATCHLEVEL 510
#define RUBY_RELEASE_DATE "2014-01-30"
#define RUBY_RELEASE_YEAR 2014