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

ruby-changes:28045

From: nobu <ko1@a...>
Date: Thu, 4 Apr 2013 15:47:04 +0900 (JST)
Subject: [ruby-changes:28045] nobu:r40097 (trunk): enum.c: avoid inadvertent symbol creation

nobu	2013-04-04 15:46:53 +0900 (Thu, 04 Apr 2013)

  New Revision: 40097

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

  Log:
    enum.c: avoid inadvertent symbol creation
    
    * enum.c (enum_inject): avoid inadvertent symbol creation.

  Modified files:
    trunk/ChangeLog
    trunk/enum.c
    trunk/test/-ext-/symbol/test_inadvertent_creation.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40096)
+++ ChangeLog	(revision 40097)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Apr  4 15:46:48 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* enum.c (enum_inject): avoid inadvertent symbol creation.
+
 Thu Apr  4 14:37:07 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* thread.c (rb_thread_aref): avoid inadvertent symbol creation.
Index: enum.c
===================================================================
--- enum.c	(revision 40096)
+++ enum.c	(revision 40097)
@@ -17,6 +17,10 @@ https://github.com/ruby/ruby/blob/trunk/enum.c#L17
 
 #define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
 
+#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
+
+VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);
+
 VALUE rb_mEnumerable;
 
 static ID id_next;
@@ -527,6 +531,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/enum.c#L531
 inject_op_i(VALUE i, VALUE p, int argc, VALUE *argv)
 {
     NODE *memo = RNODE(p);
+    VALUE name;
 
     ENUM_WANT_SVALUE();
 
@@ -534,8 +539,14 @@ inject_op_i(VALUE i, VALUE p, int argc, https://github.com/ruby/ruby/blob/trunk/enum.c#L539
 	memo->u2.argc = 1;
 	memo->u1.value = i;
     }
+    else if (SYMBOL_P(name = memo->u3.value)) {
+	memo->u1.value = rb_funcall(memo->u1.value, SYM2ID(name), 1, i);
+    }
     else {
-	memo->u1.value = rb_funcall(memo->u1.value, memo->u3.id, 1, i);
+	VALUE args[2];
+	args[0] = name;
+	args[1] = i;
+	memo->u1.value = rb_f_send(numberof(args), args, memo->u1.value);
     }
     return Qnil;
 }
@@ -589,6 +600,7 @@ enum_inject(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/enum.c#L600
     NODE *memo;
     VALUE init, op;
     VALUE (*iter)(VALUE, VALUE, int, VALUE*) = inject_i;
+    ID id;
 
     switch (rb_scan_args(argc, argv, "02", &init, &op)) {
       case 0:
@@ -597,7 +609,8 @@ enum_inject(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/enum.c#L609
 	if (rb_block_given_p()) {
 	    break;
 	}
-	op = (VALUE)rb_to_id(init);
+	id = rb_check_id(&init);
+	op = id ? ID2SYM(id) : init;
 	argc = 0;
 	init = Qnil;
 	iter = inject_op_i;
@@ -606,7 +619,8 @@ enum_inject(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/enum.c#L619
 	if (rb_block_given_p()) {
 	    rb_warning("given block not used");
 	}
-	op = (VALUE)rb_to_id(op);
+	id = rb_check_id(&op);
+	if (id) op = ID2SYM(id);
 	iter = inject_op_i;
 	break;
     }
Index: test/-ext-/symbol/test_inadvertent_creation.rb
===================================================================
--- test/-ext-/symbol/test_inadvertent_creation.rb	(revision 40096)
+++ test/-ext-/symbol/test_inadvertent_creation.rb	(revision 40097)
@@ -187,5 +187,11 @@ module Test_Symbol https://github.com/ruby/ruby/blob/trunk/test/-ext-/symbol/test_inadvertent_creation.rb#L187
       assert_not_send([Thread.current, :thread_variable?, name])
       assert_not_send([Bug::Symbol, :interned?, name])
     end
+
+    def test_enumerable_inject_op
+      name = noninterned_name
+      assert_raise(NoMethodError) {[1, 2].inject(name)}
+      assert_not_send([Bug::Symbol, :interned?, name])
+    end
   end
 end

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

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