diff --git a/array.c b/array.c index bcf98fc012..56f3584e1d 100644 --- a/array.c +++ b/array.c @@ -3393,6 +3393,9 @@ rb_ary_sort_bang(VALUE ary) rb_ary_unshare(ary); FL_SET_EMBED(ary); } + if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) { + ary_resize_capa(ary, ARY_EMBED_LEN(tmp)); + } ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp)); ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp)); } diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 6e84bdbd02..9560fca958 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -3556,6 +3556,15 @@ class TestArray < Test::Unit::TestCase assert_equal(10000, eval(lit).size) end + def test_array_safely_modified_by_sort_block + var_0 = (1..70).to_a + var_0.sort! do |var_0_block_129, var_1_block_129| + var_0.pop + var_1_block_129 <=> var_0_block_129 + end.shift(3) + assert_equal((1..67).to_a.reverse, var_0) + end + private def need_continuation unless respond_to?(:callcc, true)