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

ruby-changes:27825

From: marcandre <ko1@a...>
Date: Sat, 23 Mar 2013 07:30:56 +0900 (JST)
Subject: [ruby-changes:27825] marcandRe: r39877 (trunk): * array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

marcandre	2013-03-23 07:30:45 +0900 (Sat, 23 Mar 2013)

  New Revision: 39877

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

  Log:
    * array.c: Avoid zip bug by not using obsolete rb_check_block_call [Bug #8153]

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/test/ruby/test_array.rb

Index: array.c
===================================================================
--- array.c	(revision 39876)
+++ array.c	(revision 39877)
@@ -17,6 +17,7 @@ https://github.com/ruby/ruby/blob/trunk/array.c#L17
 #include "ruby/encoding.h"
 #include "internal.h"
 #include "probes.h"
+#include "node.h"
 #include "id.h"
 
 #ifndef ARRAY_DEBUG
@@ -3032,11 +3033,11 @@ rb_ary_delete_if(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L3033
 }
 
 static VALUE
-take_i(VALUE val, VALUE *args, int argc, VALUE *argv)
+take_i(VALUE i, VALUE args, int argc, VALUE *argv)
 {
-    if (args[1]-- == 0) rb_iter_break();
-    if (argc > 1) val = rb_ary_new4(argc, argv);
-    rb_ary_push(args[0], val);
+    NODE *memo = RNODE(args);
+    rb_ary_push(memo->u1.value, rb_enum_values_pack(argc, argv));
+    if (--memo->u3.cnt == 0) rb_iter_break();
     return Qnil;
 }
 
@@ -3044,18 +3045,19 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L3045
 take_items(VALUE obj, long n)
 {
     VALUE result = rb_check_array_type(obj);
-    VALUE args[2];
+    NODE *memo;
 
     if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
+    if (!rb_respond_to(obj, idEach)) {
+	rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
+	    rb_obj_classname(obj));
+    }
     result = rb_ary_new2(n);
-    args[0] = result; args[1] = (VALUE)n;
-    if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
-        rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
-            rb_obj_classname(obj));
+    memo = NEW_MEMO(result, 0, n);
+    rb_block_call(obj, idEach, 0, 0, take_i, (VALUE)memo);
     return result;
 }
 
-
 /*
  *  call-seq:
  *     ary.zip(arg, ...)                  -> new_ary
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39876)
+++ ChangeLog	(revision 39877)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Mar 23 07:30:31 2013  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* array.c: Avoid zip bug by not using obsolete rb_check_block_call
+	  [Bug #8153]
+
 Fri Mar 22 17:48:34 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/forwardable.rb (Forwardable::FILE_REGEXP): create regexp object
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 39876)
+++ test/ruby/test_array.rb	(revision 39877)
@@ -1918,6 +1918,15 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1918
     assert_equal([['a', 5], ['b', 6]], %w(a b).zip(ary))
   end
 
+  def test_zip_bug
+    bug8153 = "ruby-core:53650"
+    r = 1..1
+    def r.respond_to?(*)
+      super
+    end
+    assert_equal [[42, 1]], [42].zip(r), bug8153
+  end
+
   def test_transpose
     assert_equal([[1, :a], [2, :b], [3, :c]],
       [[1, 2, 3], [:a, :b, :c]].transpose)

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

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