diff --git a/ChangeLog b/ChangeLog index f13688ec18..5df3c64ad5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Jun 12 12:04:09 2013 Nobuyoshi Nakada + + * array.c (rb_ary_uniq_bang): must not be modified once frozen even in + a callback method. + Wed Jun 12 12:03:43 2013 Nobuyoshi Nakada * array.c (rb_ary_sort_bang): must not be modified once frozen even in diff --git a/array.c b/array.c index 9bdbe78d5c..f3076d7cf3 100644 --- a/array.c +++ b/array.c @@ -3981,6 +3981,7 @@ rb_ary_uniq_bang(VALUE ary) if (RARRAY_LEN(ary) == (i = RHASH_SIZE(hash))) { return Qnil; } + rb_ary_modify(ary); ARY_SET_LEN(ary, 0); if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) { rb_ary_unshare(ary); diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 49628215b5..6807598054 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1569,6 +1569,15 @@ class TestArray < Test::Unit::TestCase assert_equal(nil, b) end + def test_uniq_bang_with_freeze + ary = [1,2] + orig = ary.dup + assert_raise(RuntimeError, "frozen during comparison") { + ary.uniq! {|v| ary.freeze; 1} + } + assert_equal(orig, ary, "must not be modified once frozen") + end + def test_unshift a = @cls[] assert_equal(@cls['cat'], a.unshift('cat'))