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

ruby-changes:14771

From: nobu <ko1@a...>
Date: Wed, 10 Feb 2010 16:31:26 +0900 (JST)
Subject: [ruby-changes:14771] Ruby:r26632 (trunk): * array.c (rb_ary_push_m, rb_ary_unshift_m, rb_ary_aset),

nobu	2010-02-10 16:31:06 +0900 (Wed, 10 Feb 2010)

  New Revision: 26632

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26632

  Log:
    * array.c (rb_ary_push_m, rb_ary_unshift_m, rb_ary_aset),
      (rb_ary_insert, rb_ary_replace, rb_ary_concat),
      (rb_ary_uniq_bang, rb_ary_flatten_bang): check if frozen after
      wrong number of arguments but before TypeError.
      [ruby-core:28140]
    
    * hash.c (rb_hash_replace): ditto.
    
    * string.c (rb_str_replace): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/hash.c
    trunk/string.c
    trunk/test/ruby/test_array.rb
    trunk/test/ruby/test_hash.rb
    trunk/test/ruby/test_string.rb

Index: array.c
===================================================================
--- array.c	(revision 26631)
+++ array.c	(revision 26632)
@@ -700,6 +700,8 @@
     return ary_make_partial(ary, rb_cArray, offset, n);
 }
 
+static VALUE rb_ary_push_1(VALUE ary, VALUE item);
+
 /*
  *  call-seq:
  *     array << obj            -> array
@@ -716,9 +718,15 @@
 VALUE
 rb_ary_push(VALUE ary, VALUE item)
 {
+    rb_ary_modify(ary);
+    return rb_ary_push_1(ary, item);
+}
+
+static VALUE
+rb_ary_push_1(VALUE ary, VALUE item)
+{
     long idx = RARRAY_LEN(ary);
 
-    rb_ary_modify(ary);
     if (idx >= ARY_CAPA(ary)) {
 	ary_double_capa(ary, idx);
     }
@@ -745,7 +753,7 @@
 {
     rb_ary_modify_check(ary);
     while (argc--) {
-	rb_ary_push(ary, *argv++);
+	rb_ary_push_1(ary, *argv++);
     }
     return ary;
 }
@@ -892,8 +900,8 @@
 {
     long len;
 
+    rb_ary_modify(ary);
     if (argc == 0) return ary;
-    rb_ary_modify(ary);
     if (ARY_CAPA(ary) <= (len = RARRAY_LEN(ary)) + argc) {
 	ary_double_capa(ary, len + argc);
     }
@@ -1321,6 +1329,7 @@
     long offset, beg, len;
 
     if (argc == 3) {
+	rb_ary_modify_check(ary);
 	beg = NUM2LONG(argv[0]);
 	len = NUM2LONG(argv[1]);
 	rb_ary_splice(ary, beg, len, argv[2]);
@@ -1329,6 +1338,7 @@
     if (argc != 2) {
 	rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
     }
+    rb_ary_modify_check(ary);
     if (FIXNUM_P(argv[0])) {
 	offset = FIX2LONG(argv[0]);
 	goto fixnum;
@@ -1362,10 +1372,11 @@
 {
     long pos;
 
-    if (argc == 1) return ary;
     if (argc < 1) {
 	rb_raise(rb_eArgError, "wrong number of arguments (at least 1)");
     }
+    rb_ary_modify_check(ary);
+    if (argc == 1) return ary;
     pos = NUM2LONG(argv[0]);
     if (pos == -1) {
 	pos = RARRAY_LEN(ary);
@@ -2600,8 +2611,8 @@
 VALUE
 rb_ary_replace(VALUE copy, VALUE orig)
 {
+    rb_ary_modify_check(copy);
     orig = to_ary(orig);
-    rb_ary_modify_check(copy);
     if (copy == orig) return copy;
 
     if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
@@ -2794,6 +2805,7 @@
 VALUE
 rb_ary_concat(VALUE x, VALUE y)
 {
+    rb_ary_modify_check(x);
     y = to_ary(y);
     if (RARRAY_LEN(y) > 0) {
 	rb_ary_splice(x, RARRAY_LEN(x), 0, y);
@@ -3301,6 +3313,7 @@
     VALUE hash, v;
     long i, j;
 
+    rb_ary_modify_check(ary);
     if (rb_block_given_p()) {
 	hash = ary_make_hash_by(ary);
 	if (RARRAY_LEN(ary) == (i = RHASH_SIZE(hash))) {
@@ -3547,6 +3560,7 @@
     VALUE result, lv;
 
     rb_scan_args(argc, argv, "01", &lv);
+    rb_ary_modify_check(ary);
     if (!NIL_P(lv)) level = NUM2INT(lv);
     if (level == 0) return Qnil;
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26631)
+++ ChangeLog	(revision 26632)
@@ -1,3 +1,15 @@
+Wed Feb 10 16:31:03 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* array.c (rb_ary_push_m, rb_ary_unshift_m, rb_ary_aset),
+	  (rb_ary_insert, rb_ary_replace, rb_ary_concat),
+	  (rb_ary_uniq_bang, rb_ary_flatten_bang): check if frozen after
+	  wrong number of arguments but before TypeError.
+	  [ruby-core:28140]
+
+	* hash.c (rb_hash_replace): ditto.
+
+	* string.c (rb_str_replace): ditto.
+
 Wed Feb 10 04:06:36 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm.c (vm_exec): reset thread state before starting vm loop.
Index: string.c
===================================================================
--- string.c	(revision 26631)
+++ string.c	(revision 26632)
@@ -3752,6 +3752,7 @@
 VALUE
 rb_str_replace(VALUE str, VALUE str2)
 {
+    str_modifiable(str);
     if (str == str2) return str;
 
     StringValue(str2);
Index: hash.c
===================================================================
--- hash.c	(revision 26631)
+++ hash.c	(revision 26632)
@@ -1073,6 +1073,7 @@
 static VALUE
 rb_hash_replace(VALUE hash, VALUE hash2)
 {
+    rb_hash_modify_check(hash);
     hash2 = to_hash(hash2);
     if (hash == hash2) return hash;
     rb_hash_clear(hash);
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 26631)
+++ test/ruby/test_array.rb	(revision 26632)
@@ -539,6 +539,9 @@
     a = @cls[1, 2, 3]
     a.concat(a)
     assert_equal([1, 2, 3, 1, 2, 3], a)
+
+    assert_raise(TypeError) { [0].concat(:foo) }
+    assert_raise(RuntimeError) { [0].freeze.concat(:foo) }
   end
 
   def test_count
@@ -1033,6 +1036,13 @@
     assert_equal(@cls[4, 5, 6], a)
     assert_equal(a_id, a.__id__)
     assert_equal(@cls[], a.replace(@cls[]))
+
+    fa = a.dup.freeze
+    assert_nothing_raised(RuntimeError) { a.replace(a) }
+    assert_raise(RuntimeError) { fa.replace(fa) }
+    assert_raise(ArgumentError) { fa.replace() }
+    assert_raise(TypeError) { a.replace(42) }
+    assert_raise(RuntimeError) { fa.replace(42) }
   end
 
   def test_reverse
@@ -1325,6 +1335,11 @@
     assert_equal(@cls[ "a:def", "b:abc", "c:jkl" ], c)
 
     assert_nil(@cls[1, 2, 3].uniq!)
+
+    f = a.dup.freeze
+    assert_raise(ArgumentError) { a.uniq!(1) }
+    assert_raise(ArgumentError) { f.uniq!(1) }
+    assert_raise(RuntimeError) { f.uniq! }
   end
 
   def test_unshift
@@ -1452,7 +1467,7 @@
     assert_equal([1, 1, 1], Array.new(3, 1) { 1 })
   end
 
-  def test_aset
+  def test_aset_error
     assert_raise(IndexError) { [0][-2] = 1 }
     assert_raise(IndexError) { [0][LONGP] = 2 }
     assert_raise(IndexError) { [0][(LONGP + 1) / 2 - 1] = 2 }
@@ -1461,6 +1476,9 @@
     a[2] = 4
     assert_equal([0, nil, 4], a)
     assert_raise(ArgumentError) { [0][0, 0, 0] = 0 }
+    assert_raise(ArgumentError) { [0].freeze[0, 0, 0] = 0 }
+    assert_raise(TypeError) { [0][:foo] = 0 }
+    assert_raise(RuntimeError) { [0].freeze[:foo] = 0 }
   end
 
   def test_first2
@@ -1477,8 +1495,9 @@
     assert_equal([2, 3], a)
   end
 
-  def test_unshift2
-    Struct.new(:a, :b, :c)
+  def test_unshift_error
+    assert_raise(RuntimeError) { [].freeze.unshift('cat') }
+    assert_raise(RuntimeError) { [].freeze.unshift() }
   end
 
   def test_aref
@@ -1537,6 +1556,8 @@
     assert_raise(ArgumentError) { a.insert }
     assert_equal([0, 1, 2], a.insert(-1, 2))
     assert_equal([0, 1, 3, 2], a.insert(-2, 3))
+    assert_raise(RuntimeError) { [0].freeze.insert(0)}
+    assert_raise(ArgumentError) { [0].freeze.insert }
   end
 
   def test_join2
@@ -1628,10 +1649,17 @@
     assert_not_equal([a, a].hash, a.hash) # Implementation dependent
   end
 
-  def test_flatten2
+  def test_flatten_error
     a = []
     a << a
     assert_raise(ArgumentError) { a.flatten }
+
+    f = [].freeze
+    assert_raise(ArgumentError) { a.flatten!(1, 2) }
+    assert_raise(TypeError) { a.flatten!(:foo) }
+    assert_raise(ArgumentError) { f.flatten!(1, 2) }
+    assert_raise(RuntimeError) { f.flatten! }
+    assert_raise(RuntimeError) { f.flatten!(:foo) }
   end
 
   def test_shuffle
@@ -1756,7 +1784,7 @@
     assert_equal((1..10).to_a, a)
   end
 
-  def test_slice_freezed_array
+  def test_slice_frozen_array
     a = [1,2,3,4,5].freeze
     assert_equal([1,2,3,4], a[0,4])
     assert_equal([2,3,4,5], a[1,4])
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 26631)
+++ test/ruby/test_string.rb	(revision 26632)
@@ -875,6 +875,12 @@
     s2 = ["foo"].pack("p")
     s.replace(s2)
     assert_equal(s2, s)
+
+    fs = "".freeze
+    assert_raise(RuntimeError) { fs.replace("a") }
+    assert_raise(RuntimeError) { fs.replace(fs) }
+    assert_raise(ArgumentError) { fs.replace() }
+    assert_raise(RuntimeError) { fs.replace(42) }
   end
 
   def test_reverse
Index: test/ruby/test_hash.rb
===================================================================
--- test/ruby/test_hash.rb	(revision 26631)
+++ test/ruby/test_hash.rb	(revision 26632)
@@ -748,6 +748,13 @@
     h2 = {}
     h2.replace h1
     assert_equal(:foo, h2[0])
+
+    assert_raise(ArgumentError) { h2.replace() }
+    assert_raise(TypeError) { h2.replace(1) }
+    h2.freeze
+    assert_raise(ArgumentError) { h2.replace() }
+    assert_raise(RuntimeError) { h2.replace(h1) }
+    assert_raise(RuntimeError) { h2.replace(42) }
   end
 
   def test_size2

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

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