[前][次][番号順一覧][スレッド一覧]

ruby-changes:54541

From: tenderlove <ko1@a...>
Date: Wed, 9 Jan 2019 04:22:10 +0900 (JST)
Subject: [ruby-changes:54541] tenderlove:r66756 (trunk): Mark array as "going to be modified" in `Array#reject!`

tenderlove	2019-01-09 04:22:05 +0900 (Wed, 09 Jan 2019)

  New Revision: 66756

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66756

  Log:
    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]

  Modified files:
    trunk/array.c
    trunk/test/ruby/test_array.rb
Index: array.c
===================================================================
--- array.c	(revision 66755)
+++ array.c	(revision 66756)
@@ -3540,6 +3540,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L3540
 rb_ary_reject_bang(VALUE ary)
 {
     RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
+    rb_ary_modify(ary);
     return ary_reject_bang(ary);
 }
 
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 66755)
+++ test/ruby/test_array.rb	(revision 66756)
@@ -1308,6 +1308,65 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1308
     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__

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]