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

ruby-changes:26166

From: nobu <ko1@a...>
Date: Thu, 6 Dec 2012 01:10:54 +0900 (JST)
Subject: [ruby-changes:26166] nobu:r38223 (trunk): vm_eval.c: public_send does not consider how it is called

nobu	2012-12-06 01:10:41 +0900 (Thu, 06 Dec 2012)

  New Revision: 38223

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

  Log:
    vm_eval.c: public_send does not consider how it is called
    
    * vm_eval.c (rb_method_call_status): use Qundef as no self instead of
      the current self.
    * vm_eval.c (send_internal): public_send does not consider how it is
      called, as mentioned in r14173.  patched by charliesome (Charlie
      Somerville).  [ruby-core:50489] [Bug #7499]

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_object.rb
    trunk/vm_eval.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38222)
+++ ChangeLog	(revision 38223)
@@ -1,3 +1,12 @@
+Thu Dec  6 01:10:36 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* vm_eval.c (rb_method_call_status): use Qundef as no self instead of
+	  the current self.
+
+	* vm_eval.c (send_internal): public_send does not consider how it is
+	  called, as mentioned in r14173.  patched by charliesome (Charlie
+	  Somerville).  [ruby-core:50489] [Bug #7499]
+
 Thu Dec  6 00:51:21 2012  Masaya Tarui  <tarui@r...>
 
 	* lib/timeout.rb (Timeout#timeout): specify a exception
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 38222)
+++ vm_eval.c	(revision 38223)
@@ -289,7 +289,8 @@
  * \param argc   the number of method arguments
  * \param argv   a pointer to an array of method arguments
  * \param scope
- * \param self   self in the caller. Qundef means the current control frame's self.
+ * \param self   self in the caller. Qundef means no self is considered and
+ *               protected methods cannot be called
  *
  * \note \a self is used in order to controlling access to protected methods.
  */
@@ -364,7 +365,7 @@
     }
 
     me = rb_search_method_entry(Qnil, recv, mid, &defined_class);
-    call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
+    call_status = rb_method_call_status(th, me, CALL_FCALL, th->cfp->self);
     if (call_status != NOEX_OK) {
 	if (rb_method_basic_definition_p(klass, idMethodMissing)) {
 	    return Qundef;
@@ -501,10 +502,7 @@
 		    defined_class = RBASIC(defined_class)->klass;
 		}
 
-		if (self == Qundef) {
-		    self = th->cfp->self;
-		}
-		if (!rb_obj_is_kind_of(self, defined_class)) {
+		if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) {
 		    return NOEX_PROTECTED;
 		}
 	    }
@@ -533,7 +531,8 @@
 static inline VALUE
 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
 {
-    return rb_call0(recv, mid, argc, argv, scope, Qundef, Qnil);
+    rb_thread_t *th = GET_THREAD();
+    return rb_call0(recv, mid, argc, argv, scope, th->cfp->self, Qnil);
 }
 
 NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv,
@@ -786,9 +785,10 @@
 					  const VALUE *argv,
 					  VALUE refinements)
 {
-    PASS_PASSED_BLOCK_TH(GET_THREAD());
+    rb_thread_t *th = GET_THREAD();
 
-    return rb_call0(recv, mid, argc, argv, CALL_PUBLIC, Qundef,
+    PASS_PASSED_BLOCK_TH(th);
+    return rb_call0(recv, mid, argc, argv, CALL_PUBLIC, th->cfp->self,
 		    refinements);
 }
 
@@ -797,9 +797,16 @@
 {
     ID id;
     VALUE vid;
-    VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
+    VALUE self;
     rb_thread_t *th = GET_THREAD();
 
+    if (scope == CALL_PUBLIC) {
+	self = Qundef;
+    }
+    else {
+	self = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp)->self;
+    }
+
     if (argc == 0) {
 	rb_raise(rb_eArgError, "no method name given");
     }
Index: test/ruby/test_object.rb
===================================================================
--- test/ruby/test_object.rb	(revision 38222)
+++ test/ruby/test_object.rb	(revision 38223)
@@ -587,6 +587,8 @@
     assert_raise(NoMethodError) {c.public_send(:priv)}
     assert_raise(NoMethodError) {c.public_send(:prot)}
     assert_raise(NoMethodError) {c.invoke(:priv)}
+    bug7499 = '[ruby-core:50489]'
+    assert_raise(NoMethodError, bug7499) {c.invoke(:prot)}
   end
 
   def test_no_superclass_method

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

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