* [gentoo-commits] proj/ruby-scripts:master commit in: patchsets/patches-ee-1.8.7-2010.02-r1/
@ 2011-05-15 6:24 Hans de Graaff
0 siblings, 0 replies; only message in thread
From: Hans de Graaff @ 2011-05-15 6:24 UTC (permalink / raw
To: gentoo-commits
commit: a0da514e1682ea6ad1bd1ebca9c4b95a8625f4e6
Author: Hans de Graaff <hans <AT> degraaff <DOT> org>
AuthorDate: Sun May 15 06:24:04 2011 +0000
Commit: Hans de Graaff <graaff <AT> gentoo <DOT> org>
CommitDate: Sun May 15 06:24:04 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/ruby-scripts.git;a=commit;h=a0da514e
Add missing patchset for ruby enterprise 2010.02-r1.
---
.../001_memory_leak.patch | 59 +
.../patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch | 16 +
.../003_mkmf-parallel-install.patch | 16 +
.../004_configure-libdir.patch | 13 +
.../005_mkconfig-libdir.patch | 15 +
.../006_pathname_warning.patch | 16 +
.../007_no-undefined-ext.patch | 13 +
.../008_berkdb-5.0.patch | 13 +
.../patches-ee-1.8.7-2010.02-r1/010_openssl1.patch | 2500 ++++++++++++++++++++
.../012_webrick-CVE-2010-0541.patch | 15 +
.../999-fast-threading-NOAPPLY.diff | 1320 +++++++++++
patchsets/patches-ee-1.8.7-2010.02-r1/series | 10 +
12 files changed, 4006 insertions(+), 0 deletions(-)
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch
new file mode 100644
index 0000000..25853be
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch
@@ -0,0 +1,59 @@
+Index: source/ext/dl/handle.c
+===================================================================
+--- source.orig/ext/dl/handle.c
++++ source/ext/dl/handle.c
+@@ -10,9 +10,12 @@ VALUE rb_cDLHandle;
+ void
+ dlhandle_free(struct dl_handle *dlhandle)
+ {
++ if (!dlhandle)
++ return;
+ if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {
+ dlclose(dlhandle->ptr);
+ }
++ dlfree(dlhandle);
+ }
+
+ VALUE
+Index: source/ext/dl/ptr.c
+===================================================================
+--- source.orig/ext/dl/ptr.c
++++ source/ext/dl/ptr.c
+@@ -45,6 +45,8 @@ rb_dlmem_aref(void *ptr)
+ void
+ dlptr_free(struct ptr_data *data)
+ {
++ if (!data)
++ return;
+ if (data->ptr) {
+ DEBUG_CODE({
+ printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n",
+@@ -61,6 +63,7 @@ dlptr_free(struct ptr_data *data)
+ if (data->stype) dlfree(data->stype);
+ if (data->ssize) dlfree(data->ssize);
+ if (data->ids) dlfree(data->ids);
++ dlfree(data);
+ }
+
+ void
+Index: source/ext/dl/sym.c
+===================================================================
+--- source.orig/ext/dl/sym.c
++++ source/ext/dl/sym.c
+@@ -57,6 +57,8 @@ char2type(int ch)
+ void
+ dlsym_free(struct sym_data *data)
+ {
++ if(!data)
++ return;
+ if( data->name ){
+ DEBUG_CODE({
+ printf("dlsym_free(): free(data->name:%s)\n",data->name);
+@@ -69,6 +71,7 @@ dlsym_free(struct sym_data *data)
+ });
+ free(data->type);
+ }
++ dlfree(data);
+ }
+
+ VALUE
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch
new file mode 100644
index 0000000..6574925
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch
@@ -0,0 +1,16 @@
+Fix for mkconfig to be able to handle empty continued lines.
+Patch from [ruby-core:20420] via bug 234877.
+
+Index: source/mkconfig.rb
+===================================================================
+--- source.orig/mkconfig.rb
++++ source/mkconfig.rb
+@@ -55,7 +55,7 @@ File.foreach "config.status" do |line|
+ continued_name = name
+ next
+ end
+- when /^"(.+)"\s*(\\)?$/
++ when /^"(.*)"\s*(\\)?$/
+ if continued_line
+ continued_line << $1
+ unless $2
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch
new file mode 100644
index 0000000..41bf2bc
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch
@@ -0,0 +1,16 @@
+ Patch for bug 239101 by Matsuu Takuto, via Redmine issue 1337 (yes, really).
+ Backported for 1.8.* by Alex Legler.
+
+Index: source/lib/mkmf.rb
+===================================================================
+--- source.orig/lib/mkmf.rb
++++ source/lib/mkmf.rb
+@@ -1523,7 +1523,7 @@ static: $(STATIC_LIB)#{$extout ? " inst
+ dest = "#{dir}/#{f}"
+ mfile.puts dir, "install-so: #{dest}"
+ unless $extout
+- mfile.print "#{dest}: #{f}\n"
++ mfile.print "#{dest}: #{dir} #{f}\n"
+ if (sep = config_string('BUILD_FILE_SEPARATOR'))
+ f.gsub!("/", sep)
+ dir.gsub!("/", sep)
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch
new file mode 100644
index 0000000..b7f17fa
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch
@@ -0,0 +1,13 @@
+Index: source/configure.in
+===================================================================
+--- source.orig/configure.in
++++ source/configure.in
+@@ -1730,7 +1730,7 @@ case "$target_os" in
+ rubyw_install_name="$RUBYW_INSTALL_NAME"
+ ;;
+ esac
+-RUBY_LIB_PREFIX=`eval echo \\"${libdir}/ruby\\"`
++RUBY_LIB_PREFIX=`eval echo \\"${libdir}/rubyee\\"`
+
+ AC_ARG_WITH(sitedir,
+ [ --with-sitedir=DIR site libraries in DIR [[LIBDIR/ruby/site_ruby]]],
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch
new file mode 100644
index 0000000..932a4e3
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch
@@ -0,0 +1,15 @@
+Evil hack fiddling with the ruby libdir
+
+Index: source/mkconfig.rb
+===================================================================
+--- source.orig/mkconfig.rb
++++ source/mkconfig.rb
+@@ -141,7 +141,7 @@ print(*v_fast)
+ print(*v_others)
+ print <<EOS
+ CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)"
+- CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)"
++ CONFIG["rubylibdir"] = "$(libdir)/rubyee/$(ruby_version)"
+ CONFIG["archdir"] = "$(rubylibdir)/$(arch)"
+ CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)"
+ CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)"
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch
new file mode 100644
index 0000000..ed051d3
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch
@@ -0,0 +1,16 @@
+Fix a warning shown in Pathname#sub. Asked upstream for inclusion in redmine
+issue 2538 -a3li
+
+Index: source/lib/pathname.rb
+===================================================================
+--- source.orig/lib/pathname.rb
++++ source/lib/pathname.rb
+@@ -260,7 +260,7 @@ class Pathname
+ ensure
+ Thread.current[:pathname_sub_matchdata] = old
+ end
+- yield *args
++ yield(*args)
+ }
+ else
+ path = @path.sub(pattern, *rest)
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch
new file mode 100644
index 0000000..a122561
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch
@@ -0,0 +1,13 @@
+Index: source/configure.in
+===================================================================
+--- source.orig/configure.in
++++ source/configure.in
+@@ -1201,7 +1201,7 @@ if test "$with_dln_a_out" != yes; then
+ linux* | gnu* | k*bsd*-gnu | netbsd* | bsdi*)
+ : ${LDSHARED='${CC} -shared'}
+ if test "$rb_cv_binary_elf" = yes; then
+- LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
++ LDFLAGS="$LDFLAGS -Wl,-export-dynamic -Wl,--no-undefined"
+ fi
+ rb_cv_dlopen=yes ;;
+ interix*) : ${LDSHARED="$CC -shared"}
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch
new file mode 100644
index 0000000..096a1bf
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch
@@ -0,0 +1,13 @@
+Index: ruby-1.8.7-p249/ext/dbm/extconf.rb
+===================================================================
+--- ruby-1.8.7-p249.orig/ext/dbm/extconf.rb
++++ ruby-1.8.7-p249/ext/dbm/extconf.rb
+@@ -26,7 +26,7 @@ def headers.db_check(db)
+ case db
+ when /^db2?$/
+ db_prefix = "__db_n"
+- hsearch = "-DDB_DBM_HSEARCH "
++ hsearch = "-DDB_DBM_HSEARCH -DHAVE_DBM "
+ when "gdbm"
+ have_gdbm = true
+ when "gdbm_compat"
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch
new file mode 100644
index 0000000..bdec751
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch
@@ -0,0 +1,2500 @@
+Sync OpenSSL module to the 1.8.7_p299 version. Backport by a3li@g.o
+Upstream: reported, but not yet fixed
+Gentoo bug 326633
+
+diff -Naur source.old/ext/openssl/extconf.rb source/ext/openssl/extconf.rb
+--- source.old/ext/openssl/extconf.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/extconf.rb 2010-08-06 12:43:44.802276474 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: extconf.rb 28367 2010-06-21 09:18:59Z shyouhei $
+ =end
+
+ require "mkmf"
+@@ -91,12 +91,13 @@
+ have_func("X509_CRL_set_issuer_name")
+ have_func("X509_CRL_set_version")
+ have_func("X509_CRL_sort")
++have_func("X509_NAME_hash_old")
+ have_func("X509_STORE_get_ex_data")
+ have_func("X509_STORE_set_ex_data")
+ have_func("OBJ_NAME_do_all_sorted")
+ have_func("SSL_SESSION_get_id")
+ have_func("OPENSSL_cleanse")
+-if try_compile("#define FOO(a, ...) foo(a, ##__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n")
++if try_compile("#define FOO(...) foo(__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n")
+ $defs.push("-DHAVE_VA_ARGS_MACRO")
+ end
+ if have_header("openssl/engine.h")
+@@ -106,6 +107,14 @@
+ have_func("ENGINE_get_digest")
+ have_func("ENGINE_get_cipher")
+ have_func("ENGINE_cleanup")
++ have_func("ENGINE_load_4758cca")
++ have_func("ENGINE_load_aep")
++ have_func("ENGINE_load_atalla")
++ have_func("ENGINE_load_chil")
++ have_func("ENGINE_load_cswift")
++ have_func("ENGINE_load_nuron")
++ have_func("ENGINE_load_sureware")
++ have_func("ENGINE_load_ubsec")
+ end
+ if try_compile(<<SRC)
+ #include <openssl/opensslv.h>
+diff -Naur source.old/ext/openssl/lib/net/ftptls.rb source/ext/openssl/lib/net/ftptls.rb
+--- source.old/ext/openssl/lib/net/ftptls.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/net/ftptls.rb 2010-08-06 12:43:44.802276474 +0200
+@@ -13,7 +13,7 @@
+ = Requirements
+
+ = Version
+- $Id$
++ $Id: ftptls.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
+
+ = Notes
+ Tested on FreeBSD 5-CURRENT and 4-STABLE
+diff -Naur source.old/ext/openssl/lib/net/telnets.rb source/ext/openssl/lib/net/telnets.rb
+--- source.old/ext/openssl/lib/net/telnets.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/net/telnets.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: telnets.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
+
+ 2001/11/06: Contiributed to Ruby/OpenSSL project.
+
+diff -Naur source.old/ext/openssl/lib/openssl/bn.rb source/ext/openssl/lib/openssl/bn.rb
+--- source.old/ext/openssl/lib/openssl/bn.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/bn.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: bn.rb 11708 2007-02-12 23:01:19Z shyouhei $
+ =end
+
+ ##
+diff -Naur source.old/ext/openssl/lib/openssl/buffering.rb source/ext/openssl/lib/openssl/buffering.rb
+--- source.old/ext/openssl/lib/openssl/buffering.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/buffering.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -11,9 +11,10 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: buffering.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+
++module OpenSSL
+ module Buffering
+ include Enumerable
+ attr_accessor :sync
+@@ -237,3 +238,4 @@
+ sysclose
+ end
+ end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/cipher.rb source/ext/openssl/lib/openssl/cipher.rb
+--- source.old/ext/openssl/lib/openssl/cipher.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/cipher.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: cipher.rb 12496 2007-06-08 15:02:04Z technorama $
+ =end
+
+ ##
+diff -Naur source.old/ext/openssl/lib/openssl/digest.rb source/ext/openssl/lib/openssl/digest.rb
+--- source.old/ext/openssl/lib/openssl/digest.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/digest.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: digest.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+
+ ##
+@@ -40,7 +40,7 @@
+ super(name, data.first)
+ }
+ }
+- singleton = (class <<klass; self; end)
++ singleton = (class << klass; self; end)
+ singleton.class_eval{
+ define_method(:digest){|data| Digest.digest(name, data) }
+ define_method(:hexdigest){|data| Digest.hexdigest(name, data) }
+diff -Naur source.old/ext/openssl/lib/openssl/ssl-internal.rb source/ext/openssl/lib/openssl/ssl-internal.rb
+--- source.old/ext/openssl/lib/openssl/ssl-internal.rb 1970-01-01 01:00:00.000000000 +0100
++++ source/ext/openssl/lib/openssl/ssl-internal.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -0,0 +1,179 @@
++=begin
++= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
++
++= Info
++ 'OpenSSL for Ruby 2' project
++ Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
++ All rights reserved.
++
++= Licence
++ This program is licenced under the same licence as Ruby.
++ (See the file 'LICENCE'.)
++
++= Version
++ $Id$
++=end
++
++require "openssl/buffering"
++require "fcntl"
++
++module OpenSSL
++ module SSL
++ class SSLContext
++ DEFAULT_PARAMS = {
++ :ssl_version => "SSLv23",
++ :verify_mode => OpenSSL::SSL::VERIFY_PEER,
++ :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
++ :options => OpenSSL::SSL::OP_ALL,
++ }
++
++ DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
++ DEFAULT_CERT_STORE.set_default_paths
++ if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
++ DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
++ end
++
++ def set_params(params={})
++ params = DEFAULT_PARAMS.merge(params)
++ # ssl_version need to be set at first.
++ self.ssl_version = params.delete(:ssl_version)
++ params.each{|name, value| self.__send__("#{name}=", value) }
++ if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
++ unless self.ca_file or self.ca_path or self.cert_store
++ self.cert_store = DEFAULT_CERT_STORE
++ end
++ end
++ return params
++ end
++ end
++
++ module SocketForwarder
++ def addr
++ to_io.addr
++ end
++
++ def peeraddr
++ to_io.peeraddr
++ end
++
++ def setsockopt(level, optname, optval)
++ to_io.setsockopt(level, optname, optval)
++ end
++
++ def getsockopt(level, optname)
++ to_io.getsockopt(level, optname)
++ end
++
++ def fcntl(*args)
++ to_io.fcntl(*args)
++ end
++
++ def closed?
++ to_io.closed?
++ end
++
++ def do_not_reverse_lookup=(flag)
++ to_io.do_not_reverse_lookup = flag
++ end
++ end
++
++ module Nonblock
++ def initialize(*args)
++ flag = File::NONBLOCK
++ flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
++ @io.fcntl(Fcntl::F_SETFL, flag)
++ super
++ end
++ end
++
++ def verify_certificate_identity(cert, hostname)
++ should_verify_common_name = true
++ cert.extensions.each{|ext|
++ next if ext.oid != "subjectAltName"
++ ext.value.split(/,\s+/).each{|general_name|
++ if /\ADNS:(.*)/ =~ general_name
++ should_verify_common_name = false
++ reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
++ return true if /\A#{reg}\z/i =~ hostname
++ elsif /\AIP Address:(.*)/ =~ general_name
++ should_verify_common_name = false
++ return true if $1 == hostname
++ end
++ }
++ }
++ if should_verify_common_name
++ cert.subject.to_a.each{|oid, value|
++ if oid == "CN"
++ reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
++ return true if /\A#{reg}\z/i =~ hostname
++ end
++ }
++ end
++ return false
++ end
++ module_function :verify_certificate_identity
++
++ class SSLSocket
++ include Buffering
++ include SocketForwarder
++ include Nonblock
++
++ def post_connection_check(hostname)
++ unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
++ raise SSLError, "hostname was not match with the server certificate"
++ end
++ return true
++ end
++
++ def session
++ SSL::Session.new(self)
++ rescue SSL::Session::SessionError
++ nil
++ end
++ end
++
++ class SSLServer
++ include SocketForwarder
++ attr_accessor :start_immediately
++
++ def initialize(svr, ctx)
++ @svr = svr
++ @ctx = ctx
++ unless ctx.session_id_context
++ session_id = OpenSSL::Digest::MD5.hexdigest($0)
++ @ctx.session_id_context = session_id
++ end
++ @start_immediately = true
++ end
++
++ def to_io
++ @svr
++ end
++
++ def listen(backlog=5)
++ @svr.listen(backlog)
++ end
++
++ def shutdown(how=Socket::SHUT_RDWR)
++ @svr.shutdown(how)
++ end
++
++ def accept
++ sock = @svr.accept
++ begin
++ ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
++ ssl.sync_close = true
++ ssl.accept if @start_immediately
++ ssl
++ rescue SSLError => ex
++ sock.close
++ raise ex
++ end
++ end
++
++ def close
++ @svr.close
++ end
++ end
++ end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/ssl.rb source/ext/openssl/lib/openssl/ssl.rb
+--- source.old/ext/openssl/lib/openssl/ssl.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/ssl.rb 2010-08-06 12:43:44.814276754 +0200
+@@ -1,179 +1 @@
+-=begin
+-= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
+-
+-= Info
+- 'OpenSSL for Ruby 2' project
+- Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
+- All rights reserved.
+-
+-= Licence
+- This program is licenced under the same licence as Ruby.
+- (See the file 'LICENCE'.)
+-
+-= Version
+- $Id$
+-=end
+-
+-require "openssl"
+-require "openssl/buffering"
+-require "fcntl"
+-
+-module OpenSSL
+- module SSL
+- class SSLContext
+- DEFAULT_PARAMS = {
+- :ssl_version => "SSLv23",
+- :verify_mode => OpenSSL::SSL::VERIFY_PEER,
+- :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
+- :options => OpenSSL::SSL::OP_ALL,
+- }
+-
+- DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
+- DEFAULT_CERT_STORE.set_default_paths
+- if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
+- DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
+- end
+-
+- def set_params(params={})
+- params = DEFAULT_PARAMS.merge(params)
+- self.ssl_version = params.delete(:ssl_version)
+- params.each{|name, value| self.__send__("#{name}=", value) }
+- if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
+- unless self.ca_file or self.ca_path or self.cert_store
+- self.cert_store = DEFAULT_CERT_STORE
+- end
+- end
+- return params
+- end
+- end
+-
+- module SocketForwarder
+- def addr
+- to_io.addr
+- end
+-
+- def peeraddr
+- to_io.peeraddr
+- end
+-
+- def setsockopt(level, optname, optval)
+- to_io.setsockopt(level, optname, optval)
+- end
+-
+- def getsockopt(level, optname)
+- to_io.getsockopt(level, optname)
+- end
+-
+- def fcntl(*args)
+- to_io.fcntl(*args)
+- end
+-
+- def closed?
+- to_io.closed?
+- end
+-
+- def do_not_reverse_lookup=(flag)
+- to_io.do_not_reverse_lookup = flag
+- end
+- end
+-
+- module Nonblock
+- def initialize(*args)
+- flag = File::NONBLOCK
+- flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
+- @io.fcntl(Fcntl::F_SETFL, flag)
+- super
+- end
+- end
+-
+- def verify_certificate_identity(cert, hostname)
+- should_verify_common_name = true
+- cert.extensions.each{|ext|
+- next if ext.oid != "subjectAltName"
+- ext.value.split(/,\s+/).each{|general_name|
+- if /\ADNS:(.*)/ =~ general_name
+- should_verify_common_name = false
+- reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
+- return true if /\A#{reg}\z/i =~ hostname
+- elsif /\AIP Address:(.*)/ =~ general_name
+- should_verify_common_name = false
+- return true if $1 == hostname
+- end
+- }
+- }
+- if should_verify_common_name
+- cert.subject.to_a.each{|oid, value|
+- if oid == "CN"
+- reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
+- return true if /\A#{reg}\z/i =~ hostname
+- end
+- }
+- end
+- return false
+- end
+- module_function :verify_certificate_identity
+-
+- class SSLSocket
+- include Buffering
+- include SocketForwarder
+- include Nonblock
+-
+- def post_connection_check(hostname)
+- unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
+- raise SSLError, "hostname was not match with the server certificate"
+- end
+- return true
+- end
+-
+- def session
+- SSL::Session.new(self)
+- rescue SSL::Session::SessionError
+- nil
+- end
+- end
+-
+- class SSLServer
+- include SocketForwarder
+- attr_accessor :start_immediately
+-
+- def initialize(svr, ctx)
+- @svr = svr
+- @ctx = ctx
+- unless ctx.session_id_context
+- session_id = OpenSSL::Digest::MD5.hexdigest($0)
+- @ctx.session_id_context = session_id
+- end
+- @start_immediately = true
+- end
+-
+- def to_io
+- @svr
+- end
+-
+- def listen(backlog=5)
+- @svr.listen(backlog)
+- end
+-
+- def shutdown(how=Socket::SHUT_RDWR)
+- @svr.shutdown(how)
+- end
+-
+- def accept
+- sock = @svr.accept
+- begin
+- ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
+- ssl.sync_close = true
+- ssl.accept if @start_immediately
+- ssl
+- rescue SSLError => ex
+- sock.close
+- raise ex
+- end
+- end
+-
+- def close
+- @svr.close
+- end
+- end
+- end
+-end
++require 'openssl'
+diff -Naur source.old/ext/openssl/lib/openssl/x509-internal.rb source/ext/openssl/lib/openssl/x509-internal.rb
+--- source.old/ext/openssl/lib/openssl/x509-internal.rb 1970-01-01 01:00:00.000000000 +0100
++++ source/ext/openssl/lib/openssl/x509-internal.rb 2010-08-06 12:43:44.818276265 +0200
+@@ -0,0 +1,153 @@
++=begin
++= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
++
++= Info
++ 'OpenSSL for Ruby 2' project
++ Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
++ All rights reserved.
++
++= Licence
++ This program is licenced under the same licence as Ruby.
++ (See the file 'LICENCE'.)
++
++= Version
++ $Id$
++=end
++
++module OpenSSL
++ module X509
++ class ExtensionFactory
++ def create_extension(*arg)
++ if arg.size > 1
++ create_ext(*arg)
++ else
++ send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
++ end
++ end
++
++ def create_ext_from_array(ary)
++ raise ExtensionError, "unexpected array form" if ary.size > 3
++ create_ext(ary[0], ary[1], ary[2])
++ end
++
++ def create_ext_from_string(str) # "oid = critical, value"
++ oid, value = str.split(/=/, 2)
++ oid.strip!
++ value.strip!
++ create_ext(oid, value)
++ end
++
++ def create_ext_from_hash(hash)
++ create_ext(hash["oid"], hash["value"], hash["critical"])
++ end
++ end
++
++ class Extension
++ def to_s # "oid = critical, value"
++ str = self.oid
++ str << " = "
++ str << "critical, " if self.critical?
++ str << self.value.gsub(/\n/, ", ")
++ end
++
++ def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
++ {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
++ end
++
++ def to_a
++ [ self.oid, self.value, self.critical? ]
++ end
++ end
++
++ class Name
++ module RFC2253DN
++ Special = ',=+<>#;'
++ HexChar = /[0-9a-fA-F]/
++ HexPair = /#{HexChar}#{HexChar}/
++ HexString = /#{HexPair}+/
++ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
++ StringChar = /[^#{Special}\\"]/
++ QuoteChar = /[^\\"]/
++ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
++ AttributeValue = /
++ (?!["#])((?:#{StringChar}|#{Pair})*)|
++ \#(#{HexString})|
++ "((?:#{QuoteChar}|#{Pair})*)"
++ /x
++ TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
++
++ module_function
++
++ def expand_pair(str)
++ return nil unless str
++ return str.gsub(Pair){
++ pair = $&
++ case pair.size
++ when 2 then pair[1,1]
++ when 3 then Integer("0x#{pair[1,2]}").chr
++ else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
++ end
++ }
++ end
++
++ def expand_hexstring(str)
++ return nil unless str
++ der = str.gsub(HexPair){$&.to_i(16).chr }
++ a1 = OpenSSL::ASN1.decode(der)
++ return a1.value, a1.tag
++ end
++
++ def expand_value(str1, str2, str3)
++ value = expand_pair(str1)
++ value, tag = expand_hexstring(str2) unless value
++ value = expand_pair(str3) unless value
++ return value, tag
++ end
++
++ def scan(dn)
++ str = dn
++ ary = []
++ while true
++ if md = TypeAndValue.match(str)
++ matched = md.to_s
++ remain = md.post_match
++ type = md[1]
++ value, tag = expand_value(md[2], md[3], md[4]) rescue nil
++ if value
++ type_and_value = [type, value]
++ type_and_value.push(tag) if tag
++ ary.unshift(type_and_value)
++ if remain.length > 2 && remain[0] == ?,
++ str = remain[1..-1]
++ next
++ elsif remain.length > 2 && remain[0] == ?+
++ raise OpenSSL::X509::NameError,
++ "multi-valued RDN is not supported: #{dn}"
++ elsif remain.empty?
++ break
++ end
++ end
++ end
++ msg_dn = dn[0, dn.length - str.length] + " =>" + str
++ raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
++ end
++ return ary
++ end
++ end
++
++ class <<self
++ def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
++ ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
++ self.new(ary, template)
++ end
++
++ def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
++ ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
++ self.new(ary, template)
++ end
++
++ alias parse parse_openssl
++ end
++ end
++ end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/x509.rb source/ext/openssl/lib/openssl/x509.rb
+--- source.old/ext/openssl/lib/openssl/x509.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/x509.rb 2010-08-06 12:43:44.818276265 +0200
+@@ -1,154 +1 @@
+-=begin
+-= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
+-
+-= Info
+- 'OpenSSL for Ruby 2' project
+- Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
+- All rights reserved.
+-
+-= Licence
+- This program is licenced under the same licence as Ruby.
+- (See the file 'LICENCE'.)
+-
+-= Version
+- $Id$
+-=end
+-
+-require "openssl"
+-
+-module OpenSSL
+- module X509
+- class ExtensionFactory
+- def create_extension(*arg)
+- if arg.size > 1
+- create_ext(*arg)
+- else
+- send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
+- end
+- end
+-
+- def create_ext_from_array(ary)
+- raise ExtensionError, "unexpected array form" if ary.size > 3
+- create_ext(ary[0], ary[1], ary[2])
+- end
+-
+- def create_ext_from_string(str) # "oid = critical, value"
+- oid, value = str.split(/=/, 2)
+- oid.strip!
+- value.strip!
+- create_ext(oid, value)
+- end
+-
+- def create_ext_from_hash(hash)
+- create_ext(hash["oid"], hash["value"], hash["critical"])
+- end
+- end
+-
+- class Extension
+- def to_s # "oid = critical, value"
+- str = self.oid
+- str << " = "
+- str << "critical, " if self.critical?
+- str << self.value.gsub(/\n/, ", ")
+- end
+-
+- def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
+- {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
+- end
+-
+- def to_a
+- [ self.oid, self.value, self.critical? ]
+- end
+- end
+-
+- class Name
+- module RFC2253DN
+- Special = ',=+<>#;'
+- HexChar = /[0-9a-fA-F]/
+- HexPair = /#{HexChar}#{HexChar}/
+- HexString = /#{HexPair}+/
+- Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
+- StringChar = /[^#{Special}\\"]/
+- QuoteChar = /[^\\"]/
+- AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
+- AttributeValue = /
+- (?!["#])((?:#{StringChar}|#{Pair})*)|
+- \#(#{HexString})|
+- "((?:#{QuoteChar}|#{Pair})*)"
+- /x
+- TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
+-
+- module_function
+-
+- def expand_pair(str)
+- return nil unless str
+- return str.gsub(Pair){|pair|
+- case pair.size
+- when 2 then pair[1,1]
+- when 3 then Integer("0x#{pair[1,2]}").chr
+- else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
+- end
+- }
+- end
+-
+- def expand_hexstring(str)
+- return nil unless str
+- der = str.gsub(HexPair){|hex| Integer("0x#{hex}").chr }
+- a1 = OpenSSL::ASN1.decode(der)
+- return a1.value, a1.tag
+- end
+-
+- def expand_value(str1, str2, str3)
+- value = expand_pair(str1)
+- value, tag = expand_hexstring(str2) unless value
+- value = expand_pair(str3) unless value
+- return value, tag
+- end
+-
+- def scan(dn)
+- str = dn
+- ary = []
+- while true
+- if md = TypeAndValue.match(str)
+- matched = md.to_s
+- remain = md.post_match
+- type = md[1]
+- value, tag = expand_value(md[2], md[3], md[4]) rescue nil
+- if value
+- type_and_value = [type, value]
+- type_and_value.push(tag) if tag
+- ary.unshift(type_and_value)
+- if remain.length > 2 && remain[0] == ?,
+- str = remain[1..-1]
+- next
+- elsif remain.length > 2 && remain[0] == ?+
+- raise OpenSSL::X509::NameError,
+- "multi-valued RDN is not supported: #{dn}"
+- elsif remain.empty?
+- break
+- end
+- end
+- end
+- msg_dn = dn[0, dn.length - str.length] + " =>" + str
+- raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
+- end
+- return ary
+- end
+- end
+-
+- class <<self
+- def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
+- ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
+- self.new(ary, template)
+- end
+-
+- def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
+- ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
+- self.new(ary, template)
+- end
+-
+- alias parse parse_openssl
+- end
+- end
+- end
+-end
++require 'openssl'
+diff -Naur source.old/ext/openssl/lib/openssl.rb source/ext/openssl/lib/openssl.rb
+--- source.old/ext/openssl/lib/openssl.rb 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl.rb 2010-08-06 12:43:44.818276265 +0200
+@@ -11,7 +11,7 @@
+ (See the file 'LICENCE'.)
+
+ = Version
+- $Id$
++ $Id: openssl.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+
+ require 'openssl.so'
+@@ -20,6 +20,6 @@
+ require 'openssl/cipher'
+ require 'openssl/digest'
+ require 'openssl/pkcs7'
+-require 'openssl/ssl'
+-require 'openssl/x509'
++require 'openssl/ssl-internal'
++require 'openssl/x509-internal'
+
+diff -Naur source.old/ext/openssl/openssl_missing.c source/ext/openssl/openssl_missing.c
+--- source.old/ext/openssl/openssl_missing.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/openssl_missing.c 2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: openssl_missing.c 16467 2008-05-19 03:00:52Z knu $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/openssl_missing.h source/ext/openssl/openssl_missing.h
+--- source.old/ext/openssl/openssl_missing.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/openssl_missing.h 2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: openssl_missing.h 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -18,6 +18,9 @@
+ #ifndef TYPEDEF_D2I_OF
+ typedef char *d2i_of_void();
+ #endif
++#ifndef TYPEDEF_I2D_OF
++typedef int i2d_of_void();
++#endif
+
+ /*
+ * These functions are not included in headers of OPENSSL <= 0.9.6b
+@@ -30,33 +33,33 @@
+
+ #if !defined(PEM_write_bio_DSAPublicKey)
+ # define PEM_write_bio_DSAPublicKey(bp,x) \
+- PEM_ASN1_write_bio((int (*)())i2d_DSAPublicKey,\
++ PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPublicKey,\
+ PEM_STRING_DSA_PUBLIC,\
+ bp,(char *)x, NULL, NULL, 0, NULL, NULL)
+ #endif
+
+ #if !defined(DSAPrivateKey_dup)
+-# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPrivateKey, \
++# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \
+ (char *(*)())d2i_DSAPrivateKey,(char *)dsa)
+ #endif
+
+ #if !defined(DSAPublicKey_dup)
+-# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPublicKey, \
++# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \
+ (char *(*)())d2i_DSAPublicKey,(char *)dsa)
+ #endif
+
+ #if !defined(X509_REVOKED_dup)
+-# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((int (*)())i2d_X509_REVOKED, \
++# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
+ (char *(*)())d2i_X509_REVOKED, (char *)rev)
+ #endif
+
+ #if !defined(PKCS7_SIGNER_INFO_dup)
+-# define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((int (*)())i2d_PKCS7_SIGNER_INFO, \
++# define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \
+ (char *(*)())d2i_PKCS7_SIGNER_INFO, (char *)si)
+ #endif
+
+ #if !defined(PKCS7_RECIP_INFO_dup)
+-# define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((int (*)())i2d_PKCS7_RECIP_INFO, \
++# define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \
+ (char *(*)())d2i_PKCS7_RECIP_INFO, (char *)ri)
+ #endif
+
+diff -Naur source.old/ext/openssl/ossl_asn1.c source/ext/openssl/ossl_asn1.c
+--- source.old/ext/openssl/ossl_asn1.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_asn1.c 2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_asn1.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' team members
+ * Copyright (C) 2003
+ * All rights reserved.
+@@ -304,23 +304,23 @@
+ * DER to Ruby converters
+ */
+ static VALUE
+-decode_bool(OSSL_MORE_CONST unsigned char* der, int length)
++decode_bool(unsigned char* der, int length)
+ {
+- int bool;
+- OSSL_MORE_CONST unsigned char *p;
++ int val;
++ unsigned char *p;
+
+ p = der;
+- if((bool = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
++ if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
+ ossl_raise(eASN1Error, NULL);
+
+- return bool ? Qtrue : Qfalse;
++ return val ? Qtrue : Qfalse;
+ }
+
+ static VALUE
+-decode_int(OSSL_MORE_CONST unsigned char* der, int length)
++decode_int(unsigned char* der, int length)
+ {
+ ASN1_INTEGER *ai;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ VALUE ret;
+ int status = 0;
+
+@@ -336,11 +336,10 @@
+ }
+
+ static VALUE
+-decode_bstr(OSSL_MORE_CONST unsigned char* der, int length, long *unused_bits)
++decode_bstr(unsigned char* der, int length, long *unused_bits)
+ {
+ ASN1_BIT_STRING *bstr;
+- OSSL_MORE_CONST unsigned char *p;
+- unsigned char *buf;
++ const unsigned char *p;
+ long len;
+ VALUE ret;
+
+@@ -348,25 +347,20 @@
+ if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
+ ossl_raise(eASN1Error, NULL);
+ len = bstr->length;
+- if(!(buf = OPENSSL_malloc(len))){
+- ASN1_BIT_STRING_free(bstr);
+- ossl_raise(eASN1Error, NULL);
+- }
+ *unused_bits = 0;
+ if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
+ *unused_bits = bstr->flags & 0x07;
+- memcpy(buf, bstr->data, len);
++ ret = rb_str_new((const char *)bstr->data, len);
+ ASN1_BIT_STRING_free(bstr);
+- ret = ossl_buf2str(buf, len);
+
+ return ret;
+ }
+
+ static VALUE
+-decode_enum(OSSL_MORE_CONST unsigned char* der, int length)
++decode_enum(unsigned char* der, int length)
+ {
+ ASN1_ENUMERATED *ai;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ VALUE ret;
+ int status = 0;
+
+@@ -382,10 +376,10 @@
+ }
+
+ static VALUE
+-decode_null(OSSL_MORE_CONST unsigned char* der, int length)
++decode_null(unsigned char* der, int length)
+ {
+ ASN1_NULL *null;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+
+ p = der;
+ if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
+@@ -396,10 +390,10 @@
+ }
+
+ static VALUE
+-decode_obj(OSSL_MORE_CONST unsigned char* der, int length)
++decode_obj(unsigned char* der, int length)
+ {
+ ASN1_OBJECT *obj;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ VALUE ret;
+ int nid;
+ BIO *bio;
+@@ -425,10 +419,10 @@
+ }
+
+ static VALUE
+-decode_time(OSSL_MORE_CONST unsigned char* der, int length)
++decode_time(unsigned char* der, int length)
+ {
+ ASN1_TIME *time;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ VALUE ret;
+ int status = 0;
+
+@@ -501,7 +495,7 @@
+ value = ossl_asn1_get_value(obj);
+ switch(tag){
+ case V_ASN1_BOOLEAN:
+- ptr = (void*)obj_to_asn1bool(value);
++ ptr = (void*)(VALUE)obj_to_asn1bool(value);
+ free_func = NULL;
+ break;
+ case V_ASN1_INTEGER: /* FALLTHROUGH */
+@@ -713,10 +707,10 @@
+ }
+
+ static VALUE
+-ossl_asn1_decode0(OSSL_MORE_CONST unsigned char **pp, long length,
+- long *offset, long depth, int once, int yield)
++ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
++ int once, int yield)
+ {
+- OSSL_MORE_CONST unsigned char *start, *p;
++ unsigned char *start, *p;
+ long len, off = *offset;
+ int hlen, tag, tc, j;
+ VALUE ary, asn1data, value, tag_class;
+@@ -819,7 +813,7 @@
+ static VALUE
+ ossl_asn1_traverse(VALUE self, VALUE obj)
+ {
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ long offset = 0;
+ volatile VALUE tmp;
+
+@@ -835,7 +829,7 @@
+ ossl_asn1_decode(VALUE self, VALUE obj)
+ {
+ VALUE ret, ary;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ long offset = 0;
+ volatile VALUE tmp;
+
+@@ -852,7 +846,7 @@
+ ossl_asn1_decode_all(VALUE self, VALUE obj)
+ {
+ VALUE ret;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ long offset = 0;
+ volatile VALUE tmp;
+
+@@ -926,7 +920,7 @@
+ {
+ ASN1_TYPE *asn1;
+ int tn, tc, explicit;
+- long length, reallen;
++ long len, reallen;
+ unsigned char *buf, *p;
+ VALUE str;
+
+@@ -935,26 +929,24 @@
+ explicit = ossl_asn1_is_explicit(self);
+ asn1 = ossl_asn1_get_asn1type(self);
+
+- length = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
+- if(!(buf = OPENSSL_malloc(length))){
++ len = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
++ if(!(buf = OPENSSL_malloc(len))){
+ ossl_ASN1_TYPE_free(asn1);
+ ossl_raise(eASN1Error, "cannot alloc buffer");
+ }
+ p = buf;
+- if(tc == V_ASN1_UNIVERSAL) ossl_i2d_ASN1_TYPE(asn1, &p);
+- else{
+- if(explicit){
+- ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
+- ossl_i2d_ASN1_TYPE(asn1, &p);
+- }
+- else{
+- ossl_i2d_ASN1_TYPE(asn1, &p);
+- *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+- }
++ if (tc == V_ASN1_UNIVERSAL) {
++ ossl_i2d_ASN1_TYPE(asn1, &p);
++ } else if (explicit) {
++ ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
++ ossl_i2d_ASN1_TYPE(asn1, &p);
++ } else {
++ ossl_i2d_ASN1_TYPE(asn1, &p);
++ *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+ }
+ ossl_ASN1_TYPE_free(asn1);
+ reallen = p - buf;
+- assert(reallen <= length);
++ assert(reallen <= len);
+ str = ossl_buf2str(buf, reallen); /* buf will be free in ossl_buf2str */
+
+ return str;
+diff -Naur source.old/ext/openssl/ossl_asn1.h source/ext/openssl/ossl_asn1.h
+--- source.old/ext/openssl/ossl_asn1.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_asn1.h 2010-08-06 12:43:44.822276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_asn1.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' team members
+ * Copyright (C) 2003
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bio.c source/ext/openssl/ossl_bio.c
+--- source.old/ext/openssl/ossl_bio.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bio.c 2010-08-06 12:43:44.822276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bio.c 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' team members
+ * Copyright (C) 2003
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bio.h source/ext/openssl/ossl_bio.h
+--- source.old/ext/openssl/ossl_bio.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bio.h 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bio.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' team members
+ * Copyright (C) 2003
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bn.c source/ext/openssl/ossl_bn.c
+--- source.old/ext/openssl/ossl_bn.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bn.c 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bn.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net>
+ * All rights reserved.
+@@ -151,7 +151,7 @@
+ }
+ break;
+ default:
+- ossl_raise(rb_eArgError, "illegal radix %d", base);
++ ossl_raise(rb_eArgError, "invalid radix %d", base);
+ }
+ return self;
+ }
+@@ -203,7 +203,7 @@
+ str = ossl_buf2str(buf, strlen(buf));
+ break;
+ default:
+- ossl_raise(rb_eArgError, "illegal radix %d", base);
++ ossl_raise(rb_eArgError, "invalid radix %d", base);
+ }
+
+ return str;
+@@ -272,9 +272,9 @@
+ } \
+ return Qfalse; \
+ }
+-BIGNUM_BOOL1(is_zero);
+-BIGNUM_BOOL1(is_one);
+-BIGNUM_BOOL1(is_odd);
++BIGNUM_BOOL1(is_zero)
++BIGNUM_BOOL1(is_one)
++BIGNUM_BOOL1(is_odd)
+
+ #define BIGNUM_1c(func) \
+ /* \
+@@ -298,7 +298,7 @@
+ WrapBN(CLASS_OF(self), obj, result); \
+ return obj; \
+ }
+-BIGNUM_1c(sqr);
++BIGNUM_1c(sqr)
+
+ #define BIGNUM_2(func) \
+ /* \
+@@ -322,8 +322,8 @@
+ WrapBN(CLASS_OF(self), obj, result); \
+ return obj; \
+ }
+-BIGNUM_2(add);
+-BIGNUM_2(sub);
++BIGNUM_2(add)
++BIGNUM_2(sub)
+
+ #define BIGNUM_2c(func) \
+ /* \
+@@ -347,12 +347,12 @@
+ WrapBN(CLASS_OF(self), obj, result); \
+ return obj; \
+ }
+-BIGNUM_2c(mul);
+-BIGNUM_2c(mod);
+-BIGNUM_2c(exp);
+-BIGNUM_2c(gcd);
+-BIGNUM_2c(mod_sqr);
+-BIGNUM_2c(mod_inverse);
++BIGNUM_2c(mul)
++BIGNUM_2c(mod)
++BIGNUM_2c(exp)
++BIGNUM_2c(gcd)
++BIGNUM_2c(mod_sqr)
++BIGNUM_2c(mod_inverse)
+
+ /*
+ * call-seq:
+@@ -407,10 +407,10 @@
+ WrapBN(CLASS_OF(self), obj, result); \
+ return obj; \
+ }
+-BIGNUM_3c(mod_add);
+-BIGNUM_3c(mod_sub);
+-BIGNUM_3c(mod_mul);
+-BIGNUM_3c(mod_exp);
++BIGNUM_3c(mod_add)
++BIGNUM_3c(mod_sub)
++BIGNUM_3c(mod_mul)
++BIGNUM_3c(mod_exp)
+
+ #define BIGNUM_BIT(func) \
+ /* \
+@@ -428,9 +428,9 @@
+ } \
+ return self; \
+ }
+-BIGNUM_BIT(set_bit);
+-BIGNUM_BIT(clear_bit);
+-BIGNUM_BIT(mask_bits);
++BIGNUM_BIT(set_bit)
++BIGNUM_BIT(clear_bit)
++BIGNUM_BIT(mask_bits)
+
+ /*
+ * call-seq:
+@@ -474,8 +474,8 @@
+ WrapBN(CLASS_OF(self), obj, result); \
+ return obj; \
+ }
+-BIGNUM_SHIFT(lshift);
+-BIGNUM_SHIFT(rshift);
++BIGNUM_SHIFT(lshift)
++BIGNUM_SHIFT(rshift)
+
+ #define BIGNUM_SELF_SHIFT(func) \
+ /* \
+@@ -494,8 +494,8 @@
+ ossl_raise(eBNError, NULL); \
+ return self; \
+ }
+-BIGNUM_SELF_SHIFT(lshift);
+-BIGNUM_SELF_SHIFT(rshift);
++BIGNUM_SELF_SHIFT(lshift)
++BIGNUM_SELF_SHIFT(rshift)
+
+ #define BIGNUM_RAND(func) \
+ /* \
+@@ -528,8 +528,8 @@
+ WrapBN(klass, obj, result); \
+ return obj; \
+ }
+-BIGNUM_RAND(rand);
+-BIGNUM_RAND(pseudo_rand);
++BIGNUM_RAND(rand)
++BIGNUM_RAND(pseudo_rand)
+
+ #define BIGNUM_RAND_RANGE(func) \
+ /* \
+@@ -552,8 +552,8 @@
+ WrapBN(klass, obj, result); \
+ return obj; \
+ }
+-BIGNUM_RAND_RANGE(rand);
+-BIGNUM_RAND_RANGE(pseudo_rand);
++BIGNUM_RAND_RANGE(rand)
++BIGNUM_RAND_RANGE(pseudo_rand)
+
+ /*
+ * call-seq:
+@@ -608,8 +608,8 @@
+ GetBN(self, bn); \
+ return INT2FIX(BN_##func(bn)); \
+ }
+-BIGNUM_NUM(num_bytes);
+-BIGNUM_NUM(num_bits);
++BIGNUM_NUM(num_bytes)
++BIGNUM_NUM(num_bits)
+
+ static VALUE
+ ossl_bn_copy(VALUE self, VALUE other)
+@@ -642,8 +642,8 @@
+ GetBN(self, bn1); \
+ return INT2FIX(BN_##func(bn1, bn2)); \
+ }
+-BIGNUM_CMP(cmp);
+-BIGNUM_CMP(ucmp);
++BIGNUM_CMP(cmp)
++BIGNUM_CMP(ucmp)
+
+ static VALUE
+ ossl_bn_eql(VALUE self, VALUE other)
+diff -Naur source.old/ext/openssl/ossl_bn.h source/ext/openssl/ossl_bn.h
+--- source.old/ext/openssl/ossl_bn.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bn.h 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bn.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl.c source/ext/openssl/ossl.c
+--- source.old/ext/openssl/ossl.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl.c 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -272,10 +272,9 @@
+ /*
+ * Errors
+ */
+-void
+-ossl_raise(VALUE exc, const char *fmt, ...)
++static VALUE
++ossl_make_error(VALUE exc, const char *fmt, va_list args)
+ {
+- va_list args;
+ char buf[BUFSIZ];
+ const char *msg;
+ long e;
+@@ -287,17 +286,14 @@
+ e = ERR_peek_error();
+ #endif
+ if (fmt) {
+- va_start(args, fmt);
+ len = vsnprintf(buf, BUFSIZ, fmt, args);
+- va_end(args);
+ }
+ if (len < BUFSIZ && e) {
+ if (dOSSL == Qtrue) /* FULL INFO */
+ msg = ERR_error_string(e, NULL);
+ else
+ msg = ERR_reason_error_string(e);
+- fmt = len ? ": %s" : "%s";
+- len += snprintf(buf+len, BUFSIZ-len, fmt, msg);
++ len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
+ }
+ if (dOSSL == Qtrue){ /* show all errors on the stack */
+ while ((e = ERR_get_error()) != 0){
+@@ -307,7 +303,29 @@
+ ERR_clear_error();
+
+ if(len > BUFSIZ) len = strlen(buf);
+- rb_exc_raise(rb_exc_new(exc, buf, len));
++ return rb_exc_new(exc, buf, len);
++}
++
++void
++ossl_raise(VALUE exc, const char *fmt, ...)
++{
++ va_list args;
++ VALUE err;
++ va_start(args, fmt);
++ err = ossl_make_error(exc, fmt, args);
++ va_end(args);
++ rb_exc_raise(err);
++}
++
++VALUE
++ossl_exc_new(VALUE exc, const char *fmt, ...)
++{
++ va_list args;
++ VALUE err;
++ va_start(args, fmt);
++ err = ossl_make_error(exc, fmt, args);
++ va_end(args);
++ return err;
+ }
+
+ /*
+diff -Naur source.old/ext/openssl/ossl_cipher.c source/ext/openssl/ossl_cipher.c
+--- source.old/ext/openssl/ossl_cipher.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_cipher.c 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_cipher.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -67,7 +67,7 @@
+ {
+ if (ctx) {
+ EVP_CIPHER_CTX_cleanup(ctx);
+- free(ctx);
++ ruby_xfree(ctx);
+ }
+ }
+
+@@ -124,12 +124,14 @@
+ return self;
+ }
+
++#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED
+ static void*
+ add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)
+ {
+ rb_ary_push(ary, rb_str_new2(name->name));
+ return NULL;
+ }
++#endif
+
+ /*
+ * call-seq:
+@@ -186,7 +188,7 @@
+ * We deprecated the arguments for this method, but we decided
+ * keeping this behaviour for backward compatibility.
+ */
+- const char *cname = rb_class2name(rb_obj_class(self));
++ char *cname = rb_class2name(rb_obj_class(self));
+ rb_warn("argumtents for %s#encrypt and %s#decrypt were deprecated; "
+ "use %s#pkcs5_keyivgen to derive key and IV",
+ cname, cname, cname);
+@@ -307,7 +309,7 @@
+ static VALUE
+ ossl_cipher_update_deprecated(VALUE self, VALUE data)
+ {
+- const char *cname;
++ char *cname;
+
+ cname = rb_class2name(rb_obj_class(self));
+ rb_warning("%s#<< is deprecated; use %s#update instead", cname, cname);
+diff -Naur source.old/ext/openssl/ossl_cipher.h source/ext/openssl/ossl_cipher.h
+--- source.old/ext/openssl/ossl_cipher.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_cipher.h 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_cipher.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_config.c source/ext/openssl/ossl_config.c
+--- source.old/ext/openssl/ossl_config.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_config.c 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_config.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -158,14 +158,6 @@
+ return self;
+ }
+
+-static void
+-rb_ossl_config_modify_check(VALUE config)
+-{
+- if (OBJ_FROZEN(config)) rb_error_frozen("OpenSSL::Config");
+- if (!OBJ_TAINTED(config) && rb_safe_level() >= 4)
+- rb_raise(rb_eSecurityError, "Insecure: can't modify OpenSSL config");
+-}
+-
+ static VALUE
+ ossl_config_add_value(VALUE self, VALUE section, VALUE name, VALUE value)
+ {
+@@ -175,7 +167,6 @@
+ CONF *conf;
+ CONF_VALUE *sv, *cv;
+
+- rb_ossl_config_modify_check(self);
+ StringValue(section);
+ StringValue(name);
+ StringValue(value);
+@@ -201,6 +192,25 @@
+ #endif
+ }
+
++static void
++rb_ossl_config_modify_check(VALUE config)
++{
++ if (OBJ_FROZEN(config)) rb_error_frozen("OpenSSL::Config");
++ if (!OBJ_TAINTED(config) && rb_safe_level() >= 4)
++ rb_raise(rb_eSecurityError, "Insecure: can't modify OpenSSL config");
++}
++
++static VALUE
++ossl_config_add_value_m(VALUE self, VALUE section, VALUE name, VALUE value)
++{
++#if defined(OSSL_NO_CONF_API)
++ rb_notimplement();
++#else
++ rb_ossl_config_modify_check(self);
++ return ossl_config_add_value(self, section, name, value);
++#endif
++}
++
+ static VALUE
+ ossl_config_get_value(VALUE self, VALUE section, VALUE name)
+ {
+@@ -303,6 +313,12 @@
+ }
+
+ #ifdef IMPLEMENT_LHASH_DOALL_ARG_FN
++#define IMPLEMENT_LHASH_DOALL_ARG_FN_098(f_name,o_type,a_type) \
++ void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
++ o_type a = (o_type)arg1; \
++ a_type b = (a_type)arg2; \
++ f_name(a,b); }
++
+ static void
+ get_conf_section(CONF_VALUE *cv, VALUE ary)
+ {
+@@ -310,7 +326,7 @@
+ rb_ary_push(ary, rb_str_new2(cv->section));
+ }
+
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE*, VALUE);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(get_conf_section, CONF_VALUE*, VALUE)
+
+ static VALUE
+ ossl_config_get_sections(VALUE self)
+@@ -348,7 +364,7 @@
+ rb_str_cat2(str, "\n");
+ }
+
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE*, VALUE);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(dump_conf_value, CONF_VALUE*, VALUE)
+
+ static VALUE
+ dump_conf(CONF *conf)
+@@ -392,13 +408,15 @@
+ }
+ }
+
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE*, void*);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(each_conf_value, CONF_VALUE*, void*)
+
+ static VALUE
+ ossl_config_each(VALUE self)
+ {
+ CONF *conf;
+
++ RETURN_ENUMERATOR(self, 0, 0);
++
+ GetConfig(self, conf);
+ lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(each_conf_value), (void*)NULL);
+
+@@ -448,11 +466,14 @@
+ void
+ Init_ossl_config()
+ {
++ char *default_config_file;
+ eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError);
+ cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject);
+
++ default_config_file = CONF_get1_default_config_file();
+ rb_define_const(cConfig, "DEFAULT_CONFIG_FILE",
+- rb_str_new2(CONF_get1_default_config_file()));
++ rb_str_new2(default_config_file));
++ OPENSSL_free(default_config_file);
+ rb_include_module(cConfig, rb_mEnumerable);
+ rb_define_singleton_method(cConfig, "parse", ossl_config_s_parse, 1);
+ rb_define_alias(CLASS_OF(cConfig), "load", "new");
+@@ -461,7 +482,7 @@
+ rb_define_method(cConfig, "initialize", ossl_config_initialize, -1);
+ rb_define_method(cConfig, "get_value", ossl_config_get_value, 2);
+ rb_define_method(cConfig, "value", ossl_config_get_value_old, -1);
+- rb_define_method(cConfig, "add_value", ossl_config_add_value, 3);
++ rb_define_method(cConfig, "add_value", ossl_config_add_value_m, 3);
+ rb_define_method(cConfig, "[]", ossl_config_get_section, 1);
+ rb_define_method(cConfig, "section", ossl_config_get_section_old, 1);
+ rb_define_method(cConfig, "[]=", ossl_config_set_section, 2);
+diff -Naur source.old/ext/openssl/ossl_config.h source/ext/openssl/ossl_config.h
+--- source.old/ext/openssl/ossl_config.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_config.h 2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_config.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_digest.c source/ext/openssl/ossl_digest.c
+--- source.old/ext/openssl/ossl_digest.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_digest.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_digest.c 15600 2008-02-25 08:48:57Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_digest.h source/ext/openssl/ossl_digest.h
+--- source.old/ext/openssl/ossl_digest.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_digest.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_digest.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_engine.c source/ext/openssl/ossl_engine.c
+--- source.old/ext/openssl/ossl_engine.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_engine.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_engine.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
+ * All rights reserved.
+@@ -61,16 +61,34 @@
+ }
+ StringValue(name);
+ #ifndef OPENSSL_NO_STATIC_ENGINE
++#if HAVE_ENGINE_LOAD_DYNAMIC
+ OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
++#endif
++#if HAVE_ENGINE_LOAD_CSWIFT
+ OSSL_ENGINE_LOAD_IF_MATCH(cswift);
++#endif
++#if HAVE_ENGINE_LOAD_CHIL
+ OSSL_ENGINE_LOAD_IF_MATCH(chil);
++#endif
++#if HAVE_ENGINE_LOAD_ATALLA
+ OSSL_ENGINE_LOAD_IF_MATCH(atalla);
++#endif
++#if HAVE_ENGINE_LOAD_NURON
+ OSSL_ENGINE_LOAD_IF_MATCH(nuron);
++#endif
++#if HAVE_ENGINE_LOAD_UBSEC
+ OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
++#endif
++#if HAVE_ENGINE_LOAD_AEP
+ OSSL_ENGINE_LOAD_IF_MATCH(aep);
++#endif
++#if HAVE_ENGINE_LOAD_SUREWARE
+ OSSL_ENGINE_LOAD_IF_MATCH(sureware);
++#endif
++#if HAVE_ENGINE_LOAD_4758CCA
+ OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
+ #endif
++#endif
+ #ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
+ OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
+ #endif
+@@ -119,7 +137,7 @@
+ if(!ENGINE_init(e))
+ ossl_raise(eEngineError, NULL);
+ ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,
+- 0, NULL, (void(*)())ossl_pem_passwd_cb);
++ 0, NULL, (void(*)(void))ossl_pem_passwd_cb);
+ ERR_clear_error();
+
+ return obj;
+diff -Naur source.old/ext/openssl/ossl_engine.h source/ext/openssl/ossl_engine.h
+--- source.old/ext/openssl/ossl_engine.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_engine.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_engine.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
+diff -Naur source.old/ext/openssl/ossl.h source/ext/openssl/ossl.h
+--- source.old/ext/openssl/ossl.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl.h 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -111,10 +111,7 @@
+ * Compatibility
+ */
+ #if OPENSSL_VERSION_NUMBER >= 0x10000000L
+-#define OSSL_MORE_CONST const
+ #define STACK _STACK
+-#else
+-#define OSSL_MORE_CONST
+ #endif
+
+ /*
+@@ -149,6 +146,7 @@
+ */
+ #define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error())
+ NORETURN(void ossl_raise(VALUE, const char *, ...));
++VALUE ossl_exc_new(VALUE, const char *, ...);
+
+ /*
+ * Verify callback
+@@ -177,10 +175,10 @@
+ extern VALUE dOSSL;
+
+ #if defined(HAVE_VA_ARGS_MACRO)
+-#define OSSL_Debug(fmt, ...) do { \
++#define OSSL_Debug(...) do { \
+ if (dOSSL == Qtrue) { \
+ fprintf(stderr, "OSSL_DEBUG: "); \
+- fprintf(stderr, fmt, ##__VA_ARGS__); \
++ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \
+ } \
+ } while (0)
+diff -Naur source.old/ext/openssl/ossl_hmac.c source/ext/openssl/ossl_hmac.c
+--- source.old/ext/openssl/ossl_hmac.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_hmac.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_hmac.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -42,7 +42,7 @@
+ ossl_hmac_free(HMAC_CTX *ctx)
+ {
+ HMAC_CTX_cleanup(ctx);
+- free(ctx);
++ ruby_xfree(ctx);
+ }
+
+ static VALUE
+diff -Naur source.old/ext/openssl/ossl_hmac.h source/ext/openssl/ossl_hmac.h
+--- source.old/ext/openssl/ossl_hmac.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_hmac.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_hmac.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ns_spki.c source/ext/openssl/ossl_ns_spki.c
+--- source.old/ext/openssl/ossl_ns_spki.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ns_spki.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ns_spki.c 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ns_spki.h source/ext/openssl/ossl_ns_spki.h
+--- source.old/ext/openssl/ossl_ns_spki.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ns_spki.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ns_spki.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ocsp.c source/ext/openssl/ossl_ocsp.c
+--- source.old/ext/openssl/ossl_ocsp.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ocsp.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ocsp.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
+@@ -378,7 +378,7 @@
+ ossl_raise(eOCSPError, NULL);
+ str = rb_str_new(0, len);
+ p = RSTRING_PTR(str);
+- if(i2d_OCSP_RESPONSE(res, NULL) <= 0)
++ if(i2d_OCSP_RESPONSE(res, &p) <= 0)
+ ossl_raise(eOCSPError, NULL);
+ ossl_str_adjust(str, p);
+
+diff -Naur source.old/ext/openssl/ossl_ocsp.h source/ext/openssl/ossl_ocsp.h
+--- source.old/ext/openssl/ossl_ocsp.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ocsp.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ocsp.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
+diff -Naur source.old/ext/openssl/ossl_pkcs12.c source/ext/openssl/ossl_pkcs12.c
+--- source.old/ext/openssl/ossl_pkcs12.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs12.c 2010-08-06 12:43:44.834275985 +0200
+@@ -1,7 +1,7 @@
+ /*
+ * This program is licenced under the same licence as Ruby.
+ * (See the file 'LICENCE'.)
+- * $Id$
++ * $Id: ossl_pkcs12.c 12496 2007-06-08 15:02:04Z technorama $
+ */
+ #include "ossl.h"
+
+diff -Naur source.old/ext/openssl/ossl_pkcs12.h source/ext/openssl/ossl_pkcs12.h
+--- source.old/ext/openssl/ossl_pkcs12.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs12.h 2010-08-06 12:43:44.834275985 +0200
+@@ -1,7 +1,7 @@
+ /*
+ * This program is licenced under the same licence as Ruby.
+ * (See the file 'LICENCE'.)
+- * $Id$
++ * $Id: ossl_pkcs12.h 12496 2007-06-08 15:02:04Z technorama $
+ */
+ #if !defined(_OSSL_PKCS12_H_)
+ #define _OSSL_PKCS12_H_
+diff -Naur source.old/ext/openssl/ossl_pkcs5.c source/ext/openssl/ossl_pkcs5.c
+--- source.old/ext/openssl/ossl_pkcs5.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs5.c 2010-08-06 12:43:44.834275985 +0200
+@@ -29,14 +29,17 @@
+ VALUE str;
+ const EVP_MD *md;
+ int len = NUM2INT(keylen);
++ unsigned char* salt_p;
++ unsigned char* str_p;
+
+ StringValue(pass);
+ StringValue(salt);
+ md = GetDigestPtr(digest);
+-
+ str = rb_str_new(0, len);
++ salt_p = (unsigned char*)RSTRING_PTR(salt);
++ str_p = (unsigned char*)RSTRING_PTR(str);
+
+- if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), md, len, RSTRING_PTR(str)) != 1)
++ if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass), salt_p, RSTRING_LEN(salt), NUM2INT(iter), md, len, str_p) != 1)
+ ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
+
+ return str;
+diff -Naur source.old/ext/openssl/ossl_pkcs7.c source/ext/openssl/ossl_pkcs7.c
+--- source.old/ext/openssl/ossl_pkcs7.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs7.c 2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkcs7.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkcs7.h source/ext/openssl/ossl_pkcs7.h
+--- source.old/ext/openssl/ossl_pkcs7.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs7.h 2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkcs7.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkey.c source/ext/openssl/ossl_pkey.c
+--- source.old/ext/openssl/ossl_pkey.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey.c 2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -177,7 +177,7 @@
+ str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
+ if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))
+ ossl_raise(ePKeyError, NULL);
+- assert(buf_len <= RSTRING_LEN(str));
++ assert((long)buf_len <= RSTRING_LEN(str));
+ rb_str_set_len(str, buf_len);
+
+ return str;
+diff -Naur source.old/ext/openssl/ossl_pkey_dh.c source/ext/openssl/ossl_pkey_dh.c
+--- source.old/ext/openssl/ossl_pkey_dh.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_dh.c 2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_dh.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -415,10 +415,10 @@
+ return str;
+ }
+
+-OSSL_PKEY_BN(dh, p);
+-OSSL_PKEY_BN(dh, g);
+-OSSL_PKEY_BN(dh, pub_key);
+-OSSL_PKEY_BN(dh, priv_key);
++OSSL_PKEY_BN(dh, p)
++OSSL_PKEY_BN(dh, g)
++OSSL_PKEY_BN(dh, pub_key)
++OSSL_PKEY_BN(dh, priv_key)
+
+ /*
+ * -----BEGIN DH PARAMETERS-----
+diff -Naur source.old/ext/openssl/ossl_pkey_dsa.c source/ext/openssl/ossl_pkey_dsa.c
+--- source.old/ext/openssl/ossl_pkey_dsa.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_dsa.c 2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_dsa.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -432,11 +432,11 @@
+ return Qfalse;
+ }
+
+-OSSL_PKEY_BN(dsa, p);
+-OSSL_PKEY_BN(dsa, q);
+-OSSL_PKEY_BN(dsa, g);
+-OSSL_PKEY_BN(dsa, pub_key);
+-OSSL_PKEY_BN(dsa, priv_key);
++OSSL_PKEY_BN(dsa, p)
++OSSL_PKEY_BN(dsa, q)
++OSSL_PKEY_BN(dsa, g)
++OSSL_PKEY_BN(dsa, pub_key)
++OSSL_PKEY_BN(dsa, priv_key)
+
+ /*
+ * INIT
+diff -Naur source.old/ext/openssl/ossl_pkey_ec.c source/ext/openssl/ossl_pkey_ec.c
+--- source.old/ext/openssl/ossl_pkey_ec.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_ec.c 2010-08-06 12:43:44.838276125 +0200
+@@ -463,8 +463,10 @@
+ BIO *out;
+ int i = -1;
+ int private = 0;
++#if 0 /* unused now */
+ EVP_CIPHER *cipher = NULL;
+ char *password = NULL;
++#endif
+ VALUE str;
+
+ Require_EC_KEY(self, ec);
+@@ -484,13 +486,18 @@
+ switch(format) {
+ case EXPORT_PEM:
+ if (private) {
++#if 0 /* unused now */
+ if (cipher || password)
+ /* BUG: finish cipher/password key export */
+ rb_notimplement();
+ i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
++#endif
++ i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
+ } else {
++#if 0 /* unused now */
+ if (cipher || password)
+ rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+
+ i = PEM_write_bio_EC_PUBKEY(out, ec);
+ }
+@@ -498,13 +505,17 @@
+ break;
+ case EXPORT_DER:
+ if (private) {
++#if 0 /* unused now */
+ if (cipher || password)
+ rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+
+ i = i2d_ECPrivateKey_bio(out, ec);
+ } else {
++#if 0 /* unused now */
+ if (cipher || password)
+ rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+
+ i = i2d_EC_PUBKEY_bio(out, ec);
+ }
+@@ -670,7 +681,7 @@
+
+ /*
+ * call-seq:
+- * key.dsa_verify(data, sig) => true or false
++ * key.dsa_verify_asn1(data, sig) => true or false
+ *
+ * See the OpenSSL documentation for ECDSA_verify()
+ */
+@@ -695,7 +706,7 @@
+ {
+ if (!ec_group->dont_free && ec_group->group)
+ EC_GROUP_clear_free(ec_group->group);
+- free(ec_group);
++ ruby_xfree(ec_group);
+ }
+
+ static VALUE ossl_ec_group_alloc(VALUE klass)
+@@ -1201,7 +1212,7 @@
+ {
+ if (!ec_point->dont_free && ec_point->point)
+ EC_POINT_clear_free(ec_point->point);
+- free(ec_point);
++ ruby_xfree(ec_point);
+ }
+
+ static VALUE ossl_ec_point_alloc(VALUE klass)
+diff -Naur source.old/ext/openssl/ossl_pkey.h source/ext/openssl/ossl_pkey.h
+--- source.old/ext/openssl/ossl_pkey.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey.h 2010-08-06 12:43:44.842276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkey_rsa.c source/ext/openssl/ossl_pkey_rsa.c
+--- source.old/ext/openssl/ossl_pkey_rsa.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_rsa.c 2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_rsa.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -519,14 +519,14 @@
+ }
+ */
+
+-OSSL_PKEY_BN(rsa, n);
+-OSSL_PKEY_BN(rsa, e);
+-OSSL_PKEY_BN(rsa, d);
+-OSSL_PKEY_BN(rsa, p);
+-OSSL_PKEY_BN(rsa, q);
+-OSSL_PKEY_BN(rsa, dmp1);
+-OSSL_PKEY_BN(rsa, dmq1);
+-OSSL_PKEY_BN(rsa, iqmp);
++OSSL_PKEY_BN(rsa, n)
++OSSL_PKEY_BN(rsa, e)
++OSSL_PKEY_BN(rsa, d)
++OSSL_PKEY_BN(rsa, p)
++OSSL_PKEY_BN(rsa, q)
++OSSL_PKEY_BN(rsa, dmp1)
++OSSL_PKEY_BN(rsa, dmq1)
++OSSL_PKEY_BN(rsa, iqmp)
+
+ /*
+ * INIT
+diff -Naur source.old/ext/openssl/ossl_rand.c source/ext/openssl/ossl_rand.c
+--- source.old/ext/openssl/ossl_rand.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_rand.c 2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_rand.c 16692 2008-05-29 18:15:50Z knu $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_rand.h source/ext/openssl/ossl_rand.h
+--- source.old/ext/openssl/ossl_rand.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_rand.h 2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_rand.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ssl.c source/ext/openssl/ossl_ssl.c
+--- source.old/ext/openssl/ossl_ssl.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl.c 2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ssl.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org>
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+@@ -95,7 +95,7 @@
+ */
+ struct {
+ const char *name;
+- OSSL_MORE_CONST SSL_METHOD *(*func)(void);
++ SSL_METHOD *(*func)(void);
+ } ossl_ssl_method_tab[] = {
+ #define OSSL_SSL_METHOD_ENTRY(name) { #name, name##_method }
+ OSSL_SSL_METHOD_ENTRY(TLSv1),
+@@ -144,7 +144,7 @@
+ static VALUE
+ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
+ {
+- OSSL_MORE_CONST SSL_METHOD *method = NULL;
++ SSL_METHOD *method = NULL;
+ const char *s;
+ int i;
+
+@@ -585,7 +585,7 @@
+ }
+
+ static VALUE
+-ossl_ssl_cipher_to_ary(OSSL_MORE_CONST SSL_CIPHER *cipher)
++ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
+ {
+ VALUE ary;
+ int bits, alg_bits;
+@@ -829,7 +829,7 @@
+ rb_raise(rb_eArgError, "arg must be Time or nil");
+ }
+
+- SSL_CTX_flush_sessions(ctx, tm);
++ SSL_CTX_flush_sessions(ctx, (long)tm);
+
+ return self;
+ }
+@@ -1199,7 +1199,7 @@
+ num = sk_X509_num(chain);
+ ary = rb_ary_new2(num);
+ for (i = 0; i < num; i++){
+- cert = (X509*)sk_X509_value(chain, i);
++ cert = sk_X509_value(chain, i);
+ rb_ary_push(ary, ossl_x509_new(cert));
+ }
+
+@@ -1214,7 +1214,7 @@
+ ossl_ssl_get_cipher(VALUE self)
+ {
+ SSL *ssl;
+- OSSL_MORE_CONST SSL_CIPHER *cipher;
++ SSL_CIPHER *cipher;
+
+ Data_Get_Struct(self, SSL, ssl);
+ if (!ssl) {
+diff -Naur source.old/ext/openssl/ossl_ssl.h source/ext/openssl/ossl_ssl.h
+--- source.old/ext/openssl/ossl_ssl.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl.h 2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ssl.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ssl_session.c source/ext/openssl/ossl_ssl_session.c
+--- source.old/ext/openssl/ossl_ssl_session.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl_session.c 2010-08-06 12:43:44.846276474 +0200
+@@ -86,9 +86,18 @@
+ GetSSLSession(val1, ctx1);
+ SafeGetSSLSession(val2, ctx2);
+
+- switch (SSL_SESSION_cmp(ctx1, ctx2)) {
+- case 0: return Qtrue;
+- default: return Qfalse;
++ /*
++ * OpenSSL 1.0.0betas do not have non-static SSL_SESSION_cmp.
++ * ssl_session_cmp (was SSL_SESSION_cmp in 0.9.8) is for lhash
++ * comparing so we should not depend on it. Just compare sessions
++ * by version and id.
++ */
++ if ((ctx1->ssl_version == ctx2->ssl_version) &&
++ (ctx1->session_id_length == ctx2->session_id_length) &&
++ (memcmp(ctx1->session_id, ctx2->session_id, ctx1->session_id_length) == 0)) {
++ return Qtrue;
++ } else {
++ return Qfalse;
+ }
+ }
+
+@@ -100,7 +109,7 @@
+ static VALUE ossl_ssl_session_get_time(VALUE self)
+ {
+ SSL_SESSION *ctx;
+- time_t t;
++ long t;
+
+ GetSSLSession(self, ctx);
+
+@@ -122,20 +131,20 @@
+ static VALUE ossl_ssl_session_get_timeout(VALUE self)
+ {
+ SSL_SESSION *ctx;
+- time_t t;
++ long t;
+
+ GetSSLSession(self, ctx);
+
+ t = SSL_SESSION_get_timeout(ctx);
+
+- return ULONG2NUM(t);
++ return LONG2NUM(t);
+ }
+
+ #define SSLSESSION_SET_TIME(func) \
+ static VALUE ossl_ssl_session_set_##func(VALUE self, VALUE time_v) \
+ { \
+ SSL_SESSION *ctx; \
+- time_t t; \
++ long t; \
+ \
+ GetSSLSession(self, ctx); \
+ \
+@@ -147,7 +156,7 @@
+ rb_raise(rb_eArgError, "unknown type"); \
+ } \
+ \
+- t = NUM2ULONG(time_v); \
++ t = NUM2LONG(time_v); \
+ \
+ SSL_SESSION_set_##func(ctx, t); \
+ \
+diff -Naur source.old/ext/openssl/ossl_version.h source/ext/openssl/ossl_version.h
+--- source.old/ext/openssl/ossl_version.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_version.h 2010-08-06 12:43:44.850276055 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_version.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509attr.c source/ext/openssl/ossl_x509attr.c
+--- source.old/ext/openssl/ossl_x509attr.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509attr.c 2010-08-06 12:43:44.850276055 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509attr.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -93,7 +93,7 @@
+ {
+ VALUE oid, value;
+ X509_ATTRIBUTE *attr;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+
+ GetX509Attr(self, attr);
+ if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
+diff -Naur source.old/ext/openssl/ossl_x509.c source/ext/openssl/ossl_x509.c
+--- source.old/ext/openssl/ossl_x509.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509.c 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509cert.c source/ext/openssl/ossl_x509cert.c
+--- source.old/ext/openssl/ossl_x509cert.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509cert.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509cert.c 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509crl.c source/ext/openssl/ossl_x509crl.c
+--- source.old/ext/openssl/ossl_x509crl.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509crl.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509crl.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -262,7 +262,7 @@
+ VALUE ary, revoked;
+
+ GetX509CRL(self, crl);
+- num = sk_X509_CRL_num(X509_CRL_get_REVOKED(crl));
++ num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
+ if (num < 0) {
+ OSSL_Debug("num < 0???");
+ return rb_ary_new();
+@@ -270,7 +270,7 @@
+ ary = rb_ary_new2(num);
+ for(i=0; i<num; i++) {
+ /* NO DUP - don't free! */
+- rev = (X509_REVOKED *)sk_X509_CRL_value(X509_CRL_get_REVOKED(crl), i);
++ rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
+ revoked = ossl_x509revoked_new(rev);
+ rb_ary_push(ary, revoked);
+ }
+diff -Naur source.old/ext/openssl/ossl_x509ext.c source/ext/openssl/ossl_x509ext.c
+--- source.old/ext/openssl/ossl_x509ext.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509ext.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509ext.c 28004 2010-05-24 23:58:49Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -198,6 +198,7 @@
+ ossl_x509extfactory_set_subject_req(self, subject_req);
+ if (!NIL_P(crl))
+ ossl_x509extfactory_set_crl(self, crl);
++ rb_iv_set(self, "@config", Qnil);
+
+ return self;
+ }
+@@ -220,7 +221,6 @@
+ #ifdef HAVE_X509V3_EXT_NCONF_NID
+ VALUE rconf;
+ CONF *conf;
+- ID i_config;
+ #else
+ static LHASH *empty_lhash;
+ #endif
+@@ -237,11 +237,7 @@
+ rb_str_append(valstr, value);
+ GetX509ExtFactory(self, ctx);
+ #ifdef HAVE_X509V3_EXT_NCONF_NID
+- i_config = rb_intern("@config");
+- if (rb_ivar_defined(self, i_config))
+- rconf = rb_ivar_get(self, i_config);
+- else
+- rconf = Qnil;
++ rconf = rb_iv_get(self, "@config");
+ conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);
+ ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
+ #else
+@@ -278,7 +274,7 @@
+ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
+ {
+ VALUE oid, value, critical;
+- OSSL_MORE_CONST unsigned char *p;
++ unsigned char *p;
+ X509_EXTENSION *ext;
+
+ GetX509Ext(self, ext);
+@@ -328,14 +324,15 @@
+ ossl_raise(eX509ExtError, "malloc error");
+ memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));
+ if(!(asn1s = ASN1_OCTET_STRING_new())){
+- free(s);
++ OPENSSL_free(s);
+ ossl_raise(eX509ExtError, NULL);
+ }
+ if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LEN(data))){
+- free(s);
++ OPENSSL_free(s);
+ ASN1_OCTET_STRING_free(asn1s);
+ ossl_raise(eX509ExtError, NULL);
+ }
++ OPENSSL_free(s);
+ GetX509Ext(self, ext);
+ X509_EXTENSION_set_data(ext, asn1s);
+
+diff -Naur source.old/ext/openssl/ossl_x509.h source/ext/openssl/ossl_x509.h
+--- source.old/ext/openssl/ossl_x509.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509.h 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509.h 11708 2007-02-12 23:01:19Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509name.c source/ext/openssl/ossl_x509name.c
+--- source.old/ext/openssl/ossl_x509name.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509name.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509name.c 28367 2010-06-21 09:18:59Z shyouhei $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+@@ -137,9 +137,12 @@
+ else{
+ unsigned char *p;
+ VALUE str = ossl_to_der_if_possible(arg);
++ X509_NAME *x;
+ StringValue(str);
+- p = RSTRING_PTR(str);
+- if(!d2i_X509_NAME((X509_NAME**)&DATA_PTR(self), &p, RSTRING_LEN(str))){
++ p = (unsigned char *)RSTRING_PTR(str);
++ x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
++ DATA_PTR(self) = name;
++ if(!x){
+ ossl_raise(eX509NameError, NULL);
+ }
+ }
+@@ -303,6 +306,27 @@
+ return ULONG2NUM(hash);
+ }
+
++#ifdef HAVE_X509_NAME_HASH_OLD
++/*
++ * call-seq:
++ * name.hash_old => integer
++ *
++ * hash_old returns MD5 based hash used in OpenSSL 0.9.X.
++ */
++static VALUE
++ossl_x509name_hash_old(VALUE self)
++{
++ X509_NAME *name;
++ unsigned long hash;
++
++ GetX509Name(self, name);
++
++ hash = X509_NAME_hash_old(name);
++
++ return ULONG2NUM(hash);
++}
++#endif
++
+ /*
+ * call-seq:
+ * name.to_der => string
+@@ -348,6 +372,9 @@
+ rb_define_alias(cX509Name, "<=>", "cmp");
+ rb_define_method(cX509Name, "eql?", ossl_x509name_eql, 1);
+ rb_define_method(cX509Name, "hash", ossl_x509name_hash, 0);
++#ifdef HAVE_X509_NAME_HASH_OLD
++ rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0);
++#endif
+ rb_define_method(cX509Name, "to_der", ossl_x509name_to_der, 0);
+
+ utf8str = INT2NUM(V_ASN1_UTF8STRING);
+diff -Naur source.old/ext/openssl/ossl_x509req.c source/ext/openssl/ossl_x509req.c
+--- source.old/ext/openssl/ossl_x509req.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509req.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509req.c 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509revoked.c source/ext/openssl/ossl_x509revoked.c
+--- source.old/ext/openssl/ossl_x509revoked.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509revoked.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509revoked.c 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509store.c source/ext/openssl/ossl_x509store.c
+--- source.old/ext/openssl/ossl_x509store.c 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509store.c 2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509store.c 16691 2008-05-29 17:45:47Z knu $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
+diff -Naur source.old/ext/openssl/ruby_missing.h source/ext/openssl/ruby_missing.h
+--- source.old/ext/openssl/ruby_missing.h 2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ruby_missing.h 2010-08-06 12:43:44.862276614 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ruby_missing.h 12496 2007-06-08 15:02:04Z technorama $
+ * 'OpenSSL for Ruby' project
+ * Copyright (C) 2001-2003 Michal Rokos <m.rokos@sh.cvut.cz>
+ * All rights reserved.
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch
new file mode 100644
index 0000000..5ae9cba
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch
@@ -0,0 +1,15 @@
+Patch for CVE-2010-0541
+
+Index: httpresponse.rb
+===================================================================
+--- lib/webrick/httpresponse.rb (revision 28759)
++++ lib/webrick/httpresponse.rb (working copy)
+@@ -208,7 +208,7 @@
+ @keep_alive = false
+ self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
+ end
+- @header['content-type'] = "text/html"
++ @header['content-type'] = "text/html; charset=ISO-8859-1"
+
+ if respond_to?(:create_error_page)
+ create_error_page()
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff b/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff
new file mode 100644
index 0000000..9ffb0de
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff
@@ -0,0 +1,1320 @@
+Phusion ship their code with this patch enabled. bug 335569.
+Using this to revert the changes. DON'T REMOVE the NOAPPLY from the name. -a3li
+
+diff --git a/eval.c b/eval.c
+index 77121fe..b6ef5b6 100644
+--- a/eval.c
++++ b/eval.c
+@@ -73,6 +73,7 @@ char *strrchr _((const char*,const char));
+ #endif
+
+ #include <time.h>
++#include <sys/mman.h>
+
+ #if defined(HAVE_FCNTL_H) || defined(_WIN32)
+ #include <fcntl.h>
+@@ -1058,7 +1059,7 @@ static struct tag *prot_tag;
+ _tag.blkid = 0; \
+ prot_tag = &_tag
+
+-#define PROT_NONE Qfalse /* 0 */
++#define PROT_EMPTY Qfalse /* 0 */
+ #define PROT_THREAD Qtrue /* 2 */
+ #define PROT_FUNC INT2FIX(0) /* 1 */
+ #define PROT_LOOP INT2FIX(1) /* 3 */
+@@ -1280,7 +1281,7 @@ error_print()
+
+ if (NIL_P(ruby_errinfo)) return;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ errat = EXEC_TAG() ? Qnil : get_backtrace(ruby_errinfo);
+ if (EXEC_TAG()) goto error;
+ if (NIL_P(errat)){
+@@ -1436,7 +1437,7 @@ ruby_init()
+ /* default visibility is private at toplevel */
+ SCOPE_SET(SCOPE_PRIVATE);
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ rb_call_inits();
+ ruby_class = rb_cObject;
+@@ -1570,7 +1571,7 @@ ruby_options(argc, argv)
+ int state;
+
+ Init_stack((void*)&state);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ ruby_process_options(argc, argv);
+ }
+@@ -1587,7 +1588,7 @@ void rb_exec_end_proc _((void));
+ static void
+ ruby_finalize_0()
+ {
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if (EXEC_TAG() == 0) {
+ rb_trap_exit();
+ }
+@@ -1626,7 +1627,7 @@ ruby_cleanup(exArg)
+ Init_stack((void *)&state);
+ ruby_finalize_0();
+ errs[0] = ruby_errinfo;
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ PUSH_ITER(ITER_NOT);
+ if ((state = EXEC_TAG()) == 0) {
+ rb_thread_cleanup();
+@@ -1677,7 +1678,7 @@ ruby_exec_internal()
+ {
+ int state;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ PUSH_ITER(ITER_NOT);
+ /* default visibility is private at toplevel */
+ SCOPE_SET(SCOPE_PRIVATE);
+@@ -1899,7 +1900,7 @@ rb_eval_cmd(cmd, arg, level)
+ }
+ if (TYPE(cmd) != T_STRING) {
+ PUSH_ITER(ITER_NOT);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ ruby_safe_level = level;
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr);
+@@ -1921,7 +1922,7 @@ rb_eval_cmd(cmd, arg, level)
+
+ ruby_safe_level = level;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ val = (state = EXEC_TAG()) ? Qnil : eval(ruby_top_self, cmd, Qnil, 0, 0);
+ if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
+ scope_dup(saved_scope);
+@@ -2433,7 +2434,7 @@ is_defined(self, node, buf)
+ val = self;
+ if (node->nd_recv == (NODE *)1) goto check_bound;
+ case NODE_CALL:
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_eval(self, node->nd_recv);
+ }
+@@ -2535,7 +2536,7 @@ is_defined(self, node, buf)
+ break;
+
+ case NODE_COLON2:
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_eval(self, node->nd_head);
+ }
+@@ -2584,7 +2585,7 @@ is_defined(self, node, buf)
+ goto again;
+
+ default:
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ rb_eval(self, node);
+ }
+@@ -2789,7 +2790,7 @@ call_trace_func(event, node, self, id, klass)
+ klass = rb_iv_get(klass, "__attached__");
+ }
+ }
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ raised = rb_thread_reset_raised(th);
+ if ((state = EXEC_TAG()) == 0) {
+ srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
+@@ -3231,7 +3232,7 @@ eval_node_volatile(rescue, VALUE)
+ int state;
+ VALUE result;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ retry_entry:
+ result = rb_eval(self, node->nd_head);
+@@ -3286,7 +3287,7 @@ eval_node_volatile(ensure, VALUE)
+ int state;
+ VALUE result;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ result = rb_eval(self, node->nd_head);
+ }
+@@ -3453,7 +3454,7 @@ eval_node_volatile(scope, VALUE)
+ ruby_frame = &frame;
+
+ PUSH_SCOPE();
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if (node->nd_rval) {
+ saved_cref = ruby_cref;
+ ruby_cref = (NODE*)node->nd_rval;
+@@ -4351,7 +4352,7 @@ module_setup(module, n)
+ }
+
+ PUSH_CREF(module);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase,
+ ruby_frame->last_func, ruby_frame->last_class);
+@@ -4758,7 +4759,7 @@ rb_longjmp(tag, mesg)
+ VALUE e = ruby_errinfo;
+ int status;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ StringValue(e);
+ warn_printf("Exception `%s' at %s:%d - %s\n",
+@@ -5136,7 +5137,7 @@ rb_yield_0(val, self, klass, flags, avalue)
+ var = block->var;
+
+ if (var) {
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ NODE *bvar = NULL;
+ block_var:
+@@ -5209,7 +5210,7 @@ rb_yield_0(val, self, klass, flags, avalue)
+ ruby_current_node = node;
+
+ PUSH_ITER(block->iter);
+- PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
++ PUSH_TAG(lambda ? PROT_EMPTY : PROT_YIELD);
+ switch (state = EXEC_TAG()) {
+ case TAG_REDO:
+ state = 0;
+@@ -5614,7 +5615,7 @@ rb_rescue2(b_proc, data1, r_proc, data2, va_alist)
+ VALUE eclass;
+ va_list args;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ switch (state = EXEC_TAG()) {
+ case TAG_RETRY:
+ if (!handle) break;
+@@ -5672,7 +5673,7 @@ rb_protect(proc, data, state)
+ VALUE result;
+ int status;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ cont_protect = (VALUE)rb_node_newnode(NODE_MEMO, cont_protect, 0, 0);
+ if ((status = EXEC_TAG()) == 0) {
+ result = (*proc)(data);
+@@ -5696,7 +5697,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
+ VALUE result;
+ VALUE retval;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ result = (*b_proc)(data1);
+ }
+@@ -5723,7 +5724,7 @@ rb_with_disable_interrupt(proc, data)
+ int thr_critical = rb_thread_critical;
+
+ rb_thread_critical = Qtrue;
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ result = (*proc)(data);
+ }
+@@ -6419,7 +6420,7 @@ rb_funcall_rescue(recv, mid, n, va_alist)
+
+ va_init_list(ar, n);
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ result = vafuncall(recv, mid, n, &ar);
+ }
+@@ -6695,7 +6696,7 @@ eval(self, src, scope, file, line)
+ if (TYPE(ruby_class) == T_ICLASS) {
+ ruby_class = RBASIC(ruby_class)->klass;
+ }
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ NODE *node;
+
+@@ -6863,7 +6864,7 @@ exec_under(func, under, cbase, args)
+
+ mode = scope_vmode;
+ SCOPE_SET(SCOPE_PUBLIC);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ val = (*func)(args);
+ }
+@@ -7174,7 +7175,7 @@ rb_load(fname, wrap)
+ PUSH_SCOPE();
+ /* default visibility is private at loading toplevel */
+ SCOPE_SET(SCOPE_PRIVATE);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ state = EXEC_TAG();
+ last_func = ruby_frame->last_func;
+ last_node = ruby_current_node;
+@@ -7233,7 +7234,7 @@ rb_load_protect(fname, wrap, state)
+ {
+ int status;
+
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ rb_load(fname, wrap);
+ }
+@@ -7554,7 +7555,7 @@ rb_require_safe(fname, safe)
+ saved.node = ruby_current_node;
+ saved.func = ruby_frame->last_func;
+ saved.safe = ruby_safe_level;
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((state = EXEC_TAG()) == 0) {
+ VALUE feature, path;
+ long handle;
+@@ -8263,7 +8264,7 @@ rb_exec_end_proc()
+ tmp_end_procs = link = ephemeral_end_procs;
+ ephemeral_end_procs = 0;
+ while (link) {
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ ruby_safe_level = link->safe;
+ (*link->func)(link->data);
+@@ -8281,7 +8282,7 @@ rb_exec_end_proc()
+ tmp_end_procs = link = end_procs;
+ end_procs = 0;
+ while (link) {
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ if ((status = EXEC_TAG()) == 0) {
+ ruby_safe_level = link->safe;
+ (*link->func)(link->data);
+@@ -9020,7 +9021,7 @@ proc_invoke(proc, args, self, klass)
+ ruby_block = &_block;
+ PUSH_ITER(ITER_CUR);
+ ruby_frame->iter = ITER_CUR;
+- PUSH_TAG(pcall ? PROT_LAMBDA : PROT_NONE);
++ PUSH_TAG(pcall ? PROT_LAMBDA : PROT_EMPTY);
+ state = EXEC_TAG();
+ if (state == 0) {
+ proc_set_safe_level(proc);
+@@ -10464,6 +10465,7 @@ win32_set_exception_list(p)
+ int rb_thread_pending = 0;
+
+ VALUE rb_cThread;
++static unsigned int rb_thread_stack_size;
+
+ extern VALUE rb_last_status;
+
+@@ -10679,33 +10681,33 @@ timeofday()
+ return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
+ }
+
+-extern VALUE *rb_gc_stack_start;
+-#ifdef __ia64
+-extern VALUE *rb_gc_register_stack_start;
+-#endif
+-
+-#define ADJ(addr) \
+- if ((size_t)((void *)addr - stkBase) < stkSize) addr=(void *)addr + stkShift
++#define STACK(addr) (th->stk_pos<(VALUE*)(addr) && (VALUE*)(addr)<th->stk_pos+th->stk_len)
++#define ADJ(addr) (void*)(STACK(addr)?(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr):(VALUE*)(addr))
+ static void
+ thread_mark(th)
+ rb_thread_t th;
+ {
+ struct FRAME *frame;
+ struct BLOCK *block;
+- void *stkBase;
+- ptrdiff_t stkShift;
+- size_t stkSize;
+-
++
+ rb_gc_mark(th->result);
+ rb_gc_mark(th->thread);
+ if (th->join) rb_gc_mark(th->join->thread);
+
+- rb_gc_mark(th->klass);
+- rb_gc_mark(th->wrapper);
+- rb_gc_mark((VALUE)th->cref);
++ if (curr_thread == th) {
++ rb_gc_mark(ruby_class);
++ rb_gc_mark(ruby_wrapper);
++ rb_gc_mark((VALUE)ruby_cref);
++ rb_gc_mark((VALUE)ruby_scope);
++ rb_gc_mark((VALUE)ruby_dyna_vars);
++ } else {
++ rb_gc_mark(th->klass);
++ rb_gc_mark(th->wrapper);
++ rb_gc_mark((VALUE)th->cref);
++ rb_gc_mark((VALUE)th->scope);
++ rb_gc_mark((VALUE)th->dyna_vars);
++ }
+
+- rb_gc_mark((VALUE)th->scope);
+- rb_gc_mark((VALUE)th->dyna_vars);
+ rb_gc_mark(th->errinfo);
+ rb_gc_mark(th->last_status);
+ rb_gc_mark(th->last_line);
+@@ -10715,11 +10717,11 @@ thread_mark(th)
+ rb_gc_mark_maybe(th->sandbox);
+
+ /* mark data in copied stack */
+- if (th == curr_thread) return;
++ if (th == main_thread) return;
+ if (th->status == THREAD_KILLED) return;
+ if (th->stk_len == 0) return; /* stack not active, no need to mark. */
+- if (th->stk_ptr) {
+- rb_gc_mark_locations(th->stk_ptr, th->stk_ptr+th->stk_len);
++ if (th->stk_ptr && th != curr_thread) {
++ rb_gc_mark_locations(th->stk_pos, th->stk_base);
+ #if defined(THINK_C) || defined(__human68k__)
+ rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2);
+ #endif
+@@ -10729,35 +10731,30 @@ thread_mark(th)
+ }
+ #endif
+ }
+-
+- stkBase = (void *)rb_gc_stack_start;
+- stkSize = th->stk_len * sizeof(VALUE);
+-#if STACK_GROW_DIRECTION == 0
+- if ((VALUE *)&th < rb_gc_stack_start)
+-#endif
+-#if STACK_GROW_DIRECTION <= 0
+- stkBase -= stkSize;
+-#endif
+- stkShift = (void *)th->stk_ptr - stkBase;
+-
+- frame = th->frame;
++
++ if (curr_thread == th)
++ frame = ruby_frame;
++ else
++ frame = th->frame;
++
+ while (frame && frame != top_frame) {
+- ADJ(frame);
+ rb_gc_mark_frame(frame);
+ if (frame->tmp) {
+ struct FRAME *tmp = frame->tmp;
+-
+ while (tmp && tmp != top_frame) {
+- ADJ(tmp);
+ rb_gc_mark_frame(tmp);
+ tmp = tmp->prev;
+ }
+ }
+ frame = frame->prev;
+ }
+- block = th->block;
++
++ if (curr_thread == th)
++ block = ruby_block;
++ else
++ block = th->block;
++
+ while (block) {
+- ADJ(block);
+ rb_gc_mark_frame(&block->frame);
+ block = block->prev;
+ }
+@@ -10821,7 +10818,7 @@ stack_free(th)
+ rb_thread_t th;
+ {
+ if (th->stk_ptr) {
+- free(th->stk_ptr);
++ munmap(th->stk_ptr, th->stk_size);
+ th->stk_ptr = 0;
+ }
+ #ifdef __ia64
+@@ -10873,6 +10870,11 @@ static int th_sig, th_safe;
+ #define RESTORE_SIGNAL 6
+ #define RESTORE_EXIT 7
+
++extern VALUE *rb_gc_stack_start;
++#ifdef __ia64
++extern VALUE *rb_gc_register_stack_start;
++#endif
++
+ static void
+ rb_thread_save_context(th)
+ rb_thread_t th;
+@@ -10882,35 +10884,8 @@ rb_thread_save_context(th)
+ static VALUE tval;
+
+ len = ruby_stack_length(&pos);
+- th->stk_len = 0;
+- th->stk_pos = pos;
+- if (len > th->stk_max) {
+- VALUE *ptr = realloc(th->stk_ptr, sizeof(VALUE) * len);
+- if (!ptr) rb_memerror();
+- th->stk_ptr = ptr;
+- th->stk_max = len;
+- }
+ th->stk_len = len;
+- FLUSH_REGISTER_WINDOWS;
+- MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len);
+-#ifdef __ia64
+- th->bstr_pos = rb_gc_register_stack_start;
+- len = (VALUE*)rb_ia64_bsp() - th->bstr_pos;
+- th->bstr_len = 0;
+- if (len > th->bstr_max) {
+- VALUE *ptr = realloc(th->bstr_ptr, sizeof(VALUE) * len);
+- if (!ptr) rb_memerror();
+- th->bstr_ptr = ptr;
+- th->bstr_max = len;
+- }
+- th->bstr_len = len;
+- rb_ia64_flushrs();
+- MEMCPY(th->bstr_ptr, th->bstr_pos, VALUE, th->bstr_len);
+-#endif
+-#ifdef SAVE_WIN32_EXCEPTION_LIST
+- th->win32_exception_list = win32_get_exception_list();
+-#endif
+-
++ th->stk_pos = pos;
+ th->frame = ruby_frame;
+ th->scope = ruby_scope;
+ ruby_scope->flags |= SCOPE_DONT_RECYCLE;
+@@ -11023,11 +10998,6 @@ rb_thread_restore_context_0(rb_thread_t th, int exit)
+ #endif
+ tmp = th;
+ ex = exit;
+- FLUSH_REGISTER_WINDOWS;
+- MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len);
+-#ifdef __ia64
+- MEMCPY(tmp->bstr_pos, tmp->bstr_ptr, VALUE, tmp->bstr_len);
+-#endif
+
+ tval = rb_lastline_get();
+ rb_lastline_set(tmp->last_line);
+@@ -11119,8 +11089,8 @@ rb_thread_restore_context(th, exit)
+ rb_thread_t th;
+ int exit;
+ {
+- if (!th->stk_ptr) rb_bug("unsaved context");
+- stack_extend(th, exit);
++ if (!th->stk_ptr && th != main_thread) rb_bug("unsaved context");
++ rb_thread_restore_context_0(th, exit);
+ }
+
+ static void
+@@ -11139,7 +11109,6 @@ rb_thread_die(th)
+ {
+ th->thgroup = 0;
+ th->status = THREAD_KILLED;
+- stack_free(th);
+ }
+
+ static void
+@@ -12468,8 +12437,10 @@ rb_thread_group(thread)
+ \
+ th->stk_ptr = 0;\
+ th->stk_len = 0;\
++ th->stk_size = 0;\
+ th->stk_max = 0;\
+ th->wait_for = 0;\
++ th->gc_stack_end = (VALUE *) STACK_GROW_DIRECTION;\
+ IA64_INIT(th->bstr_ptr = 0);\
+ IA64_INIT(th->bstr_len = 0);\
+ IA64_INIT(th->bstr_max = 0);\
+@@ -12515,6 +12486,48 @@ rb_thread_alloc(klass)
+ THREAD_ALLOC(th);
+ th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th);
+
++ /* if main_thread != NULL, then this is NOT the main thread, so
++ * we create a heap-stack
++ */
++ if (main_thread) {
++ /* Allocate stack, don't forget to add 1 extra word because of the MATH below */
++ unsigned int pagesize = getpagesize();
++ unsigned int total_size = rb_thread_stack_size + pagesize + sizeof(int);
++ void *stack_area = NULL;
++
++ stack_area = mmap(NULL, total_size, PROT_READ | PROT_WRITE | PROT_EXEC,
++ MAP_PRIVATE | MAP_ANON, -1, 0);
++
++ if (stack_area == MAP_FAILED) {
++ fprintf(stderr, "Thread stack allocation failed!\n");
++ rb_memerror();
++ }
++
++ th->stk_ptr = th->stk_pos = stack_area;
++ th->stk_size = total_size;
++
++ if (mprotect(th->stk_ptr, pagesize, PROT_NONE) == -1) {
++ fprintf(stderr, "Failed to create thread guard region: %s\n", strerror(errno));
++ rb_memerror();
++ }
++
++ th->guard = th->stk_ptr + (pagesize/sizeof(VALUE *));
++
++ /* point stk_base at the top of the stack */
++ /* ASSUMPTIONS:
++ * 1.) The address returned by malloc is "suitably aligned" for anything on this system
++ * 2.) Adding a value that is "aligned" for this platform should not unalign the address
++ * returned from malloc.
++ * 3.) Don't push anything on to the stack, otherwise it'll get unaligned.
++ * 4.) x86_64 ABI says aligned AFTER arguments have been pushed. You *must* then do a call[lq]
++ * or push[lq] something else on to the stack if you inted to do a ret.
++ */
++ th->stk_base = th->stk_ptr + ((total_size - sizeof(int))/sizeof(VALUE *));
++ th->stk_len = rb_thread_stack_size;
++ } else {
++ th->stk_ptr = th->stk_pos = rb_gc_stack_start;
++ }
++
+ for (vars = th->dyna_vars; vars; vars = vars->next) {
+ if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
+ FL_SET(vars, DVAR_DONT_RECYCLE);
+@@ -12681,6 +12694,15 @@ rb_thread_stop_timer()
+ int rb_thread_tick = THREAD_TICK;
+ #endif
+
++struct thread_start_args {
++ VALUE (*fn)();
++ void *arg;
++ rb_thread_t th;
++} new_th;
++
++static VALUE
++rb_thread_start_2();
++
+ #if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
+ #define START_TIMER() (thread_init ? (void)0 : rb_thread_start_timer())
+ #define STOP_TIMER() (rb_thread_stop_timer())
+@@ -12695,11 +12717,7 @@ rb_thread_start_0(fn, arg, th)
+ void *arg;
+ rb_thread_t th;
+ {
+- volatile rb_thread_t th_save = th;
+ volatile VALUE thread = th->thread;
+- struct BLOCK *volatile saved_block = 0;
+- enum rb_thread_status status;
+- int state;
+
+ if (OBJ_FROZEN(curr_thread->thgroup)) {
+ rb_raise(rb_eThreadError,
+@@ -12710,16 +12728,41 @@ rb_thread_start_0(fn, arg, th)
+ return thread;
+ }
+
+- if (ruby_block) { /* should nail down higher blocks */
+- struct BLOCK dummy;
++ new_th.fn = fn;
++ new_th.arg = arg;
++ new_th.th = th;
++
++#if defined(__i386__)
++ __asm__ __volatile__ ("movl %0, %%esp\n\t"
++ "calll *%1\n"
++ :: "r" (th->stk_base),
++ "r" (rb_thread_start_2));
++#elif defined(__x86_64__)
++ __asm__ __volatile__ ("movq %0, %%rsp\n\t"
++ "callq *%1\n"
++ :: "r" (th->stk_base),
++ "r" (rb_thread_start_2));
++#else
++ #error unsupported architecture!
++#endif
++ /* NOTREACHED */
++ return 0;
++}
+
+- dummy.prev = ruby_block;
+- blk_copy_prev(&dummy);
+- saved_block = ruby_block = dummy.prev;
+- }
+- scope_dup(ruby_scope);
++static VALUE
++rb_thread_start_2()
++{
++ volatile rb_thread_t th = new_th.th;
++ volatile rb_thread_t th_save = th;
++ volatile VALUE thread = th->thread;
++ struct BLOCK *volatile saved_block = 0;
++ enum rb_thread_status status;
++ int state;
++ struct tag *tag, *new_tag, *prev_tag;
++ struct RVarmap *vars;
++ struct FRAME dummy_frame;
+
+- if (!th->next) {
++ if (!th->next) {
+ /* merge in thread list */
+ th->prev = curr_thread;
+ curr_thread->next->prev = th;
+@@ -12727,14 +12770,42 @@ rb_thread_start_0(fn, arg, th)
+ curr_thread->next = th;
+ th->priority = curr_thread->priority;
+ th->thgroup = curr_thread->thgroup;
++ }
++ curr_thread = th;
++
++ dummy_frame = *ruby_frame;
++ dummy_frame.prev = top_frame;
++ ruby_frame = &dummy_frame;
++
++ if (ruby_block) { /* should nail down higher blocks */
++ struct BLOCK dummy;
++
++ dummy.prev = ruby_block;
++ blk_copy_prev(&dummy);
++ saved_block = ruby_block = dummy.prev;
+ }
+ START_TIMER();
+
++ scope_dup(ruby_scope);
++ prev_tag = NULL;
++ tag = prot_tag;
++ while (tag) {
++ new_tag = alloca(sizeof(struct tag));
++ memcpy(new_tag, tag, sizeof(struct tag));
++
++ if (prev_tag)
++ prev_tag->prev = new_tag;
++ else
++ prot_tag = new_tag;
++
++ prev_tag = new_tag;
++ tag = tag->prev;
++ }
++
+ PUSH_TAG(PROT_THREAD);
+ if ((state = EXEC_TAG()) == 0) {
+ if (THREAD_SAVE_CONTEXT(th) == 0) {
+- curr_thread = th;
+- th->result = (*fn)(arg, th);
++ th->result = (*new_th.fn)(new_th.arg, th);
+ }
+ th = th_save;
+ }
+@@ -13071,6 +13142,43 @@ rb_thread_cleanup()
+ END_FOREACH_FROM(curr, th);
+ }
+
++/*
++ * call-seq:
++ * Thread.stack_size => fixnum
++ *
++ * Returns the thread stack size in bytes
++ */
++static VALUE
++rb_thread_stacksize_get()
++{
++ return INT2FIX(rb_thread_stack_size);
++}
++
++/*
++ * call-seq:
++ * Thread.stack_size= fixnum => Qnil
++ *
++ * Sets the global thread stacksize and returns Qnil.
++ */
++static VALUE
++rb_thread_stacksize_set(obj, val)
++ VALUE obj;
++ VALUE val;
++{
++
++ unsigned int size = FIX2UINT(val);
++
++ /* 16byte alignment works for both x86 and x86_64 */
++ if (size & (~0xf)) {
++ size += 0x10;
++ size = size & (~0xf);
++ }
++
++ rb_thread_stack_size = size;
++
++ return Qnil;
++}
++
+ int rb_thread_critical;
+
+
+@@ -13919,7 +14027,7 @@ rb_exec_recursive(func, obj, arg)
+ int state;
+
+ hash = recursive_push(hash, objid);
+- PUSH_TAG(PROT_NONE);
++ PUSH_TAG(PROT_EMPTY);
+ result = (state = EXEC_TAG()) ? Qundef : (*func) (obj, arg, Qfalse);
+ POP_TAG();
+ recursive_pop(hash, objid);
+@@ -13944,6 +14052,8 @@ Init_Thread()
+ {
+ VALUE cThGroup;
+
++ rb_thread_stack_size = (1024 * 1024);
++
+ recursive_key = rb_intern("__recursive_key__");
+ rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
+ rb_cThread = rb_define_class("Thread", rb_cObject);
+@@ -13968,6 +14078,9 @@ Init_Thread()
+ rb_define_singleton_method(rb_cThread, "abort_on_exception", rb_thread_s_abort_exc, 0);
+ rb_define_singleton_method(rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1);
+
++ rb_define_singleton_method(rb_cThread, "stack_size", rb_thread_stacksize_get, 0);
++ rb_define_singleton_method(rb_cThread, "stack_size=", rb_thread_stacksize_set, 1);
++
+ rb_define_method(rb_cThread, "run", rb_thread_run, 0);
+ rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0);
+ rb_define_method(rb_cThread, "kill", rb_thread_kill, 0);
+@@ -14006,7 +14119,7 @@ Init_Thread()
+ #ifdef MBARI_API
+ rb_define_method(rb_cCont, "thread", rb_cont_thread, 0);
+ #endif
+- rb_define_global_function("callcc", rb_callcc, 0);
++ /* rb_define_global_function("callcc", rb_callcc, 0); */
+ rb_global_variable(&cont_protect);
+
+ cThGroup = rb_define_class("ThreadGroup", rb_cObject);
+diff --git a/gc.c b/gc.c
+index 80f2c16..4a83543 100644
+--- a/gc.c
++++ b/gc.c
+@@ -68,7 +68,19 @@ int _setjmp(), _longjmp();
+ #endif
+ #define GC_STACK_MAX (GC_LEVEL_MAX+GC_STACK_PAD)
+
+-static VALUE *stack_limit, *gc_stack_limit;
++/* The address of the end of the main thread's application stack. When the
++ * main thread is active, application code may not cause the stack to grow
++ * past this point. Past this point there's still a small area reserved for
++ * garbage collector operations.
++ */
++static VALUE *stack_limit;
++/*
++ * The address of the end of the current thread's GC stack. When running
++ * the GC, the stack may not grow past this point.
++ * The value of this variable is reset every time garbage_collect() is
++ * called.
++ */
++static VALUE *gc_stack_limit;
+
+ static size_t malloc_increase = 0;
+ static size_t malloc_limit = GC_MALLOC_LIMIT;
+@@ -715,8 +727,6 @@ VALUE *rb_gc_stack_start = 0;
+ VALUE *rb_gc_register_stack_start = 0;
+ #endif
+
+-VALUE *rb_gc_stack_end = (VALUE *)STACK_GROW_DIRECTION;
+-
+
+ #ifdef DJGPP
+ /* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */
+@@ -750,12 +760,12 @@ VALUE *__sp(void) {
+ #endif
+
+ #if STACK_GROW_DIRECTION < 0
+-# define STACK_LENGTH (rb_gc_stack_start - STACK_END)
++# define STACK_LENGTH(start) ((start) - STACK_END)
+ #elif STACK_GROW_DIRECTION > 0
+-# define STACK_LENGTH (STACK_END - rb_gc_stack_start + 1)
++# define STACK_LENGTH(start) (STACK_END - (start) + 1)
+ #else
+-# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\
+- : STACK_END - rb_gc_stack_start + 1)
++# define STACK_LENGTH(start) ((STACK_END < (start)) ? (start) - STACK_END\
++ : STACK_END - (start) + 1)
+ #endif
+ #if STACK_GROW_DIRECTION > 0
+ # define STACK_UPPER(a, b) a
+@@ -778,15 +788,31 @@ ruby_stack_length(base)
+ VALUE **base;
+ {
+ SET_STACK_END;
++ VALUE *start;
++ if (rb_curr_thread == rb_main_thread) {
++ start = rb_gc_stack_start;
++ } else {
++ start = rb_curr_thread->stk_base;
++ }
+ if (base) *base = STACK_UPPER(start, STACK_END);
+- return STACK_LENGTH;
++ return STACK_LENGTH(start);
+ }
+
+ int
+ ruby_stack_check()
+ {
+ SET_STACK_END;
+- return __stack_past(stack_limit, STACK_END);
++ if (!rb_main_thread || rb_curr_thread == rb_main_thread) {
++ return __stack_past(stack_limit, STACK_END);
++ } else {
++ /* ruby_stack_check() is only called periodically, but we want to
++ * detect a stack overflow before the thread's guard area is accessed.
++ * So we append a '+ getpagesize()' to the address check.
++ *
++ * TODO: support architectures on which the stack grows upwards.
++ */
++ return __stack_past(rb_curr_thread->guard + getpagesize(), STACK_END);
++ }
+ }
+
+ /*
+@@ -797,22 +823,24 @@ ruby_stack_check()
+ #if STACK_WIPE_METHOD
+ void rb_gc_wipe_stack(void)
+ {
+- VALUE *stack_end = rb_gc_stack_end;
+- VALUE *sp = __sp();
+- rb_gc_stack_end = sp;
++ if (rb_curr_thread) {
++ VALUE *stack_end = rb_curr_thread->gc_stack_end;
++ VALUE *sp = __sp();
++ rb_curr_thread->gc_stack_end = sp;
+ #if STACK_WIPE_METHOD == 1
+ #warning clearing of "ghost references" from the call stack has been disabled
+ #elif STACK_WIPE_METHOD == 2 /* alloca ghost stack before clearing it */
+- if (__stack_past(sp, stack_end)) {
+- size_t bytes = __stack_depth((char *)stack_end, (char *)sp);
+- STACK_UPPER(sp = nativeAllocA(bytes), stack_end = nativeAllocA(bytes));
+- __stack_zero(stack_end, sp);
+- }
++ if (__stack_past(sp, stack_end)) {
++ size_t bytes = __stack_depth((char *)stack_end, (char *)sp);
++ STACK_UPPER(sp = nativeAllocA(bytes), stack_end = nativeAllocA(bytes));
++ __stack_zero(stack_end, sp);
++ }
+ #elif STACK_WIPE_METHOD == 3 /* clear unallocated area past stack pointer */
+- __stack_zero(stack_end, sp); /* will crash if compiler pushes a temp. here */
++ __stack_zero(stack_end, sp); /* will crash if compiler pushes a temp. here */
+ #else
+ #error unsupported method of clearing ghost references from the stack
+ #endif
++ }
+ }
+ #else
+ #warning clearing of "ghost references" from the call stack completely disabled
+@@ -1683,10 +1711,12 @@ garbage_collect_0(VALUE *top_frame)
+ rb_mark_table_prepare();
+ init_mark_stack();
+
+- gc_mark((VALUE)ruby_current_node);
+-
+ /* mark frame stack */
+- for (frame = ruby_frame; frame; frame = frame->prev) {
++ if (rb_curr_thread == rb_main_thread)
++ frame = ruby_frame;
++ else
++ frame = rb_main_thread->frame;
++ for (; frame; frame = frame->prev) {
+ rb_gc_mark_frame(frame);
+ if (frame->tmp) {
+ struct FRAME *tmp = frame->tmp;
+@@ -1696,12 +1726,30 @@ garbage_collect_0(VALUE *top_frame)
+ }
+ }
+ }
+- gc_mark((VALUE)ruby_scope);
+- gc_mark((VALUE)ruby_dyna_vars);
++
++ if (rb_curr_thread == rb_main_thread) {
++ gc_mark((VALUE)ruby_current_node);
++ gc_mark((VALUE)ruby_scope);
++ gc_mark((VALUE)ruby_dyna_vars);
++ } else {
++ gc_mark((VALUE)rb_main_thread->node);
++ gc_mark((VALUE)rb_main_thread->scope);
++ gc_mark((VALUE)rb_main_thread->dyna_vars);
++
++ /* scan the current thread's stack */
++ rb_gc_mark_locations(top_frame, rb_curr_thread->stk_base);
++ }
++
+ if (finalizer_table) {
+ mark_tbl(finalizer_table);
+ }
+
++ /* If this is not the main thread, we need to scan the C stack, so
++ * set top_frame to the end of the C stack.
++ */
++ if (rb_curr_thread != rb_main_thread)
++ top_frame = rb_main_thread->stk_pos;
++
+ #if STACK_GROW_DIRECTION < 0
+ rb_gc_mark_locations(top_frame, rb_gc_stack_start);
+ #elif STACK_GROW_DIRECTION > 0
+@@ -1721,6 +1769,7 @@ garbage_collect_0(VALUE *top_frame)
+ rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
+ (VALUE*)((char*)rb_gc_stack_start + 2));
+ #endif
++
+ rb_gc_mark_threads();
+
+ /* mark protected global variables */
+@@ -1767,17 +1816,17 @@ garbage_collect()
+
+ #if STACK_WIPE_SITES & 0x400
+ # ifdef nativeAllocA
+- if (__stack_past (top, stack_limit)) {
+- /* allocate a large frame to ensure app stack cannot grow into GC stack */
++ if ((!rb_main_thread || rb_curr_thread == rb_main_thread) && __stack_past (top, stack_limit)) {
++ /* allocate a large frame to ensure app stack cannot grow into GC stack */
+ (volatile void*) nativeAllocA(__stack_depth((void*)stack_limit,(void*)top));
+- }
++ }
+ garbage_collect_0(top);
+ # else /* no native alloca() available */
+ garbage_collect_0(top);
+- {
++ if (rb_curr_thread) {
+ VALUE *paddedLimit = __stack_grow(gc_stack_limit, GC_STACK_PAD);
+- if (__stack_past(rb_gc_stack_end, paddedLimit))
+- rb_gc_stack_end = paddedLimit;
++ if (__stack_past(rb_curr_thread->gc_stack_end, paddedLimit))
++ rb_curr_thread->gc_stack_end = paddedLimit;
+ }
+ rb_gc_wipe_stack(); /* wipe the whole stack area reserved for this gc */
+ # endif
+@@ -2630,9 +2679,6 @@ Init_GC()
+ {
+ VALUE rb_mObSpace;
+
+-#if !STACK_GROW_DIRECTION
+- rb_gc_stack_end = stack_grow_direction(&rb_mObSpace);
+-#endif
+ rb_mGC = rb_define_module("GC");
+ rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
+ rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
+diff --git a/node.h b/node.h
+index c209fa5..1242be5 100644
+--- a/node.h
++++ b/node.h
+@@ -411,8 +411,12 @@ struct rb_thread {
+
+ size_t stk_len;
+ size_t stk_max;
++ size_t stk_size;
+ VALUE *stk_ptr;
+ VALUE *stk_pos;
++ VALUE *stk_base;
++ VALUE *guard;
++ VALUE *gc_stack_end;
+ #ifdef __ia64
+ size_t bstr_len;
+ size_t bstr_max;
+diff --git a/rubysig.h b/rubysig.h
+index fae0869..4a4dadc 100644
+--- a/rubysig.h
++++ b/rubysig.h
+@@ -152,7 +152,6 @@ void rb_trap_restore_mask _((void));
+ RUBY_EXTERN int rb_thread_critical;
+ void rb_thread_schedule _((void));
+
+-RUBY_EXTERN VALUE *rb_gc_stack_end;
+ RUBY_EXTERN int rb_gc_stack_grow_direction; /* -1 for down or 1 for up */
+
+ #if STACK_GROW_DIRECTION > 0
+@@ -268,12 +267,14 @@ RUBY_EXTERN VALUE *__sp(void);
+ #if STACK_WIPE_METHOD == 0
+ #define rb_gc_wipe_stack() ((void)0)
+ #elif STACK_WIPE_METHOD == 4
+-#define rb_gc_wipe_stack() { \
+- VALUE *end = rb_gc_stack_end; \
+- VALUE *sp = __sp(); \
+- rb_gc_stack_end = sp; \
+- __stack_zero(end, sp); \
+-}
++#define rb_gc_wipe_stack() do { \
++ if (rb_curr_thread) { \
++ VALUE *end = rb_curr_thread->gc_stack_end; \
++ VALUE *sp = __sp(); \
++ rb_curr_thread->gc_stack_end = sp; \
++ __stack_zero(end, sp); \
++ } \
++} while (0)
+ #else
+ RUBY_EXTERN void rb_gc_wipe_stack(void);
+ #endif
+@@ -283,7 +284,7 @@ RUBY_EXTERN void rb_gc_wipe_stack(void);
+ */
+ #define rb_gc_update_stack_extent() do { \
+ VALUE *sp = __sp(); \
+- if __stack_past(rb_gc_stack_end, sp) rb_gc_stack_end = sp; \
++ if (rb_curr_thread && __stack_past(rb_curr_thread->gc_stack_end, sp)) rb_curr_thread->gc_stack_end = sp; \
+ } while(0)
+
+
+diff --git a/signal.c b/signal.c
+index 4cf3bec..58798bd 100644
+--- a/signal.c
++++ b/signal.c
+@@ -14,6 +14,7 @@
+
+ #include "ruby.h"
+ #include "rubysig.h"
++#include "node.h"
+ #include <signal.h>
+ #include <stdio.h>
+
+@@ -428,15 +429,22 @@ typedef RETSIGTYPE (*sighandler_t)_((int));
+ static sighandler_t
+ ruby_signal(signum, handler)
+ int signum;
+- sighandler_t handler;
++ void *handler;
+ {
+ struct sigaction sigact, old;
+
+ rb_trap_accept_nativethreads[signum] = 0;
+
+- sigact.sa_handler = handler;
++ if (signum == SIGSEGV || signum == SIGBUS) {
++ sigact.sa_sigaction = handler;
++ sigact.sa_flags = (SA_ONSTACK | SA_RESETHAND | SA_SIGINFO);
++ } else {
++ sigact.sa_handler = handler;
++ sigact.sa_flags = 0;
++ }
++
+ sigemptyset(&sigact.sa_mask);
+- sigact.sa_flags = 0;
++
+ # ifdef SA_NOCLDWAIT
+ if (signum == SIGCHLD && handler == SIG_IGN)
+ sigact.sa_flags |= SA_NOCLDWAIT;
+@@ -599,7 +607,132 @@ sighandler(sig)
+ }
+ }
+
++#include <stdio.h>
++#ifdef HAVE_STDARG_PROTOTYPES
++#include <stdarg.h>
++#define va_init_list(a,b) va_start(a,b)
++#else
++#include <varargs.h>
++#define va_init_list(a,b) va_start(a)
++#endif
++
++void
++#ifdef HAVE_STDARG_PROTOTYPES
++sig_printf(const char *fmt, ...)
++#else
++ sig_printf(fmt, va_alist)
++ const char *fmt;
++ va_dcl
++#endif
++{
++ char buf[BUFSIZ];
++ va_list args;
++ FILE *out = stderr;
++
++ va_init_list(args, fmt);
++ vfprintf(out, fmt, args);
++ va_end(args);
++ fprintf(out, "\n");
++}
++
++static void
++dump_machine_state(uc)
++ ucontext_t *uc;
++{
++ const char *dump64 =
++ " ----------------- Register state dump ----------------------\n"
++ "rax = 0x%.16x rbx = 0x%.16x rcx = 0x%.16x rdx = 0x%.16x\n"
++ "rdi = 0x%.16x rsi = 0x%.16x rbp = 0x%.16x rsp = 0x%.16x\n"
++ "r8 = 0x%.16x r9 = 0x%.16x r10 = 0x%.16x r11 = 0x%.16x\n"
++ "r12 = 0x%.16x r13 = 0x%.16x r14 = 0x%.16x r15 = 0x%.16x\n"
++ "rip = 0x%.16x rflags = 0x%.16x cs = 0x%.16x fs = 0x%.16x\n"
++ "gs = 0x%.16x";
++
++ const char *dump32 =
++ " ----------------- Register state dump -------------------\n"
++ "eax = 0x%.8x ebx = 0x%.8x ecx = 0x%.8x edx = 0x%.8x\n"
++ "edi = 0x%.8x esi = 0x%.8x ebp = 0x%.8x esp = 0x%.8x\n"
++ "ss = 0x%.8x eflags = 0x%.8x eip = 0x%.8x cs = 0x%.8x\n"
++ "ds = 0x%.8x es = 0x%.8x fs = 0x%.8x gs = 0x%.8x\n";
++
++#if defined(__LP64__) && defined(__APPLE__)
++ sig_printf(dump64, uc->uc_mcontext->__ss.__rax, uc->uc_mcontext->__ss.__rbx,
++ uc->uc_mcontext->__ss.__rcx, uc->uc_mcontext->__ss.__rdx, uc->uc_mcontext->__ss.__rdi,
++ uc->uc_mcontext->__ss.__rsi, uc->uc_mcontext->__ss.__rbp, uc->uc_mcontext->__ss.__rsp,
++ uc->uc_mcontext->__ss.__r8, uc->uc_mcontext->__ss.__r9, uc->uc_mcontext->__ss.__r10,
++ uc->uc_mcontext->__ss.__r11, uc->uc_mcontext->__ss.__r12, uc->uc_mcontext->__ss.__r13,
++ uc->uc_mcontext->__ss.__r14, uc->uc_mcontext->__ss.__r15, uc->uc_mcontext->__ss.__rip,
++ uc->uc_mcontext->__ss.__rflags, uc->uc_mcontext->__ss.__cs, uc->uc_mcontext->__ss.__fs,
++ uc->uc_mcontext->__ss.__gs);
++#elif !defined(__LP64__) && defined(__APPLE__)
++ sig_printf(dump32, uc->uc_mcontext->__ss.__eax, uc->uc_mcontext->__ss.__ebx,
++ uc->uc_mcontext->__ss.__ecx, uc->uc_mcontext->__ss.__edx,
++ uc->uc_mcontext->__ss.__edi, uc->uc_mcontext->__ss.__esi,
++ uc->uc_mcontext->__ss.__ebp, uc->uc_mcontext->__ss.__esp,
++ uc->uc_mcontext->__ss.__ss, uc->uc_mcontext->__ss.__eflags,
++ uc->uc_mcontext->__ss.__eip, uc->uc_mcontext->__ss.__cs,
++ uc->uc_mcontext->__ss.__ds, uc->uc_mcontext->__ss.__es,
++ uc->uc_mcontext->__ss.__fs, uc->uc_mcontext->__ss.__gs);
++#elif defined(__i386__)
++ sig_printf(dump32, uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX],
++ uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX],
++ uc->uc_mcontext.gregs[REG_EDI], uc->uc_mcontext.gregs[REG_ESI],
++ uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP],
++ uc->uc_mcontext.gregs[REG_SS], uc->uc_mcontext.gregs[REG_EFL],
++ uc->uc_mcontext.gregs[REG_EIP], uc->uc_mcontext.gregs[REG_EIP],
++ uc->uc_mcontext.gregs[REG_DS], uc->uc_mcontext.gregs[REG_ES],
++ uc->uc_mcontext.gregs[REG_FS], uc->uc_mcontext.gregs[REG_FS]);
++#elif defined(__x86_64__)
++ sig_printf(dump64, uc->uc_mcontext.gregs[REG_RAX], uc->uc_mcontext.gregs[REG_RBX],
++ uc->uc_mcontext.gregs[REG_RCX], uc->uc_mcontext.gregs[REG_RDX],
++ uc->uc_mcontext.gregs[REG_RDI], uc->uc_mcontext.gregs[REG_RSI],
++ uc->uc_mcontext.gregs[REG_RBP], uc->uc_mcontext.gregs[REG_RSP],
++ uc->uc_mcontext.gregs[REG_R8], uc->uc_mcontext.gregs[REG_R9],
++ uc->uc_mcontext.gregs[REG_R10], uc->uc_mcontext.gregs[REG_R11],
++ uc->uc_mcontext.gregs[REG_R12], uc->uc_mcontext.gregs[REG_R13],
++ uc->uc_mcontext.gregs[REG_R14], uc->uc_mcontext.gregs[REG_R15],
++ uc->uc_mcontext.gregs[REG_RIP], uc->uc_mcontext.gregs[REG_EFL],
++ uc->uc_mcontext.gregs[REG_CSGSFS]);
++#else
++#endif
++}
++
++static int
++check_guard(caddr_t fault_addr, rb_thread_t th) {
++ if(fault_addr <= (caddr_t)rb_curr_thread->guard &&
++ fault_addr >= (caddr_t)rb_curr_thread->stk_ptr) {
++ return 1;
++ }
++ return 0;
++}
++
+ #ifdef SIGBUS
++#ifdef POSIX_SIGNAL
++static void sigbus _((int, siginfo_t*, void*));
++static void
++sigbus(sig, ip, context)
++ int sig;
++ siginfo_t *ip;
++ void *context;
++{
++#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
++ if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
++ sigsend_to_ruby_thread(sig);
++ return;
++ }
++#endif
++
++ dump_machine_state(context);
++ if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {
++ /* we hit the guard page, print out a warning to help app developers */
++ rb_bug("Thread stack overflow! Try increasing it!");
++ } else {
++ rb_bug("Bus Error");
++ }
++}
++
++#else /* !defined(POSIX_SIGNAL) */
++
+ static RETSIGTYPE sigbus _((int));
+ static RETSIGTYPE
+ sigbus(sig)
+@@ -615,8 +748,36 @@ sigbus(sig)
+ rb_bug("Bus Error");
+ }
+ #endif
++#endif
++
+
+ #ifdef SIGSEGV
++#ifdef POSIX_SIGNAL
++static void sigsegv _((int, siginfo_t*, void*));
++static void
++sigsegv(sig, ip, context)
++ int sig;
++ siginfo_t *ip;
++ void *context;
++{
++#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
++ if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
++ sigsend_to_ruby_thread(sig);
++ return;
++ }
++#endif
++
++ dump_machine_state(context);
++ if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {
++ /* we hit the guard page, print out a warning to help app developers */
++ rb_bug("Thread stack overflow! Try increasing it!");
++ } else {
++ rb_bug("Segmentation fault");
++ }
++}
++
++#else /* !defined(POSIX_SIGNAL) */
++
+ static RETSIGTYPE sigsegv _((int));
+ static RETSIGTYPE
+ sigsegv(sig)
+@@ -633,6 +794,7 @@ sigsegv(sig)
+ rb_bug("Segmentation fault");
+ }
+ #endif
++#endif
+
+ #ifdef SIGPIPE
+ static RETSIGTYPE sigpipe _((int));
+@@ -704,7 +866,8 @@ static VALUE
+ trap(arg)
+ struct trap_arg *arg;
+ {
+- sighandler_t func, oldfunc;
++ sighandler_t oldfunc;
++ void *func;
+ VALUE command, oldcmd;
+ int sig = -1;
+ const char *s;
+@@ -951,6 +1114,20 @@ sig_list()
+ }
+
+ static void
++create_sigstack()
++{
++ stack_t ss;
++ ss.ss_size = SIGSTKSZ;
++ ss.ss_sp = malloc(ss.ss_size);
++ ss.ss_flags = 0;
++ if (sigaltstack(&ss, NULL) < 0) {
++ free(ss.ss_sp);
++ fprintf(stderr, "Couldn't create signal stack! Error %d: %s\n", errno, strerror(errno));
++ exit(1);
++ }
++}
++
++static void
+ install_sighandler(signum, handler)
+ int signum;
+ sighandler_t handler;
+@@ -959,7 +1136,7 @@ install_sighandler(signum, handler)
+
+ old = ruby_signal(signum, handler);
+ if (old != SIG_DFL) {
+- ruby_signal(signum, old);
++ ruby_signal(signum, old);
+ }
+ }
+
+@@ -1088,6 +1265,8 @@ Init_signal()
+ rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
+ rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
+
++ create_sigstack();
++
+ install_sighandler(SIGINT, sighandler);
+ #ifdef SIGHUP
+ install_sighandler(SIGHUP, sighandler);
diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/series b/patchsets/patches-ee-1.8.7-2010.02-r1/series
new file mode 100644
index 0000000..ad69a95
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/series
@@ -0,0 +1,10 @@
+001_memory_leak.patch
+002_mkconfig.patch
+003_mkmf-parallel-install.patch
+004_configure-libdir.patch
+005_mkconfig-libdir.patch
+006_pathname_warning.patch
+007_no-undefined-ext.patch
+008_berkdb-5.0.patch
+010_openssl1.patch
+012_webrick-CVE-2010-0541.patch
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2011-05-15 6:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-15 6:24 [gentoo-commits] proj/ruby-scripts:master commit in: patchsets/patches-ee-1.8.7-2010.02-r1/ Hans de Graaff
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox