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

ruby-changes:58028

From: Jeremy <ko1@a...>
Date: Mon, 30 Sep 2019 08:29:10 +0900 (JST)
Subject: [ruby-changes:58028] 58dfea0c8d (master): Make direct calls to rb_{obj_instance, mod_module}_{eval, exec} not pass keywords

https://git.ruby-lang.org/ruby.git/commit/?id=58dfea0c8d

From 58dfea0c8de29cbad35621847c04372b779c5f5d Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Sun, 29 Sep 2019 13:15:04 -0700
Subject: Make direct calls to rb_{obj_instance,mod_module}_{eval,exec} not
 pass keywords

In general RB_PASS_CALLED_KEYWORDS should only be set if we are
sure the arguments passed come directly from Ruby.  For direct calls
to these C functions, we should not assume that keywords are passed.
Add static *_internal versions of these functions that
Kernel#instance_{eval,exec} and Module#{class,module}_{eval,exec}
call that set RB_PASS_CALLED_KEYWORDS.

Also, change struct.c back to calling rb_mod_module_eval, now that
the call is safe.

diff --git a/struct.c b/struct.c
index 3a631ab..b293574 100644
--- a/struct.c
+++ b/struct.c
@@ -569,7 +569,7 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L569
     setup_struct(st, rest);
     rb_ivar_set(st, id_keyword_init, keyword_init);
     if (rb_block_given_p()) {
-        rb_funcall_passing_block(st, rb_intern("module_eval"), 0, 0);
+        rb_mod_module_eval(0, 0, st);
     }
 
     return st;
diff --git a/vm_eval.c b/vm_eval.c
index b97e352..04a1315 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1781,7 +1781,7 @@ rb_eval_cmd(VALUE cmd, VALUE arg, int level) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1781
 /* block eval under the class/module context */
 
 static VALUE
-yield_under(VALUE under, VALUE self, int argc, const VALUE *argv)
+yield_under(VALUE under, VALUE self, int argc, const VALUE *argv, int kw_splat)
 {
     rb_execution_context_t *ec = GET_EC();
     rb_control_frame_t *cfp = ec->cfp;
@@ -1793,7 +1793,6 @@ yield_under(VALUE under, VALUE self, int argc, const VALUE *argv) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1793
     rb_cref_t *cref;
     int is_lambda = FALSE;
     VALUE v = 0, ret;
-    int kw_splat = RB_PASS_CALLED_KEYWORDS;
 
     v = rb_adjust_argv_kw_splat(&argc, &argv, &kw_splat);
 
@@ -1865,11 +1864,11 @@ eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1864
 }
 
 static VALUE
-specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self)
+specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self, int kw_splat)
 {
     if (rb_block_given_p()) {
 	rb_check_arity(argc, 0, 0);
-	return yield_under(klass, self, 1, &self);
+        return yield_under(klass, self, 1, &self, kw_splat);
     }
     else {
 	VALUE file = Qundef;
@@ -1938,11 +1937,18 @@ singleton_class_for_eval(VALUE self) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1937
  *     k.instance_eval {|obj| obj == self } #=> true
  */
 
+static VALUE
+rb_obj_instance_eval_internal(int argc, const VALUE *argv, VALUE self)
+{
+    VALUE klass = singleton_class_for_eval(self);
+    return specific_eval(argc, argv, klass, self, RB_PASS_CALLED_KEYWORDS);
+}
+
 VALUE
 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
 {
     VALUE klass = singleton_class_for_eval(self);
-    return specific_eval(argc, argv, klass, self);
+    return specific_eval(argc, argv, klass, self, RB_NO_KEYWORDS);
 }
 
 /*
@@ -1963,11 +1969,18 @@ rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1969
  *     k.instance_exec(5) {|x| @secret+x }   #=> 104
  */
 
+static VALUE
+rb_obj_instance_exec_internal(int argc, const VALUE *argv, VALUE self)
+{
+    VALUE klass = singleton_class_for_eval(self);
+    return yield_under(klass, self, argc, argv, RB_PASS_CALLED_KEYWORDS);
+}
+
 VALUE
 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
 {
     VALUE klass = singleton_class_for_eval(self);
-    return yield_under(klass, self, argc, argv);
+    return yield_under(klass, self, argc, argv, RB_NO_KEYWORDS);
 }
 
 /*
@@ -1997,10 +2010,16 @@ rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L2010
  *         or method `code' for Thing:Class
  */
 
+static VALUE
+rb_mod_module_eval_internal(int argc, const VALUE *argv, VALUE mod)
+{
+    return specific_eval(argc, argv, mod, mod, RB_PASS_CALLED_KEYWORDS);
+}
+
 VALUE
 rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
 {
-    return specific_eval(argc, argv, mod, mod);
+    return specific_eval(argc, argv, mod, mod, RB_NO_KEYWORDS);
 }
 
 /*
@@ -2025,10 +2044,16 @@ rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L2044
  *     Hello there!
  */
 
+static VALUE
+rb_mod_module_exec_internal(int argc, const VALUE *argv, VALUE mod)
+{
+    return yield_under(mod, mod, argc, argv, RB_PASS_CALLED_KEYWORDS);
+}
+
 VALUE
 rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
 {
-    return yield_under(mod, mod, argc, argv);
+    return yield_under(mod, mod, argc, argv, RB_NO_KEYWORDS);
 }
 
 /*
@@ -2407,8 +2432,8 @@ Init_vm_eval(void) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L2432
 
     rb_define_global_function("loop", rb_f_loop, 0);
 
-    rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
-    rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
+    rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval_internal, -1);
+    rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec_internal, -1);
     rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
 
 #if 1
@@ -2422,10 +2447,10 @@ Init_vm_eval(void) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L2447
 #endif
     rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
 
-    rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
-    rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
-    rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
-    rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
+    rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec_internal, -1);
+    rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec_internal, -1);
+    rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval_internal, -1);
+    rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval_internal, -1);
 
     rb_eUncaughtThrow = rb_define_class("UncaughtThrowError", rb_eArgError);
     rb_define_method(rb_eUncaughtThrow, "initialize", uncaught_throw_init, -1);
-- 
cgit v0.10.2


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

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