diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-05-21 18:33:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-21 18:33:56 -0700 |
commit | 8b00bfb7c2c33827490c78a16c44b102cb0d724b (patch) | |
tree | e8d06af25bd9504cf4984002f4bffaac42a777c8 /test/ruby | |
parent | b2fc592c3046e60fdfbb5692d52cc7cbf814b6d0 (diff) |
Do not allow array modifications after freeze inside sort!
If freezing an array inside sort!, previously the array could be
modified after the freeze. This checks whether the receiver is
frozen after every yield and potential call to #> or #<,
preventing modifications if the receiver is frozen inside the
block or by the #> or #< call.
Fixes [Bug #17739]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4335
Merged-By: jeremyevans <code@jeremyevans.net>
Diffstat (limited to 'test/ruby')
-rw-r--r-- | test/ruby/test_array.rb | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index fb50f581fe..0a9ba90564 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1663,6 +1663,36 @@ class TestArray < Test::Unit::TestCase assert_equal([1, 2, 3, 4], a) end + def test_freeze_inside_sort! + array = [1, 2, 3, 4, 5] + frozen_array = nil + assert_raise(FrozenError) do + array.sort! do |a, b| + array.freeze if a == 3 + frozen_array ||= array.map.to_a if array.frozen? + 1 + end + end + assert_equal(frozen_array, array) + + object = Object.new + array = [1, 2, 3, 4, 5] + object.define_singleton_method(:>){|_| array.freeze; true} + assert_raise(FrozenError) do + array.sort! do |a, b| + object + end + end + + object = Object.new + array = [object, object] + object.define_singleton_method(:>){|_| array.freeze; true} + object.define_singleton_method(:<=>){|o| object} + assert_raise(FrozenError) do + array.sort! + end + end + def test_sort_with_callcc need_continuation n = 1000 |