diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-10 15:02:21 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-10 15:02:21 +0000 |
commit | 5b23824b1cf98be53f2737467fa1818201690177 (patch) | |
tree | e7e078aa6f9aed25df9ef04c07cb7920c81e113f | |
parent | 4f0899d4bba4a03c4de45e742f9e37a89b8b32e2 (diff) | |
download | ruby-5b23824b1cf98be53f2737467fa1818201690177.tar.gz |
merge revision(s) 66756: [Backport #15479]
Mark array as "going to be modified" in `Array#reject!`
Before this patch, if `reject!` is called on a shared array it can
mutate the shared array rather than a copy. This patch marks the array
as "going to be modified" so that the shared source array isn't
mutated.
[Bug #15479] [ruby-core:90781]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@66784 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | array.c | 1 | ||||
-rw-r--r-- | test/ruby/test_array.rb | 59 | ||||
-rw-r--r-- | version.h | 2 |
3 files changed, 61 insertions, 1 deletions
@@ -3241,6 +3241,7 @@ static VALUE rb_ary_reject_bang(VALUE ary) { RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length); + rb_ary_modify(ary); return ary_reject_bang(ary); } diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 73a0bf24d0..abd8d066fd 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1291,6 +1291,65 @@ class TestArray < Test::Unit::TestCase assert_equal(@cls[7, 8, 9, 10], a, bug2545) end + def test_shared_array_reject! + c = [] + b = [1, 2, 3, 4] + 3.times do + a = b.dup + c << a.dup + + begin + a.reject! do |x| + case x + when 2 then true + when 3 then raise StandardError, 'Oops' + else false + end + end + rescue StandardError + end + + c << a.dup + end + + bug90781 = '[ruby-core:90781]' + assert_equal [[1, 2, 3, 4], + [1, 3, 4], + [1, 2, 3, 4], + [1, 3, 4], + [1, 2, 3, 4], + [1, 3, 4]], c, bug90781 + end + + def test_iseq_shared_array_reject! + c = [] + 3.times do + a = [1, 2, 3, 4] + c << a.dup + + begin + a.reject! do |x| + case x + when 2 then true + when 3 then raise StandardError, 'Oops' + else false + end + end + rescue StandardError + end + + c << a.dup + end + + bug90781 = '[ruby-core:90781]' + assert_equal [[1, 2, 3, 4], + [1, 3, 4], + [1, 2, 3, 4], + [1, 3, 4], + [1, 2, 3, 4], + [1, 3, 4]], c, bug90781 + end + def test_replace a = @cls[ 1, 2, 3] a_id = a.__id__ @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.5.4" #define RUBY_RELEASE_DATE "2019-01-10" -#define RUBY_PATCHLEVEL 127 +#define RUBY_PATCHLEVEL 128 #define RUBY_RELEASE_YEAR 2019 #define RUBY_RELEASE_MONTH 1 |