From dabc90361d1b71fcac4f606eb1eb1fa25c047fd9 Mon Sep 17 00:00:00 2001
From: hone <hone@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sun, 22 Dec 2013 23:31:03 +0000
Subject: [PATCH 1/4] merge revision(s) 43775: [Fixes GH-457]
 https://github.com/ruby/ruby/pull/457

    * util.c (ruby_strtod): ignore too long fraction part, which does not
      affect the result.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@44351 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 ChangeLog |  5 +++++
 util.c    | 14 ++++++++++++--
 version.h | 10 +++++-----
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dbba29d..0bc6d98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Nov 22 12:43:52 2013  Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* util.c (ruby_strtod): ignore too long fraction part, which does not
+	  affect the result.
+
 Thu Jun 27 20:55:23 2013  URABE Shyouhei  <shyouhei@ruby-lang.org>
 
 	* test/openssl/test_ssl.rb: Oops, sorry!
diff --git a/util.c b/util.c
index 62f3368..e98efc6 100644
--- a/util.c
+++ b/util.c
@@ -892,6 +892,11 @@ extern void *MALLOC(size_t);
 #else
 #define MALLOC malloc
 #endif
+#ifdef FREE
+extern void FREE(void*);
+#else
+#define FREE free
+#endif
 
 #ifndef Omit_Private_Memory
 #ifndef PRIVATE_MEM
@@ -1176,7 +1181,7 @@ Balloc(int k)
 #endif
 
     ACQUIRE_DTOA_LOCK(0);
