ruby-changes:43864
From: usa <ko1@a...>
Date: Tue, 16 Aug 2016 20:55:09 +0900 (JST)
Subject: [ruby-changes:43864] usa:r55937 (ruby_2_2): merge revision(s) 55047: [Backport #12441]
usa 2016-08-16 20:55:03 +0900 (Tue, 16 Aug 2016) New Revision: 55937 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55937 Log: merge revision(s) 55047: [Backport #12441] * ext/openssl/ossl_bn.c (try_convert_to_bnptr): Extracted from GetBNPtr(). This doesn't raise exception but returns NULL on error. (GetBNPtr): Raise TypeError if conversion fails. (ossl_bn_eq): Implement BN#==. (ossl_bn_eql): #eql? should not raise TypeError even if the argument is not compatible with BN. (ossl_bn_hash): Implement BN#hash. * ext/openssl/ossl_bn.c (Init_ossl_bn): Define #== and #hash. * test/openssl/test_bn.rb: Test BN#eql?, #== and #hash Modified directories: branches/ruby_2_2/ Modified files: branches/ruby_2_2/ChangeLog branches/ruby_2_2/ext/openssl/ossl_bn.c branches/ruby_2_2/test/openssl/test_bn.rb branches/ruby_2_2/version.h Index: ruby_2_2/version.h =================================================================== --- ruby_2_2/version.h (revision 55936) +++ ruby_2_2/version.h (revision 55937) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/version.h#L1 #define RUBY_VERSION "2.2.6" #define RUBY_RELEASE_DATE "2016-08-16" -#define RUBY_PATCHLEVEL 363 +#define RUBY_PATCHLEVEL 364 #define RUBY_RELEASE_YEAR 2016 #define RUBY_RELEASE_MONTH 8 Index: ruby_2_2/test/openssl/test_bn.rb =================================================================== --- ruby_2_2/test/openssl/test_bn.rb (revision 55936) +++ ruby_2_2/test/openssl/test_bn.rb (revision 55937) @@ -42,10 +42,18 @@ class OpenSSL::TestBN < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/openssl/test_bn.rb#L42 assert_equal(true, OpenSSL::BN.new((2 ** 127 - 1).to_s(16), 16).prime?(1)) end - def test_cmp_nil - bn = OpenSSL::BN.new('1') - assert_equal(false, bn == nil) - assert_equal(true, bn != nil) + def test_cmp + bn1 = OpenSSL::BN.new('1') + bn2 = OpenSSL::BN.new('1') + bn3 = OpenSSL::BN.new('2') + assert_equal(false, bn1 == nil) + assert_equal(true, bn1 != nil) + assert_equal(true, bn1 == bn2) + assert_equal(false, bn1 == bn3) + assert_equal(true, bn1.eql?(bn2)) + assert_equal(false, bn1.eql?(bn3)) + assert_equal(bn1.hash, bn2.hash) + assert_not_equal(bn3.hash, bn1.hash) end end Index: ruby_2_2/ext/openssl/ossl_bn.c =================================================================== --- ruby_2_2/ext/openssl/ossl_bn.c (revision 55936) +++ ruby_2_2/ext/openssl/ossl_bn.c (revision 55937) @@ -73,8 +73,8 @@ ossl_bn_new(const BIGNUM *bn) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_bn.c#L73 return obj; } -BIGNUM * -GetBNPtr(VALUE obj) +static BIGNUM * +try_convert_to_bnptr(VALUE obj) { BIGNUM *bn = NULL; @@ -89,14 +89,20 @@ GetBNPtr(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_bn.c#L89 } WrapBN(cBN, obj, bn); /* Handle potencial mem leaks */ break; - case T_NIL: - break; - default: - ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); } return bn; } +BIGNUM * +GetBNPtr(VALUE obj) +{ + BIGNUM *bn = try_convert_to_bnptr(obj); + if (!bn) + ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); + + return bn; +} + /* * Private */ @@ -708,16 +714,80 @@ ossl_bn_copy(VALUE self, VALUE other) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_bn.c#L714 BIGNUM_CMP(cmp) BIGNUM_CMP(ucmp) +/* + * call-seq: + * bn == obj => true or false + * + * Returns +true+ only if +obj+ has the same value as +bn+. Contrast this + * with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN. + */ static VALUE -ossl_bn_eql(VALUE self, VALUE other) +ossl_bn_eq(VALUE self, VALUE other) { - if (ossl_bn_cmp(self, other) == INT2FIX(0)) { + BIGNUM *bn1, *bn2; + + GetBN(self, bn1); + /* BNPtr may raise, so we can't use here */ + bn2 = try_convert_to_bnptr(other); + + if (bn2 && !BN_cmp(bn1, bn2)) { return Qtrue; } return Qfalse; } /* + * call-seq: + * bn.eql?(obj) => true or false + * + * Returns <code>true</code> only if <i>obj</i> is a + * <code>OpenSSL::BN</code> with the same value as <i>big</i>. Contrast this + * with OpenSSL::BN#==, which performs type conversions. + */ +static VALUE +ossl_bn_eql(VALUE self, VALUE other) +{ + BIGNUM *bn1, *bn2; + + if (!rb_obj_is_kind_of(other, cBN)) + return Qfalse; + GetBN(self, bn1); + GetBN(other, bn2); + + return BN_cmp(bn1, bn2) ? Qfalse : Qtrue; +} + +/* + * call-seq: + * bn.hash => Integer + * + * Returns a hash code for this object. + * + * See also Object#hash. + */ +static VALUE +ossl_bn_hash(VALUE self) +{ + BIGNUM *bn; + VALUE hash; + unsigned char *buf; + int len; + + GetBN(self, bn); + len = BN_num_bytes(bn); + buf = xmalloc(len); + if (BN_bn2bin(bn, buf) != len) { + xfree(buf); + ossl_raise(eBNError, NULL); + } + + hash = INT2FIX(rb_memhash(buf, len)); + xfree(buf); + + return hash; +} + +/* * call-seq: * bn.prime? => true | false * bn.prime?(checks) => true | false @@ -844,8 +914,9 @@ Init_ossl_bn(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_bn.c#L914 rb_define_alias(cBN, "<=>", "cmp"); rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1); rb_define_method(cBN, "eql?", ossl_bn_eql, 1); - rb_define_alias(cBN, "==", "eql?"); - rb_define_alias(cBN, "===", "eql?"); + rb_define_method(cBN, "hash", ossl_bn_hash, 0); + rb_define_method(cBN, "==", ossl_bn_eq, 1); + rb_define_alias(cBN, "===", "=="); rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0); rb_define_method(cBN, "one?", ossl_bn_is_one, 0); /* is_word */ Index: ruby_2_2/ChangeLog =================================================================== --- ruby_2_2/ChangeLog (revision 55936) +++ ruby_2_2/ChangeLog (revision 55937) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ChangeLog#L1 +Tue Aug 16 20:40:36 2016 Kazuki Yamaguchi <k@r...> + + * ext/openssl/ossl_bn.c (try_convert_to_bnptr): Extracted from + GetBNPtr(). This doesn't raise exception but returns NULL on error. + (GetBNPtr): Raise TypeError if conversion fails. + (ossl_bn_eq): Implement BN#==. + (ossl_bn_eql): #eql? should not raise TypeError even if the argument + is not compatible with BN. + (ossl_bn_hash): Implement BN#hash. + + * ext/openssl/ossl_bn.c (Init_ossl_bn): Define #== and #hash. + + * test/openssl/test_bn.rb: Test BN#eql?, #== and #hash + Tue Aug 16 20:34:22 2016 Nobuyoshi Nakada <nobu@r...> * transcode.c (str_transcode0): scrub in the given encoding when Property changes on: ruby_2_2 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r55047 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/