summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--ext/openssl/ossl_ssl.c14
-rw-r--r--test/openssl/test_ssl.rb27
-rw-r--r--version.h2
4 files changed, 46 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 81351a256b..bbcdfdab22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue May 14 11:24:22 2013 Martin Bosslet <Martin.Bosslet@gmail.com>
+
+ * ext/openssl/ossl_ssl.c: Correct shutdown behavior w.r.t GC.
+
+ * test/openssl/test_ssl.rb: Add tests to verify correct behavior.
+
+ [Bug #8240] Patch provided by Shugo Maeda. Thanks!
+
Tue May 14 11:22:33 2013 Naohisa Goto <ngotogenome@gmail.com>
* configure.in (AC_CHECK_HEADERS): atomic.h for Solaris atomic_ops.
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 2b52bf07c3..e437e7ecd6 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -995,7 +995,6 @@ ossl_ssl_shutdown(SSL *ssl)
static void
ossl_ssl_free(SSL *ssl)
{
- ossl_ssl_shutdown(ssl);
SSL_free(ssl);
}
@@ -1405,9 +1404,16 @@ ossl_ssl_close(VALUE self)
SSL *ssl;
Data_Get_Struct(self, SSL, ssl);
- ossl_ssl_shutdown(ssl);
- if (RTEST(ossl_ssl_get_sync_close(self)))
- rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0);
+ if (ssl) {
+ VALUE io = ossl_ssl_get_io(self);
+ if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
+ ossl_ssl_shutdown(ssl);
+ SSL_free(ssl);
+ DATA_PTR(self) = NULL;
+ if (RTEST(ossl_ssl_get_sync_close(self)))
+ rb_funcall(io, rb_intern("close"), 0);
+ }
+ }
return Qnil;
}
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 5d40a5576b..cf0f1b7bba 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -438,6 +438,33 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
+ def test_invalid_shutdown_by_gc
+ assert_nothing_raised {
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ 10.times {
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ GC.start
+ ssl.connect
+ sock.close
+ }
+ }
+ }
+ end
+
+ def test_close_after_socket_close
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ ssl.connect
+ sock.close
+ assert_nothing_raised do
+ ssl.close
+ end
+ }
+ end
+
end
end
diff --git a/version.h b/version.h
index beeb5c309a..b290241013 100644
--- a/version.h
+++ b/version.h
@@ -1,5 +1,5 @@
#define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 420
+#define RUBY_PATCHLEVEL 421
#define RUBY_RELEASE_DATE "2013-05-14"
#define RUBY_RELEASE_YEAR 2013