diff --git a/ChangeLog b/ChangeLog index 298c3722fc52a4..996b9669c88c01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,126 @@ Thu Mar 6 10:33:31 2014 Martin Bosslet <Martin.Bosslet@gmail.com> Reported by Jeff Hodges. [ruby-core:59829] [Bug #9424] +Thu May 8 01:13:10 2014 NARUSE, Yui <naruse@ruby-lang.org> + + * configure.in: correct pthread_setname_np's prototype on NetBSD. + [Bug #9586] + +Tue May 6 00:54:56 2014 Narihiro Nakamura <authornari@gmail.com> + + * gc.c (gc_after_sweep): suppress unnecessary expanding heap. + Tomb heap pages are freed pages here, so expanding heap is + not required. + +Mon May 5 02:35:20 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/openssl/ossl_pkey.c (ossl_pkey_verify): as EVP_VerifyFinal() + finalizes only a copy of the digest context, the context must be + cleaned up after initialization by EVP_MD_CTX_cleanup() or a + memory leak will occur. [ruby-core:62038] [Bug #9743] + +Mon May 5 02:21:48 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/dl/cptr.c (dlptr_free), ext/dl/handle.c (dlhandle_free), + ext/fiddle/handle.c (fiddle_handle_free), + ext/fiddle/pointer.c (fiddle_ptr_free): fix memory leak. + based on the patch Heesob Park at [ruby-dev:48021] [Bug #9599]. + +Mon May 5 01:20:27 2014 Eric Wong <e@80x24.org> + + * gc.c (rb_gc_writebarrier): drop special case for big hash/array + [Bug #9518] + +Mon May 5 01:13:00 2014 Koichi Sasada <ko1@atdot.net> + + * gc.c (gc_before_sweep): cap `malloc_limit' to + gc_params.malloc_limit_max. It can grow and grow with such case: + `loop{"a" * (1024 ** 2)}' + [Bug #9687] + + This issue is pointed by Tim Robertson. + http://www.omniref.com/blog/blog/2014/03/27/ruby-garbage-collection-still-not-ready-for-production/ + +Mon May 5 00:52:18 2014 Kenta Murata <mrkn@mrkn.jp> + + * ext/bigdecimal/bigdecimal.c (BigDecimal_initialize): Insert GC guard. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_global_new): ditto. + +Mon May 5 00:42:35 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com> + + * ext/psych/psych.gemspec: update gemspec for psych-2.0.5 + +Mon May 5 00:42:35 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com> + + * ext/psych/lib/psych.rb: Merge psych-2.0.5. bump version to + libyaml-0.1.6 for CVE-2014-2525. + * ext/psych/yaml/config.h: ditto. + * ext/psych/yaml/scanner.c: ditto. + * ext/psych/yaml/yaml_private.h: ditto. + +Mon May 5 00:35:20 2014 Aaron Patterson <aaron@tenderlovemaking.com> + + * ext/psych/lib/psych/visitors/yaml_tree.rb: support dumping Encoding + objects. + + * ext/psych/lib/psych/visitors/to_ruby.rb: support loading Encoding + objects. + + * test/psych/test_encoding.rb: add test + + * ext/psych/lib/psych.rb: add version + +Mon May 5 00:16:35 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com> + + * gc.c: Fix up default GC params by @csfrancis [fix GH-556] + +Fri May 2 00:19:36 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/openssl/ossl.c (ossl_make_error): check NULL for unknown + error reasons with old OpenSSL, and insert a colon iff formatted + message is not empty. + +Thu May 1 20:56:56 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/readline/extconf.rb (rl_hook_func_t): check pointer type. + [ruby-dev:48089] [Bug #9702] + +Thu May 1 20:47:08 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/readline/extconf.rb: fix typo, `$defs` not `$DEFS`. + [ruby-core:61756] [Bug #9578] + +Thu May 1 20:47:08 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/readline/extconf.rb (rl_hook_func_t): define as Function for + very old readline versions. [ruby-core:61209] [Bug #9578] + +Thu May 1 20:47:08 2014 Tanaka Akira <akr@fsij.org> + + * ext/readline/readline.c (Init_readline): Use rl_hook_func_t instead + of Function to support readline-6.3. (rl_hook_func_t is available + since readline-4.2.) + Reported by Dmitry Medvinsky. [ruby-core:61141] [Bug #9578] + +Sat Mar 1 21:00:27 2014 Marc-Andre Lafortune <ruby-core@marc-andre.ca> + + * proc.c: Having optional keyword arguments makes maximum arity +1, + not unlimited [#8072] + +Sat Mar 1 17:25:12 2014 Marc-Andre Lafortune <ruby-core@marc-andre.ca> + + * proc.c: Having any mandatory keyword argument increases min arity + [#9299] + +Mon Feb 24 14:56:41 2014 WATANABE Hirofumi <eban@ruby-lang.org> + + * tool/make-snapshot: needs CXXFLAGS. [ruby-core:59393][Bug #9320] + +Mon Feb 24 14:56:41 2014 NAKAMURA Usaku <usa@ruby-lang.org> + + * tool/make-snapshot: support new version scheme. + Mon Feb 24 13:05:48 2014 Aaron Patterson <aaron@tenderlovemaking.com> * ext/psych/lib/psych.rb: New release of psych. @@ -590,7 +710,6 @@ Thu Jan 9 08:21:00 2014 Aman Gupta <ruby@tmm1.net> * test/net/imap/Makefile: add `make regen_certs` to automate this process. ->>>>>>> v2_1_1 Thu Dec 26 03:28:11 2013 Koichi Sasada <ko1@atdot.net> * vm_insnhelper.c (argument_error): insert dummy frame to make diff --git a/configure.in b/configure.in index 96b8f1994416da..ddc4216d9107df 100644 --- a/configure.in +++ b/configure.in @@ -2455,6 +2455,36 @@ if test x"$enable_pthread" = xyes; then else AC_CHECK_FUNCS(pthread_attr_init) fi + if test "$ac_cv_func_pthread_setname_np" = yes; then + AC_CACHE_CHECK([arguments of pthread_setname_np], [rb_cv_func_pthread_setname_np_arguments], + [rb_cv_func_pthread_setname_np_arguments= + # Linux,AIX, (pthread_self(), name) + # NetBSD (pthread_self(), name, \"%s\") + # Darwin (name) + for mac in \ + "(pthread_self(), name)" \ + "(pthread_self(), name, \"%s\")" \ + "(name)" \ + ; do + AC_TRY_COMPILE([ + @%:@include <pthread.h> + @%:@ifdef HAVE_PTHREAD_NP_H + @%:@include <pthread_np.h> + @%:@endif + @%:@define SET_THREAD_NAME(name) pthread_setname_np${mac} + ], + [if (SET_THREAD_NAME("conftest")) return 1;], + [rb_cv_func_pthread_setname_np_arguments="${mac}" + break]) + done + ] + ) + if test -n "${rb_cv_func_pthread_setname_np_arguments}"; then + AC_DEFINE_UNQUOTED(SET_THREAD_NAME(name), pthread_setname_np${rb_cv_func_pthread_setname_np_arguments}) + else + AC_DEFINE_UNQUOTED(SET_THREAD_NAME(name), (void)0) + fi + fi fi if test x"$ac_cv_header_ucontext_h" = xyes; then if test x"$rb_with_pthread" = xyes; then diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 4120a2346dc948..6425a17db2cd7e 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2456,9 +2456,11 @@ static Real *BigDecimal_new(int argc, VALUE *argv); static VALUE BigDecimal_initialize(int argc, VALUE *argv, VALUE self) { + ENTER(1); Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); - Real *x = BigDecimal_new(argc, argv); + Real *x; + GUARD_OBJ(x, BigDecimal_new(argc, argv)); if (ToValue(x)) { pv = VpCopy(pv, x); } @@ -2539,7 +2541,10 @@ BigDecimal_new(int argc, VALUE *argv) static VALUE BigDecimal_global_new(int argc, VALUE *argv, VALUE self) { - Real *pv = BigDecimal_new(argc, argv); + ENTER(1); + Real *pv; + + GUARD_OBJ(pv, BigDecimal_new(argc, argv)); if (ToValue(pv)) pv = VpCopy(NULL, pv); pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv); return pv->obj; diff --git a/ext/dl/cptr.c b/ext/dl/cptr.c index 3f8858c4b37c2e..d34309379bbf58 100644 --- a/ext/dl/cptr.c +++ b/ext/dl/cptr.c @@ -49,6 +49,7 @@ dlptr_free(void *ptr) (*(data->free))(data->ptr); } } + xfree(ptr); } static size_t diff --git a/ext/dl/handle.c b/ext/dl/handle.c index ef182e816fc971..6b90e089eef82d 100644 --- a/ext/dl/handle.c +++ b/ext/dl/handle.c @@ -38,6 +38,7 @@ dlhandle_free(void *ptr) if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){ dlclose(dlhandle->ptr); } + xfree(ptr); } static size_t diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c index 330dbafe67cf03..36970a22486781 100644 --- a/ext/fiddle/handle.c +++ b/ext/fiddle/handle.c @@ -40,6 +40,7 @@ fiddle_handle_free(void *ptr) if( fiddle_handle->ptr && fiddle_handle->open && fiddle_handle->enable_close ){ dlclose(fiddle_handle->ptr); } + xfree(ptr); } static size_t diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c index 0129363a8df2de..b763a0c12372b6 100644 --- a/ext/fiddle/pointer.c +++ b/ext/fiddle/pointer.c @@ -56,6 +56,7 @@ fiddle_ptr_free(void *ptr) (*(data->free))(data->ptr); } } + xfree(ptr); } static size_t diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 3961d3ea33424c..50f1db7cf790c6 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -311,10 +311,11 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args) else msg = ERR_reason_error_string(e); if (NIL_P(str)) { - str = rb_str_new_cstr(msg); + if (msg) str = rb_str_new_cstr(msg); } else { - rb_str_cat2(rb_str_cat2(str, ": "), msg); + if (RSTRING_LEN(str)) rb_str_cat2(str, ": "); + rb_str_cat2(str, msg ? msg : "(null)"); } } if (dOSSL == Qtrue){ /* show all errors on the stack */ diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 0004d9d9b5e941..878b221270afd5 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -318,13 +318,16 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) { EVP_PKEY *pkey; EVP_MD_CTX ctx; + int result; GetPKey(self, pkey); - EVP_VerifyInit(&ctx, GetDigestPtr(digest)); StringValue(sig); StringValue(data); + EVP_VerifyInit(&ctx, GetDigestPtr(digest)); EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data)); - switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) { + result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey); + EVP_MD_CTX_cleanup(&ctx); + switch (result) { case 0: return Qfalse; case 1: diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index 4b422f56449b38..329514a930a005 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -21,7 +21,7 @@ # # Psych is a YAML parser and emitter. # Psych leverages libyaml [Home page: http://pyyaml.org/wiki/LibYAML] -# or [Git repo: https://github.com/zerotao/libyaml] for its YAML parsing +# or [HG repo: https://bitbucket.org/xi/libyaml] for its YAML parsing # and emitting capabilities. In addition to wrapping libyaml, Psych also # knows how to serialize and de-serialize most Ruby objects to and from # the YAML format. @@ -217,7 +217,7 @@ module Psych # The version is Psych you're using - VERSION = '2.0.3' + VERSION = '2.0.5' # The version of libyaml Psych is using LIBYAML_VERSION = Psych.libyaml_version.join '.' diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index 1bfffb952f1c5f..5c3baa5b68fd65 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -75,6 +75,8 @@ def deserialize o class_loader.date_time require 'date' @ss.parse_time(o.value).to_datetime + when '!ruby/encoding' + ::Encoding.find o.value when "!ruby/object:Complex" class_loader.complex Complex(o.value) diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index f89fcbb8f12c3e..ff0fcd204c8a45 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -157,6 +157,11 @@ def visit_Psych_Omap o @emitter.end_sequence end + def visit_Encoding o + tag = "!ruby/encoding" + @emitter.scalar o.name, nil, tag, false, false, Nodes::Scalar::ANY + end + def visit_Object o tag = Psych.dump_tags[o.class] unless tag diff --git a/ext/psych/psych.gemspec b/ext/psych/psych.gemspec index 100b6ff73720ad..6d53aef12241fb 100644 --- a/ext/psych/psych.gemspec +++ b/ext/psych/psych.gemspec @@ -2,12 +2,12 @@ Gem::Specification.new do |s| s.name = "psych" - s.version = "2.0.3" + s.version = "2.0.5" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Aaron Patterson"] - s.date = "2014-02-04" + s.date = "2014-03-27" s.description = "Psych is a YAML parser and emitter. Psych leverages libyaml[http://pyyaml.org/wiki/LibYAML]\nfor its YAML parsing and emitting capabilities. In addition to wrapping\nlibyaml, Psych also knows how to serialize and de-serialize most Ruby objects\nto and from the YAML format." s.email = ["aaron@tenderlovemaking.com"] s.extensions = ["ext/psych/extconf.rb"] @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.rdoc_options = ["--main", "README.rdoc"] s.required_ruby_version = Gem::Requirement.new(">= 1.9.2") s.rubyforge_project = "psych" - s.rubygems_version = "2.2.1" + s.rubygems_version = "2.2.2" s.summary = "Psych is a YAML parser and emitter" s.test_files = ["test/psych/handlers/test_recorder.rb", "test/psych/json/test_stream.rb", "test/psych/nodes/test_enumerable.rb", "test/psych/test_alias_and_anchor.rb", "test/psych/test_array.rb", "test/psych/test_boolean.rb", "test/psych/test_class.rb", "test/psych/test_coder.rb", "test/psych/test_date_time.rb", "test/psych/test_deprecated.rb", "test/psych/test_document.rb", "test/psych/test_emitter.rb", "test/psych/test_encoding.rb", "test/psych/test_engine_manager.rb", "test/psych/test_exception.rb", "test/psych/test_hash.rb", "test/psych/test_json_tree.rb", "test/psych/test_merge_keys.rb", "test/psych/test_nil.rb", "test/psych/test_null.rb", "test/psych/test_numeric.rb", "test/psych/test_object.rb", "test/psych/test_object_references.rb", "test/psych/test_omap.rb", "test/psych/test_parser.rb", "test/psych/test_psych.rb", "test/psych/test_safe_load.rb", "test/psych/test_scalar.rb", "test/psych/test_scalar_scanner.rb", "test/psych/test_serialize_subclasses.rb", "test/psych/test_set.rb", "test/psych/test_stream.rb", "test/psych/test_string.rb", "test/psych/test_struct.rb", "test/psych/test_symbol.rb", "test/psych/test_tainted.rb", "test/psych/test_to_yaml_properties.rb", "test/psych/test_tree_builder.rb", "test/psych/test_yaml.rb", "test/psych/test_yamldbm.rb", "test/psych/test_yamlstore.rb", "test/psych/visitors/test_depth_first.rb", "test/psych/visitors/test_emitter.rb", "test/psych/visitors/test_to_ruby.rb", "test/psych/visitors/test_yaml_tree.rb"] end diff --git a/ext/psych/yaml/config.h b/ext/psych/yaml/config.h index fb62651340416d..f54c27d339e1c4 100644 --- a/ext/psych/yaml/config.h +++ b/ext/psych/yaml/config.h @@ -1,11 +1,10 @@ - #define PACKAGE_NAME "yaml" #define PACKAGE_TARNAME "yaml" -#define PACKAGE_VERSION "0.1.5" -#define PACKAGE_STRING "yaml 0.1.5" +#define PACKAGE_VERSION "0.1.6" +#define PACKAGE_STRING "yaml 0.1.6" #define PACKAGE_BUGREPORT "http://pyyaml.org/newticket?component libyaml" #define PACKAGE_URL "" #define YAML_VERSION_MAJOR 0 #define YAML_VERSION_MINOR 1 -#define YAML_VERSION_PATCH 5 -#define YAML_VERSION_STRING "0.1.5" +#define YAML_VERSION_PATCH 6 +#define YAML_VERSION_STRING "0.1.6" diff --git a/ext/psych/yaml/scanner.c b/ext/psych/yaml/scanner.c index 34308d5d4540d7..af05766f5cc7b6 100644 --- a/ext/psych/yaml/scanner.c +++ b/ext/psych/yaml/scanner.c @@ -2629,6 +2629,9 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, /* Check if it is a URI-escape sequence. */ if (CHECK(parser->buffer, '%')) { + if (!STRING_EXTEND(parser, string)) + goto error; + if (!yaml_parser_scan_uri_escapes(parser, directive, start_mark, &string)) goto error; } diff --git a/ext/psych/yaml/yaml_private.h b/ext/psych/yaml/yaml_private.h index cd3d3a56c4b4e6..944499c94eb9dc 100644 --- a/ext/psych/yaml/yaml_private.h +++ b/ext/psych/yaml/yaml_private.h @@ -146,9 +146,12 @@ yaml_string_join( (string).start = (string).pointer = (string).end = 0) #define STRING_EXTEND(context,string) \ - (((string).pointer+5 < (string).end) \ + ((((string).pointer+5 < (string).end) \ || yaml_string_extend(&(string).start, \ - &(string).pointer, &(string).end)) + &(string).pointer, &(string).end)) ? \ + 1 : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) #define CLEAR(context,string) \ ((string).pointer = (string).start, \ diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb index 3317e2fe837c40..8c3bffc26e23be 100644 --- a/ext/readline/extconf.rb +++ b/ext/readline/extconf.rb @@ -99,9 +99,6 @@ def readline.have_type(type) readline.have_func("rl_insert_text") readline.have_func("rl_delete_text") unless readline.have_type("rl_hook_func_t*") - # rl_hook_func_t is available since readline-4.2 (2001). - # Function is removed at readline-6.3 (2014). - # However, editline (NetBSD 6.1.3, 2014) doesn't have rl_hook_func_t. $defs << "-Drl_hook_func_t=Function" end diff --git a/gc.c b/gc.c index 4df9dfe5fe0380..62a49a55b39168 100644 --- a/gc.c +++ b/gc.c @@ -151,8 +151,8 @@ typedef struct { } ruby_gc_params_t; static ruby_gc_params_t gc_params = { - GC_HEAP_FREE_SLOTS, GC_HEAP_INIT_SLOTS, + GC_HEAP_FREE_SLOTS, GC_HEAP_GROWTH_FACTOR, GC_HEAP_GROWTH_MAX_SLOTS, GC_HEAP_OLDOBJECT_LIMIT_FACTOR, @@ -2926,7 +2926,7 @@ gc_before_sweep(rb_objspace_t *objspace) malloc_limit = (size_t)(inc * gc_params.malloc_limit_growth_factor); if (gc_params.malloc_limit_max > 0 && /* ignore max-check if 0 */ malloc_limit > gc_params.malloc_limit_max) { - malloc_limit = inc; + malloc_limit = gc_params.malloc_limit_max; } } else { @@ -3012,7 +3012,6 @@ gc_after_sweep(rb_objspace_t *objspace) /* if heap_pages has unused pages, then assign them to increment */ if (heap_pages_increment < heap_tomb->page_length) { heap_pages_increment = heap_tomb->page_length; - heap_pages_expand_sorted(objspace); } #if RGENGC_PROFILE > 0 @@ -4769,20 +4768,9 @@ rb_gc_writebarrier(VALUE a, VALUE b) rb_objspace_t *objspace = &rb_objspace; if (!rgengc_remembered(objspace, a)) { - int type = BUILTIN_TYPE(a); - /* TODO: 2 << 16 is just a magic number. */ - if ((type == T_ARRAY && RARRAY_LEN(a) >= 2 << 16) || - (type == T_HASH && RHASH_SIZE(a) >= 2 << 16)) { - if (!rgengc_remembered(objspace, b)) { - rgengc_report(2, objspace, "rb_gc_wb: %p (%s) -> %p (%s)\n", (void *)a, obj_type_name(a), (void *)b, obj_type_name(b)); - rgengc_remember(objspace, b); - } - } - else { - rgengc_report(2, objspace, "rb_gc_wb: %p (%s) -> %p (%s)\n", - (void *)a, obj_type_name(a), (void *)b, obj_type_name(b)); - rgengc_remember(objspace, a); - } + rgengc_report(2, objspace, "rb_gc_wb: %p (%s) -> %p (%s)\n", + (void *)a, obj_type_name(a), (void *)b, obj_type_name(b)); + rgengc_remember(objspace, a); } } } diff --git a/proc.c b/proc.c index 78851ac54749f1..e3cecb7bbe898a 100644 --- a/proc.c +++ b/proc.c @@ -825,10 +825,11 @@ proc_arity(VALUE self) static inline int rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max) { - *max = (iseq->arg_rest == -1 && iseq->arg_keyword == -1) ? - iseq->argc + iseq->arg_post_len + iseq->arg_opts - (iseq->arg_opts > 0) + *max = iseq->arg_rest == -1 ? + iseq->argc + iseq->arg_post_len + iseq->arg_opts - + (iseq->arg_opts > 0) + (iseq->arg_keyword != -1) : UNLIMITED_ARGUMENTS; - return iseq->argc + iseq->arg_post_len; + return iseq->argc + iseq->arg_post_len + (iseq->arg_keyword_required > 0); } static int diff --git a/test/dl/test_cptr.rb b/test/dl/test_cptr.rb index c3793859d714a0..aa74a73fe54fb2 100644 --- a/test/dl/test_cptr.rb +++ b/test/dl/test_cptr.rb @@ -219,4 +219,8 @@ def test_null_pointer assert_raise(DLError) {nullpo[0] = 1} end end + + def test_no_memory_leak + assert_no_memory_leak(%w[-W0 -rdl.so], '', '100_000.times {DL::CPtr.allocate}', rss: true) + end end diff --git a/test/dl/test_handle.rb b/test/dl/test_handle.rb index 83b8af196041f9..6a8964e9a0aebc 100644 --- a/test/dl/test_handle.rb +++ b/test/dl/test_handle.rb @@ -184,4 +184,8 @@ def test_dlerror DL.dlopen("/lib/libc.so.7").sym('strcpy') end if /freebsd/=~ RUBY_PLATFORM end + + def test_no_memory_leak + assert_no_memory_leak(%w[-W0 -rdl.so], '', '100_000.times {DL::Handle.allocate}; GC.start', rss: true) + end end diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb index c598cc33a2cb09..cde3fa816dcef9 100644 --- a/test/fiddle/test_handle.rb +++ b/test/fiddle/test_handle.rb @@ -1,5 +1,6 @@ begin require_relative 'helper' + require_relative '../ruby/envutil' rescue LoadError end @@ -7,6 +8,8 @@ module Fiddle class TestHandle < TestCase include Fiddle + include Test::Unit::Assertions + def test_to_i handle = Fiddle::Handle.new(LIBC_SO) assert_kind_of Integer, handle.to_i @@ -185,5 +188,9 @@ def test_dlerror Socket.gethostbyname("localhost") Fiddle.dlopen("/lib/libc.so.7").sym('strcpy') end if /freebsd/=~ RUBY_PLATFORM + + def test_no_memory_leak + assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Handle.allocate}; GC.start', rss: true) + end end end if defined?(Fiddle) diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb index 1d908f64d9a61b..2ba11b4ed7c808 100644 --- a/test/fiddle/test_pointer.rb +++ b/test/fiddle/test_pointer.rb @@ -230,5 +230,9 @@ def test_null_pointer assert_raise(DLError) {nullpo[0]} assert_raise(DLError) {nullpo[0] = 1} end + + def test_no_memory_leak + assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Pointer.allocate}', rss: true) + end end end if defined?(Fiddle) diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb index 1881525c02e900..ce9bd60c2f1519 100644 --- a/test/openssl/test_pkey_rsa.rb +++ b/test/openssl/test_pkey_rsa.rb @@ -75,6 +75,36 @@ def test_sign_verify assert(key.verify(digest, sig, data)) end + def test_sign_verify_memory_leak + bug9743 = '[ruby-core:62038] [Bug #9743]' + assert_no_memory_leak(%w[-ropenssl], <<-PREP, <<-CODE, bug9743, rss: true) + data = 'Sign me!' + digest = OpenSSL::Digest::SHA512.new + pkey = OpenSSL::PKey::RSA.new(2048) + signature = pkey.sign(digest, data) + pub_key = pkey.public_key + PREP + 20_000.times { + pub_key.verify(digest, signature, data) + } + CODE + + assert_no_memory_leak(%w[-ropenssl], <<-PREP, <<-CODE, bug9743, rss: true) + data = 'Sign me!' + digest = OpenSSL::Digest::SHA512.new + pkey = OpenSSL::PKey::RSA.new(2048) + signature = pkey.sign(digest, data) + pub_key = pkey.public_key + PREP + 20_000.times { + begin + pub_key.verify(digest, signature, 1) + rescue TypeError + end + } + CODE + end + def test_digest_state_irrelevant_sign key = OpenSSL::TestUtils::TEST_KEY_RSA1024 digest1 = OpenSSL::Digest::SHA1.new diff --git a/test/psych/test_encoding.rb b/test/psych/test_encoding.rb index e370606c77160a..517cae20692de3 100644 --- a/test/psych/test_encoding.rb +++ b/test/psych/test_encoding.rb @@ -31,6 +31,11 @@ def setup @emitter = Psych::Emitter.new @buffer end + def test_dump_load_encoding_object + assert_cycle Encoding::US_ASCII + assert_cycle Encoding::UTF_8 + end + def test_transcode_shiftjis str = "こんにちは!" loaded = Psych.load("--- こんにちは!".encode('SHIFT_JIS')) diff --git a/test/ruby/envutil.rb b/test/ruby/envutil.rb index 079658bfbda6e2..de66102621cebd 100644 --- a/test/ruby/envutil.rb +++ b/test/ruby/envutil.rb @@ -372,7 +372,8 @@ def assert_warn(*args) assert_warning(*args) {$VERBOSE = false; yield} end - def assert_no_memory_leak(args, prepare, code, message=nil, limit: 1.5, **opt) + def assert_no_memory_leak(args, prepare, code, message=nil, limit: 1.5, rss: false, **opt) + require_relative 'memory_status' token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m" token_dump = token.dump token_re = Regexp.quote(token) @@ -385,16 +386,23 @@ def assert_no_memory_leak(args, prepare, code, message=nil, limit: 1.5, **opt) ] args.unshift(envs) if envs cmd = [ - 'END {STDERR.puts '"#{token_dump}"'"FINAL=#{Memory::Status.new.size}"}', + 'END {STDERR.puts '"#{token_dump}"'"FINAL=#{Memory::Status.new}"}', prepare, - 'STDERR.puts('"#{token_dump}"'"START=#{$initial_size = Memory::Status.new.size}")', + 'STDERR.puts('"#{token_dump}"'"START=#{$initial_status = Memory::Status.new}")', + '$initial_size = $initial_status.size', code, + 'GC.start', ].join("\n") _, err, status = EnvUtil.invoke_ruby(args, cmd, true, true, **opt) - before = err.sub!(/^#{token_re}START=(\d+)\n/, '') && $1.to_i - after = err.sub!(/^#{token_re}FINAL=(\d+)\n/, '') && $1.to_i + before = err.sub!(/^#{token_re}START=(\{.*\})\n/, '') && Memory::Status.parse($1) + after = err.sub!(/^#{token_re}FINAL=(\{.*\})\n/, '') && Memory::Status.parse($1) assert_equal([true, ""], [status.success?, err], message) - assert_operator(after.fdiv(before), :<, limit, message) + ([:size, (rss && :rss)] & after.members).each do |n| + b = before[n] + a = after[n] + next unless a > 0 and b > 0 + assert_operator(a.fdiv(b), :<, limit, message(message) {"#{n}: #{b} => #{a}"}) + end end def assert_is_minus_zero(f) diff --git a/test/ruby/memory_status.rb b/test/ruby/memory_status.rb index cb2e9e094c030b..bfbfbd6e880b06 100644 --- a/test/ruby/memory_status.rb +++ b/test/ruby/memory_status.rb @@ -1,5 +1,3 @@ -require_relative "envutil" - module Memory keys = [] vals = [] @@ -110,5 +108,20 @@ class Status def initialize _update end + + def to_s + status = each_pair.map {|n,v| + "#{n}:#{v}" + } + "{#{status.join(",")}}" + end + + def self.parse(str) + status = allocate + str.scan(/(?:\A\{|\G,)(#{members.join('|')}):(\d+)(?=,|\}\z)/) do + status[$1] = $2.to_i + end + status + end end end diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index c644aa5d9a2e81..402d560bff8b9c 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -244,7 +244,7 @@ def test_profiler_total_time GC::Profiler.clear GC.start - assert_operator(GC::Profiler.total_time, :>, 0) + assert_operator(GC::Profiler.total_time, :>=, 0) ensure GC::Profiler.disable end diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb index 206e21fb1a8bfd..1c8a053cca84fe 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -77,14 +77,19 @@ def test_arity assert_equal(2, proc{|(x, y), z|[x,y]}.arity) assert_equal(1, proc{|(x, y), z=0|[x,y]}.arity) assert_equal(-4, proc{|x, *y, z, a|}.arity) - assert_equal(-1, proc{|**|}.arity) - assert_equal(-1, proc{|**o|}.arity) - assert_equal(-2, proc{|x, **o|}.arity) - assert_equal(-1, proc{|x=0, **o|}.arity) - assert_equal(-2, proc{|x, y=0, **o|}.arity) - assert_equal(-3, proc{|x, y=0, z, **o|}.arity) + assert_equal(0, proc{|**|}.arity) + assert_equal(0, proc{|**o|}.arity) + assert_equal(1, proc{|x, **o|}.arity) + assert_equal(0, proc{|x=0, **o|}.arity) + assert_equal(1, proc{|x, y=0, **o|}.arity) + assert_equal(2, proc{|x, y=0, z, **o|}.arity) assert_equal(-3, proc{|x, y=0, *z, w, **o|}.arity) + assert_equal(2, proc{|x, y=0, z, a:1|}.arity) + assert_equal(3, proc{|x, y=0, z, a:|}.arity) + assert_equal(-4, proc{|x, y, *rest, a:, b:, c:|}.arity) + assert_equal(3, proc{|x, y=0, z, a:, **o|}.arity) + assert_equal(0, lambda{}.arity) assert_equal(0, lambda{||}.arity) assert_equal(1, lambda{|x|}.arity) diff --git a/thread_pthread.c b/thread_pthread.c index aa8962a315fc5f..aa2c49e949ab9d 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1422,11 +1422,9 @@ timer_thread_sleep(rb_global_vm_lock_t* unused) #endif /* USE_SLEEPY_TIMER_THREAD */ #if defined(__linux__) && defined(PR_SET_NAME) +# undef SET_THREAD_NAME # define SET_THREAD_NAME(name) prctl(PR_SET_NAME, name) -#elif defined(HAVE_PTHREAD_SETNAME_NP) -/* pthread_setname_np() on Darwin does not have target thread argument */ -# define SET_THREAD_NAME(name) pthread_setname_np(name) -#else +#elif !defined(SET_THREAD_NAME) # define SET_THREAD_NAME(name) (void)0 #endif diff --git a/tool/make-snapshot b/tool/make-snapshot index 962ac07d9d9196..68ffd3b2fc3422 100755 --- a/tool/make-snapshot +++ b/tool/make-snapshot @@ -116,8 +116,14 @@ def package(rev, destdir) patchlevel = true tag = "p#{$4}" url = SVNURL + "tags/v#{$1}_#{$2}_#{$3}_#{$4}" - when /\./ - url = SVNURL + "branches/ruby_#{rev.tr('.', '_')}" + when /\A(\d+)\.(\d+)\.(\d+)\z/ + if $1 > "2" || $1 == "2" && $2 >= "1" + patchlevel = true + tag = "" + url = SVNURL + "tags/v#{$1}_#{$2}_#{$3}" + else + url = SVNURL + "branches/ruby_#{rev.tr('.', '_')}" + end else warn "#{$0}: unknown version - #{rev}" return @@ -160,14 +166,20 @@ def package(rev, destdir) version ||= (versionhdr = IO.read("#{v}/version.h"))[RUBY_VERSION_PATTERN, 1] version or return if patchlevel - versionhdr ||= IO.read("#{v}/version.h") - patchlevel = versionhdr[/^\#define\s+RUBY_PATCHLEVEL\s+(\d+)/, 1] - tag = (patchlevel ? "p#{patchlevel}" : "r#{revision}") + unless tag.empty? + versionhdr ||= IO.read("#{v}/version.h") + patchlevel = versionhdr[/^\#define\s+RUBY_PATCHLEVEL\s+(\d+)/, 1] + tag = (patchlevel ? "p#{patchlevel}" : "r#{revision}") + end else tag ||= "r#{revision}" end unless v == $exported - n = "ruby-#{version}-#{tag}" + if tag.empty? + n = "ruby-#{version}" + else + n = "ruby-#{version}-#{tag}" + end File.directory?(n) or File.rename v, n v = n end @@ -177,7 +189,11 @@ def package(rev, destdir) Dir.chdir(v) do %w[config.guess config.sub].each do |conf| next if File.exist?("tool/#{conf}") - require File.expand_path("config_files", $tooldir) + begin + require File.expand_path("config_files", $tooldir) + rescue LoadError + abort "Error!!! Copy 'config_files.rb' from 'tool' directory of the recent ruby repository!" + end ConfigFiles.download(conf, "tool") end File.open(clean.add("cross.rb"), "w") do |f| @@ -205,6 +221,7 @@ def package(rev, destdir) f.puts "s,@ARCH_FLAG@,|#_!!_#|,g" f.puts "s,@CFLAGS@,|#_!!_#|,g" f.puts "s,@CPPFLAGS@,|#_!!_#|,g" + f.puts "s,@CXXFLAGS@,|#_!!_#|,g" f.puts "s,@LDFLAGS@,|#_!!_#|,g" f.puts "s,@DLDFLAGS@,|#_!!_#|,g" f.puts "s,@LIBEXT@,|#_!!_#|a,g" diff --git a/version.h b/version.h index e8e07e0109357e..5702aec34c0701 100644 --- a/version.h +++ b/version.h @@ -1,10 +1,10 @@ -#define RUBY_VERSION "2.1.1" -#define RUBY_RELEASE_DATE "2014-02-24" -#define RUBY_PATCHLEVEL 76 +#define RUBY_VERSION "2.1.2" +#define RUBY_RELEASE_DATE "2014-05-08" +#define RUBY_PATCHLEVEL 95 #define RUBY_RELEASE_YEAR 2014 -#define RUBY_RELEASE_MONTH 2 -#define RUBY_RELEASE_DAY 24 +#define RUBY_RELEASE_MONTH 5 +#define RUBY_RELEASE_DAY 8 #include "ruby/version.h"