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/