diff --git a/SOURCES/ruby-2.2.3-vm_args.c-protect-value-stack-from-calling-other-met.patch b/SOURCES/ruby-2.2.3-vm_args.c-protect-value-stack-from-calling-other-met.patch new file mode 100644 index 0000000..99dc5a9 --- /dev/null +++ b/SOURCES/ruby-2.2.3-vm_args.c-protect-value-stack-from-calling-other-met.patch @@ -0,0 +1,239 @@ +From 3e199f4c2b49a17104a0878f8e8505ab2411a608 Mon Sep 17 00:00:00 2001 +From: nagachika +Date: Wed, 20 May 2015 16:04:34 +0000 +Subject: [PATCH] merge revision(s) 50172,50173: [Backport #11027] + + * vm_args.c: protect value stack from calling other methods + during complex parameter setting process (splat, kw, and so on). + [Bug #11027] + + * vm_core.h: remove rb_thead_t::mark_stack_len. + With this modification, we don't need to use th->mark_stack_len. + + * test/ruby/test_keyword.rb: add a test. + + * cont.c (cont_capture): catch up this fix. + + * vm.c (rb_thread_mark): ditto. + + +git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@50562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e +--- + ChangeLog | 15 +++++++++++++++ + cont.c | 2 +- + test/ruby/test_keyword.rb | 10 ++++++++++ + vm.c | 1 - + vm_args.c | 44 +++++++++++++++++++++++++++++--------------- + vm_core.h | 1 - + 6 files changed, 55 insertions(+), 18 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 308d5eb..d0b4cdd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,18 @@ ++Thu May 21 00:55:45 2015 Koichi Sasada ++ ++ * vm_args.c: protect value stack from calling other methods ++ during complex parameter setting process (splat, kw, and so on). ++ [Bug #11027] ++ ++ * vm_core.h: remove rb_thead_t::mark_stack_len. ++ With this modification, we don't need to use th->mark_stack_len. ++ ++ * test/ruby/test_keyword.rb: add a test. ++ ++ * cont.c (cont_capture): catch up this fix. ++ ++ * vm.c (rb_thread_mark): ditto. ++ + Mon Apr 13 22:11:21 2015 CHIKANAGA Tomoyuki + + * ext/openssl/lib/openssl/ssl.rb: stricter hostname verification +diff --git a/cont.c b/cont.c +index 78ae089..22e0c5a 100644 +--- a/cont.c ++++ b/cont.c +@@ -490,7 +490,7 @@ cont_capture(volatile int *stat) + contval = cont->self; + + #ifdef CAPTURE_JUST_VALID_VM_STACK +- cont->vm_stack_slen = th->cfp->sp + th->mark_stack_len - th->stack; ++ cont->vm_stack_slen = th->cfp->sp - th->stack; + cont->vm_stack_clen = th->stack + th->stack_size - (VALUE*)th->cfp; + cont->vm_stack = ALLOC_N(VALUE, cont->vm_stack_slen + cont->vm_stack_clen); + MEMCPY(cont->vm_stack, th->stack, VALUE, cont->vm_stack_slen); +diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb +index 70cdba1..9c76e15 100644 +--- a/test/ruby/test_keyword.rb ++++ b/test/ruby/test_keyword.rb +@@ -566,4 +566,14 @@ def test_nonsymbol_key + result = m(["a" => 10]) { |a = nil, **b| [a, b] } + assert_equal([{"a" => 10}, {}], result) + end ++ ++ def method_for_test_to_hash_call_during_setup_complex_parameters k1:, k2:, **rest_kw ++ [k1, k2, rest_kw] ++ end ++ ++ def test_to_hash_call_during_setup_complex_parameters ++ sym = "sym_#{Time.now}".to_sym ++ h = method_for_test_to_hash_call_during_setup_complex_parameters k1: "foo", k2: "bar", sym => "baz" ++ assert_equal ["foo", "bar", {sym => "baz"}], h, '[Bug #11027]' ++ end + end +diff --git a/vm.c b/vm.c +index ca70d46..e0b536d 100644 +--- a/vm.c ++++ b/vm.c +@@ -2015,7 +2015,6 @@ rb_thread_mark(void *ptr) + rb_control_frame_t *limit_cfp = (void *)(th->stack + th->stack_size); + + rb_gc_mark_values((long)(sp - p), p); +- rb_gc_mark_locations(sp, sp + th->mark_stack_len); + + while (cfp != limit_cfp) { + rb_iseq_t *iseq = cfp->iseq; +diff --git a/vm_args.c b/vm_args.c +index 446ad48..abdd161 100644 +--- a/vm_args.c ++++ b/vm_args.c +@@ -83,19 +83,17 @@ args_reduce(struct args_info *args, int over_argc) + } + + static inline int +-args_check_block_arg0(struct args_info *args, rb_thread_t *th, const int msl) ++args_check_block_arg0(struct args_info *args, rb_thread_t *th) + { + VALUE ary = Qnil; + + if (args->rest && RARRAY_LEN(args->rest) == 1) { + VALUE arg0 = RARRAY_AREF(args->rest, 0); + ary = rb_check_array_type(arg0); +- th->mark_stack_len = msl; + } + else if (args->argc == 1) { + VALUE arg0 = args->argv[0]; + ary = rb_check_array_type(arg0); +- th->mark_stack_len = msl; + args->argv[0] = arg0; /* see: https://bugs.ruby-lang.org/issues/8484 */ + } + +@@ -173,10 +171,9 @@ args_rest_array(struct args_info *args) + } + + static int +-keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th, const int msl) ++keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th) + { + *rest_hash_ptr = rb_check_hash_type(*kw_hash_ptr); +- th->mark_stack_len = msl; + + if (!NIL_P(*rest_hash_ptr)) { + VALUE hash = rb_extract_keywords(rest_hash_ptr); +@@ -191,7 +188,7 @@ keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th, const + } + + static VALUE +-args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *th, const int msl) ++args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *th) + { + VALUE rest_hash; + +@@ -200,7 +197,7 @@ args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *t + assert(args->argc > 0); + *kw_hash_ptr = args->argv[args->argc-1]; + +- if (keyword_hash_p(kw_hash_ptr, &rest_hash, th, msl)) { ++ if (keyword_hash_p(kw_hash_ptr, &rest_hash, th)) { + if (rest_hash) { + args->argv[args->argc-1] = rest_hash; + } +@@ -216,7 +213,7 @@ args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *t + if (len > 0) { + *kw_hash_ptr = RARRAY_AREF(args->rest, len - 1); + +- if (keyword_hash_p(kw_hash_ptr, &rest_hash, th, msl)) { ++ if (keyword_hash_p(kw_hash_ptr, &rest_hash, th)) { + if (rest_hash) { + RARRAY_ASET(args->rest, len - 1, rest_hash); + } +@@ -511,9 +508,27 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r + int given_argc; + struct args_info args_body, *args; + VALUE keyword_hash = Qnil; +- const int msl = ci->argc + iseq->param.size; ++ VALUE * const orig_sp = th->cfp->sp; ++ int i; + +- th->mark_stack_len = msl; ++ /* ++ * Extend SP for GC. ++ * ++ * [pushed values] [uninitialized values] ++ * <- ci->argc --> ++ * <- iseq->param.size------------------> ++ * ^ locals ^ sp ++ * ++ * => ++ * [pushed values] [initialized values ] ++ * <- ci->argc --> ++ * <- iseq->param.size------------------> ++ * ^ locals ^ sp ++ */ ++ for (i=ci->argc; iparam.size; i++) { ++ locals[i] = Qnil; ++ } ++ th->cfp->sp = &locals[i]; + + /* setup args */ + args = &args_body; +@@ -556,7 +571,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r + (min_argc > 0 || iseq->param.opt_num > 1 || + iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) && + !iseq->param.flags.ambiguous_param0 && +- args_check_block_arg0(args, th, msl)) { ++ args_check_block_arg0(args, th)) { + given_argc = RARRAY_LENINT(args->rest); + } + break; +@@ -564,7 +579,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r + if (given_argc == 1 && + given_argc != iseq->param.lead_num && + !iseq->param.flags.has_rest && +- args_check_block_arg0(args, th, msl)) { ++ args_check_block_arg0(args, th)) { + given_argc = RARRAY_LENINT(args->rest); + } + } +@@ -590,7 +605,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r + if (given_argc > min_argc && + (iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) && + args->kw_argv == NULL) { +- if (args_pop_keyword_hash(args, &keyword_hash, th, msl)) { ++ if (args_pop_keyword_hash(args, &keyword_hash, th)) { + given_argc--; + } + } +@@ -662,8 +677,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r + } + #endif + +- th->mark_stack_len = 0; +- ++ th->cfp->sp = orig_sp; + return opt_pc; + } + +diff --git a/vm_core.h b/vm_core.h +index b61aea7..9079130 100644 +--- a/vm_core.h ++++ b/vm_core.h +@@ -642,7 +642,6 @@ typedef struct rb_thread_struct { + enum rb_thread_status status; + int to_kill; + int priority; +- int mark_stack_len; + + native_thread_data_t native_thread_data; + void *blocking_region_buffer; diff --git a/SPECS/ruby.spec b/SPECS/ruby.spec index 012070f..4655818 100644 --- a/SPECS/ruby.spec +++ b/SPECS/ruby.spec @@ -24,7 +24,7 @@ %endif -%global release 15 +%global release 16 %{!?release_string:%global release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}} %global rubygems_version 2.4.5 @@ -128,6 +128,10 @@ Patch9: ruby-2.2.3-dsym_fstrs-for-object-allocation-gc-phase.patch # Fix "dh key too small" error of OpenSSL 1.0.2c+. # https://github.com/rubygems/rubygems/issues/1289 Patch10: ruby-2.3.0-test_gem_remote_fetcher.rb-get-rid-of-errors.patch +# Fix named argument assignment from hash failure +# https://bugzilla.redhat.com/show_bug.cgi?id=1369090 +# https://bugs.ruby-lang.org/issues/11027 +Patch11: ruby-2.2.3-vm_args.c-protect-value-stack-from-calling-other-met.patch Requires: %{?scl_prefix}%{pkg_name}-libs%{?_isa} = %{version}-%{release} Requires: %{?scl_prefix}ruby(rubygems) >= %{rubygems_version} @@ -436,6 +440,7 @@ rm -rf ext/fiddle/libffi* %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 # Allow to use autoconf 2.63. sed -i '/AC_PREREQ/ s/(.*)/(2.62)/' configure.in @@ -933,6 +938,10 @@ make check TESTS="-v $DISABLE_TESTS" %{ruby_libdir}/tkextlib %changelog +* Mon Oct 31 2016 Vít Ondruch - 2.2.2-16 +- Fix named argument assignment from hash failure. + Resolves: rhbz#1369090 + * Wed Jun 22 2016 Jun Aruga - 2.2.2-15 - Fix for "dh key too small" error of OpenSSL 1.0.2+. Resolves: rhbz#1348918