ruby-changes:36870
From: naruse <ko1@a...>
Date: Wed, 24 Dec 2014 03:23:30 +0900 (JST)
Subject: [ruby-changes:36870] naruse:r48951 (ruby_2_2): merge revision(s) 48923: [Backport #10633]
naruse 2014-12-24 03:23:19 +0900 (Wed, 24 Dec 2014) New Revision: 48951 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48951 Log: merge revision(s) 48923: [Backport #10633] * ext/openssl/ossl_cipher.c (ossl_cipher_update_long): update huge data gradually not to exceed INT_MAX. workaround of OpenSSL API limitation. [ruby-core:67043] [Bug #10633] Modified directories: branches/ruby_2_2/ Modified files: branches/ruby_2_2/ChangeLog branches/ruby_2_2/ext/openssl/ossl_cipher.c Index: ruby_2_2/ChangeLog =================================================================== --- ruby_2_2/ChangeLog (revision 48950) +++ ruby_2_2/ChangeLog (revision 48951) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ChangeLog#L1 +Wed Dec 24 03:22:49 2014 Nobuyoshi Nakada <nobu@r...> + + * ext/openssl/ossl_cipher.c (ossl_cipher_update_long): update huge + data gradually not to exceed INT_MAX. workaround of OpenSSL API + limitation. [ruby-core:67043] [Bug #10633] + Wed Dec 24 03:16:32 2014 NARUSE, Yui <naruse@r...> * lib/uri/generic.rb (URI::Generic#query=): don't escape [\]^ Index: ruby_2_2/ext/openssl/ossl_cipher.c =================================================================== --- ruby_2_2/ext/openssl/ossl_cipher.c (revision 48950) +++ ruby_2_2/ext/openssl/ossl_cipher.c (revision 48951) @@ -346,6 +346,33 @@ ossl_cipher_pkcs5_keyivgen(int argc, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_cipher.c#L346 return Qnil; } +static int +ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr, + const unsigned char *in, long in_len) +{ + int out_part_len; + long out_len = 0; +#define UPDATE_LENGTH_LIMIT INT_MAX + +#if SIZEOF_LONG > UPDATE_LENGTH_LIMIT + if (in_len > UPDATE_LENGTH_LIMIT) { + const int in_part_len = (UPDATE_LENGTH_LIMIT / 2 + 1) & ~1; + do { + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, in_part_len)) + return 0; + out_len += out_part_len; + in += in_part_len; + } while ((in_len -= in_part_len) > UPDATE_LENGTH_LIMIT); + } +#endif + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, (int)in_len)) + return 0; + if (out_len_ptr) *out_len_ptr = out_len += out_part_len; + return 1; +} + /* * call-seq: * cipher.update(data [, buffer]) -> string or buffer @@ -364,17 +391,21 @@ ossl_cipher_update(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_cipher.c#L391 { EVP_CIPHER_CTX *ctx; unsigned char *in; - int in_len, out_len; + long in_len, out_len; VALUE data, str; rb_scan_args(argc, argv, "11", &data, &str); StringValue(data); in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LENINT(data)) == 0) + if ((in_len = RSTRING_LEN(data)) == 0) ossl_raise(rb_eArgError, "data must not be empty"); GetCipher(self, ctx); out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); + if (out_len <= 0) { + ossl_raise(rb_eRangeError, + "data too big to make output buffer: %ld bytes", in_len); + } if (NIL_P(str)) { str = rb_str_new(0, out_len); @@ -383,7 +414,7 @@ ossl_cipher_update(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_cipher.c#L414 rb_str_resize(str, out_len); } - if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) + if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) ossl_raise(eCipherError, NULL); assert(out_len < RSTRING_LEN(str)); rb_str_set_len(str, out_len); @@ -523,17 +554,16 @@ ossl_cipher_set_auth_data(VALUE self, VA https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ext/openssl/ossl_cipher.c#L554 { EVP_CIPHER_CTX *ctx; unsigned char *in; - int in_len; - int out_len; + long in_len, out_len; StringValue(data); in = (unsigned char *) RSTRING_PTR(data); - in_len = RSTRING_LENINT(data); + in_len = RSTRING_LEN(data); GetCipher(self, ctx); - if (!EVP_CipherUpdate(ctx, NULL, &out_len, in, in_len)) + if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); return data; Property changes on: ruby_2_2 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r48923 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/