-    if ((rv = freelist[k]) != 0) {
+    if (k <= Kmax && (rv = freelist[k]) != 0) {
         freelist[k] = rv->next;
     }
     else {
@@ -1186,7 +1191,7 @@ Balloc(int k)
 #else
         len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
                 /sizeof(double);
-        if (pmem_next - private_mem + len <= PRIVATE_mem) {
+        if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
             rv = (Bigint*)pmem_next;
             pmem_next += len;
         }
@@ -1205,6 +1210,10 @@ static void
 Bfree(Bigint *v)
 {
     if (v) {
+        if (v->k > Kmax) {
+            FREE(v);
+            return;
+        }
         ACQUIRE_DTOA_LOCK(0);
         v->next = freelist[v->k];
         freelist[v->k] = v;
@@ -2200,6 +2209,7 @@ break2:
         for (; c >= '0' && c <= '9'; c = *++s) {
 have_dig:
             nz++;
+            if (nf > DBL_DIG * 2) continue;
             if (c -= '0') {
                 nf += nz;
                 for (i = 1; i < nz; i++)
diff --git a/version.h b/version.h
index 6b6d57e..4454d95 100644
--- a/version.h
+++ b/version.h
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2013-06-27"
+#define RUBY_RELEASE_DATE "2013-12-22"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20130627
-#define RUBY_PATCHLEVEL 374
+#define RUBY_RELEASE_CODE 20131222
+#define RUBY_PATCHLEVEL 375
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 7
 #define RUBY_RELEASE_YEAR 2013
-#define RUBY_RELEASE_MONTH 6
-#define RUBY_RELEASE_DAY 27
+#define RUBY_RELEASE_MONTH 12
+#define RUBY_RELEASE_DAY 22
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
-- 
2.3.5


From b912e1d2c02a038818aac2a82a1dc927a70e0750 Mon Sep 17 00:00:00 2001
From: svn <svn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sun, 22 Dec 2013 23:31:10 +0000
Subject: [PATCH 2/4] * 2013-12-23

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@44352 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 version.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/version.h b/version.h
index 4454d95..af541ec 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2013-12-22"
+#define RUBY_RELEASE_DATE "2013-12-23"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20131222
+#define RUBY_RELEASE_CODE 20131223
 #define RUBY_PATCHLEVEL 375
 
 #define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
 #define RUBY_VERSION_TEENY 7
 #define RUBY_RELEASE_YEAR 2013
 #define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 22
+#define RUBY_RELEASE_DAY 23
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
-- 
2.3.5


From f48ae0d10c5b586db5748b0d4b645c7e9ff5d52e Mon Sep 17 00:00:00 2001
From: naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Mon, 27 Jan 2014 18:59:34 +0000
Subject: [PATCH 3/4] merge revision(s) 44717:

	* configure.in: define USE_BUILTIN_FRAME_ADDRESS on x86_64
	  even if __builtin_frame_address is not used now.
	  By this, FreeBSD's clang can build ruby 1.8,
	  and alloca(1) doesn't work on it.


git-svn-id: svn+ssh://svn.ruby-lang.org/ruby/branches/ruby_1_8_7@44719 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 ChangeLog    |  7 +++++++
 configure.in |  1 +
 version.h    | 12 ++++++------
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0bc6d98..0808298 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Tue Jan 28 03:59:15 2014  NARUSE, Yui  <naruse@ruby-lang.org>
+
+	* configure.in: define USE_BUILTIN_FRAME_ADDRESS on x86_64
+	  even if __builtin_frame_address is not used now.
+	  By this, FreeBSD's clang can build ruby 1.8,
+	  and alloca(1) doesn't work on it.
+
 Fri Nov 22 12:43:52 2013  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 
 	* util.c (ruby_strtod): ignore too long fraction part, which does not
diff --git a/configure.in b/configure.in
index 62b34a8..306d536 100644
--- a/configure.in
+++ b/configure.in
@@ -144,6 +144,7 @@ fi
 
 case $target_cpu in
   i?86) frame_address=yes;;
+  x86_64) frame_address=yes;;
   *)    frame_address=no;;
 esac
 AC_ARG_ENABLE(frame-address,
diff --git a/version.h b/version.h
index af541ec..d8e8abf 100644
--- a/version.h
+++ b/version.h
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2013-12-23"
+#define RUBY_RELEASE_DATE "2014-01-28"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20131223
-#define RUBY_PATCHLEVEL 375
+#define RUBY_RELEASE_CODE 20140128
+#define RUBY_PATCHLEVEL 376
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 7
-#define RUBY_RELEASE_YEAR 2013
-#define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 23
+#define RUBY_RELEASE_YEAR 2014
+#define RUBY_RELEASE_MONTH 1
+#define RUBY_RELEASE_DAY 28
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
-- 
2.3.5


From 9d7d09b62e8b34a9eb20a7d47b9d41354d278864 Mon Sep 17 00:00:00 2001
From: Tobias Kraze <tobias.kraze@makandra.de>
Date: Tue, 14 Apr 2015 11:03:08 +0200
Subject: [PATCH 4/4] backport [Backport #9644]

---
 ext/openssl/lib/openssl/ssl-internal.rb |  55 +++++++++++-
 test/openssl/test_ssl.rb                | 152 +++++++++++++++++++++++++++++++-
 2 files changed, 204 insertions(+), 3 deletions(-)

diff --git a/ext/openssl/lib/openssl/ssl-internal.rb b/ext/openssl/lib/openssl/ssl-internal.rb
index 9ef6f92..4ff6d72 100644
--- a/ext/openssl/lib/openssl/ssl-internal.rb
+++ b/ext/openssl/lib/openssl/ssl-internal.rb
@@ -97,7 +97,7 @@ module OpenSSL
           when 2 # dNSName in GeneralName (RFC5280)
             should_verify_common_name = false
             reg = Regexp.escape(san.value).gsub(/\\\*/, "[^.]+")
-            return true if /\A#{reg}\z/i =~ hostname
+            return true if verify_hostname(hostname, san.value)
           when 7 # iPAddress in GeneralName (RFC5280)
             should_verify_common_name = false
             # follows GENERAL_NAME_print() in x509v3/v3_alt.c
@@ -113,7 +113,7 @@ module OpenSSL
         cert.subject.to_a.each{|oid, value|
           if oid == "CN"
             reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
-            return true if /\A#{reg}\z/i =~ hostname
+            return true if verify_hostname(hostname, value)
           end
         }
       end
@@ -121,6 +121,57 @@ module OpenSSL
     end
     module_function :verify_certificate_identity
 
+    def verify_hostname(hostname, san) # :nodoc:
+      # RFC 5280, IA5String is limited to the set of ASCII characters
+      return false if san =~ /[\x80-\xff]/
+      return false if hostname =~ /[\x80-\xff]/
+
+      # See RFC 6125, section 6.4.1
+      # Matching is case-insensitive.
+      san_parts = san.downcase.split(".")
+
+      # TODO: this behavior should probably be more strict
+      return san == hostname if san_parts.size < 2
+
+      # Matching is case-insensitive.
+      host_parts = hostname.downcase.split(".")
+
+      # RFC 6125, section 6.4.3, subitem 2.
+      # If the wildcard character is the only character of the left-most
+      # label in the presented identifier, the client SHOULD NOT compare
+      # against anything but the left-most label of the reference
+      # identifier (e.g., *.example.com would match foo.example.com but
+      # not bar.foo.example.com or example.com).
+      return false unless san_parts.size == host_parts.size
+
+      # RFC 6125, section 6.4.3, subitem 1.
+      # The client SHOULD NOT attempt to match a presented identifier in
+      # which the wildcard character comprises a label other than the
+      # left-most label (e.g., do not match bar.*.example.net).
+      return false unless verify_wildcard(host_parts.shift, san_parts.shift)
+
+      san_parts.join(".") == host_parts.join(".")
+    end
+    module_function :verify_hostname
+
+    def verify_wildcard(domain_component, san_component) # :nodoc:
+      parts = san_component.split("*", -1)
+
+      return false if parts.size > 2
+      return san_component == domain_component if parts.size == 1
+
+      # RFC 6125, section 6.4.3, subitem 3.
+      # The client SHOULD NOT attempt to match a presented identifier
+      # where the wildcard character is embedded within an A-label or
+      # U-label of an internationalized domain name.
+      return false if domain_component.start_with?("xn--") && san_component != "*"
+
+      parts[0].length + parts[1].length < domain_component.length &&
+      domain_component.start_with?(parts[0]) &&
+      domain_component.end_with?(parts[1])
+    end
+    module_function :verify_wildcard
+
     class SSLSocket
       include Buffering
       include SocketForwarder
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 2e014f1..125f057 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -569,6 +569,156 @@ class OpenSSL::TestSSL < Test::Unit::TestCase
     assert_equal(false, OpenSSL::SSL.verify_certificate_identity(cert, '13::17'))
     assert_equal(true,  OpenSSL::SSL.verify_certificate_identity(cert, '13:0:0:0:0:0:0:17'))
   end
-end
 
+  def test_verify_hostname
+    assert_equal(true,  OpenSSL::SSL.verify_hostname("www.example.com", "*.example.com"))
+    assert_equal(false, OpenSSL::SSL.verify_hostname("www.subdomain.example.com", "*.example.com"))
+  end
+
+  def test_verify_wildcard
+    assert_equal(false, OpenSSL::SSL.verify_wildcard("foo", "x*"))
+    assert_equal(true,  OpenSSL::SSL.verify_wildcard("foo", "foo"))
+    assert_equal(true,  OpenSSL::SSL.verify_wildcard("foo", "f*"))
+    assert_equal(true,  OpenSSL::SSL.verify_wildcard("foo", "*"))
+    assert_equal(false, OpenSSL::SSL.verify_wildcard("abc*bcd", "abcd"))
+    assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "x*"))
+    assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "*--qdk4b9b"))
+    assert_equal(true,  OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "xn--qdk4b9b"))
+  end
+
+  # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27
+  def test_post_connection_check_wildcard_san
+    # case-insensitive ASCII comparison
+    # RFC 6125, section 6.4.1
+    #
+    # "..matching of the reference identifier against the presented identifier
+    # is performed by comparing the set of domain name labels using a
+    # case-insensitive ASCII comparison, as clarified by [DNS-CASE] (e.g.,
+    # "WWW.Example.Com" would be lower-cased to "www.example.com" for
+    # comparison purposes)
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*.example.com'), 'www.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*.Example.COM'), 'www.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*.example.com'), 'WWW.Example.COM'))
+    # 1.  The client SHOULD NOT attempt to match a presented identifier in
+    #     which the wildcard character comprises a label other than the
+    #     left-most label (e.g., do not match bar.*.example.net).
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:www.*.com'), 'www.example.com'))
+    # 2.  If the wildcard character is the only character of the left-most
+    #     label in the presented identifier, the client SHOULD NOT compare
+    #     against anything but the left-most label of the reference
+    #     identifier (e.g., *.example.com would match foo.example.com but
+    #     not bar.foo.example.com or example.com).
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*.example.com'), 'foo.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*.example.com'), 'bar.foo.example.com'))
+    # 3.  The client MAY match a presented identifier in which the wildcard
+    #     character is not the only character of the label (e.g.,
+    #     baz*.example.net and *baz.example.net and b*z.example.net would
+    #     be taken to match baz1.example.net and foobaz.example.net and
+    #     buzz.example.net, respectively).  ...
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com'))
+    # Section 6.4.3 of RFC6125 states that client should NOT match identifier
+    # where wildcard is other than left-most label.
+    #
+    # Also implicitly mentions the wildcard character only in singular form,
+    # and discourages matching against more than one wildcard.
+    #
+    # See RFC 6125, section 7.2, subitem 2.
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*b*.example.com'), 'abc.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*b*.example.com'), 'ab.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:*b*.example.com'), 'bc.example.com'))
+    #                                ...  However, the client SHOULD NOT
+    #   attempt to match a presented identifier where the wildcard
+    #   character is embedded within an A-label or U-label [IDNA-DEFS] of
+    #   an internationalized domain name [IDNA-PROTO].
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:xn*.example.com'), 'xn1ca.example.com'))
+    # part of A-label
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:xn--*.example.com'), 'xn--1ca.example.com'))
+    # part of U-label
+    # dNSName in RFC5280 is an IA5String so U-label should NOT be allowed
+    # regardless of wildcard.
+    #
+    # See Section 7.2 of RFC 5280:
+    #   IA5String is limited to the set of ASCII characters.
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_san('DNS:á*.example.com'), 'á1.example.com'))
+  end
+
+  def test_post_connection_check_wildcard_cn
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*.example.com'), 'www.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*.Example.COM'), 'www.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*.example.com'), 'WWW.Example.COM'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('www.*.com'), 'www.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*.example.com'), 'foo.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*.example.com'), 'bar.foo.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('baz*.example.com'), 'baz1.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*baz.example.com'), 'foobaz.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('b*z.example.com'), 'buzz.example.com'))
+    # Section 6.4.3 of RFC6125 states that client should NOT match identifier
+    # where wildcard is other than left-most label.
+    #
+    # Also implicitly mentions the wildcard character only in singular form,
+    # and discourages matching against more than one wildcard.
+    #
+    # See RFC 6125, section 7.2, subitem 2.
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*b*.example.com'), 'abc.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*b*.example.com'), 'ab.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('*b*.example.com'), 'bc.example.com'))
+    assert_equal(true, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('xn*.example.com'), 'xn1ca.example.com'))
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('xn--*.example.com'), 'xn--1ca.example.com'))
+    # part of U-label
+    # Subject in RFC5280 states case-insensitive ASCII comparison.
+    #
+    # See Section 7.2 of RFC 5280:
+    #   IA5String is limited to the set of ASCII characters.
+    assert_equal(false, OpenSSL::SSL.verify_certificate_identity(
+      create_cert_with_name('á*.example.com'), 'á1.example.com'))
+  end
+
+  def create_cert_with_san(san)
+    ef = OpenSSL::X509::ExtensionFactory.new
+    cert = OpenSSL::X509::Certificate.new
+    cert.subject = OpenSSL::X509::Name.parse("/DC=some/DC=site/CN=Some Site")
+    ext = ef.create_ext('subjectAltName', san)
+    cert.add_extension(ext)
+    cert
+  end
+
+  def create_cert_with_name(name)
+    cert = OpenSSL::X509::Certificate.new
+    cert.subject = OpenSSL::X509::Name.new([['DC', 'some'], ['DC', 'site'], ['CN', name]])
+    cert
+  end
+
+
+end
 end
-- 
2.3.5

