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

ruby-changes:1784

From: ko1@a...
Date: 26 Aug 2007 05:57:00 +0900
Subject: [ruby-changes:1784] ko1 - Ruby:r13275 (trunk): * insnhelper.ci (vm_call_method): fix to relaxant safe level check

ko1	2007-08-26 05:56:51 +0900 (Sun, 26 Aug 2007)

  New Revision: 13275

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/test_method.rb
    trunk/insnhelper.ci

  Log:
    * insnhelper.ci (vm_call_method): fix to relaxant safe level check
      ($SAFE > 2).  [ruby-core:11998]
    * bootstraptest/test_method.rb: add tests for above.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insnhelper.ci?r1=13275&r2=13274
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13275&r2=13274
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_method.rb?r1=13275&r2=13274

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13274)
+++ ChangeLog	(revision 13275)
@@ -1,3 +1,10 @@
+Sun Aug 26 05:54:49 2007  Koichi Sasada  <ko1@a...>
+
+	* insnhelper.ci (vm_call_method): fix to relaxant safe level check
+	  ($SAFE > 2).  [ruby-core:11998]
+
+	* bootstraptest/test_method.rb: add tests for above.
+
 Sun Aug 26 05:52:08 2007  Koichi Sasada  <ko1@a...>
 
 	* test/ruby/test_fiber.rb: fix to require 'continuation'.
Index: bootstraptest/test_method.rb
===================================================================
--- bootstraptest/test_method.rb	(revision 13274)
+++ bootstraptest/test_method.rb	(revision 13275)
@@ -916,3 +916,44 @@
   end
   C.new.m
 }
+
+assert_equal 'ok', %q{
+  proc{
+    $SAFE = 1
+    class C
+      def m
+        :ok
+      end
+    end
+  }.call
+  C.new.m
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+  proc{
+    $SAFE = 2
+    class C
+      def m
+        :ok
+      end
+    end
+  }.call
+  C.new.m
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+  proc{
+    $SAFE = 3
+    class C
+      def m
+        :ng
+      end
+    end
+  }.call
+  begin
+    C.new.m
+  rescue SecurityError
+    :ok
+  end
+}, '[ruby-core:11998]'
+
Index: insnhelper.ci
===================================================================
--- insnhelper.ci	(revision 13274)
+++ insnhelper.ci	(revision 13275)
@@ -472,101 +472,108 @@
 
   start_method_dispatch:
 
-    /* method missing */
-    if (mn == 0) {
-	if (id == idMethodMissing) {
-	    rb_bug("method missing");
+    if ((mn != 0)) {
+	if ((mn->nd_noex == 0)) {
+	    /* dispatch method */
+	    NODE *node;
+
+	  normal_method_dispatch:
+
+	    node = mn->nd_body;
+
+	    switch (nd_type(node)) {
+	      case RUBY_VM_METHOD_NODE:{
+		  vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
+		  return Qundef;
+	      }
+	      case NODE_CFUNC:{
+		  val = vm_call_cfunc(th, cfp, num, id, recv, klass, node, blockptr);
+		  break;
+	      }
+	      case NODE_ATTRSET:{
+		  val = rb_ivar_set(recv, node->nd_vid, *(cfp->sp - 1));
+		  cfp->sp -= 2;
+		  break;
+	      }
+	      case NODE_IVAR:{
+		  val = rb_ivar_get(recv, node->nd_vid);
+		  cfp->sp -= 1;
+		  break;
+	      }
+	      case NODE_BMETHOD:{
+		  VALUE *argv = cfp->sp - num;
+		  val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv);
+		  cfp->sp += - num - 1;
+		  break;
+	      }
+	      case NODE_ZSUPER:{
+		  klass = RCLASS(mn->nd_clss)->super;
+		  mn = rb_method_node(klass, id);
+
+		  if (mn != 0) {
+		      goto normal_method_dispatch;
+		  }
+		  else {
+		      goto start_method_dispatch;
+		  }
+	      }
+	      default:{
+		  printf("node: %s\n", ruby_node_name(nd_type(node)));
+		  rb_bug("eval_invoke_method: unreachable");
+		  /* unreachable */
+		  break;
+	      }
+	    }
 	}
 	else {
-	    int stat = 0;
-	    if (flag & VM_CALL_VCALL_BIT) {
-		stat |= NOEX_VCALL;
-	    }
-	    if (flag & VM_CALL_SUPER_BIT) {
-		stat |= NOEX_SUPER;
-	    }
-	    val = vm_method_missing(th, id, recv, num, blockptr, stat);
-	}
-    }
-    else if (UNLIKELY(mn->nd_noex)) {
-	if (!(flag & VM_CALL_FCALL_BIT) &&
-	    (mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
-	    int stat = NOEX_PRIVATE;
-	    if (flag & VM_CALL_VCALL_BIT) {
-		stat |= NOEX_VCALL;
-	    }
-	    val = vm_method_missing(th, id, recv, num, blockptr, stat);
-	}
-	else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
-	    VALUE defined_class = mn->nd_clss;
+	    int noex_safe;
 
-	    if (TYPE(defined_class) == T_ICLASS) {
-		defined_class = RBASIC(defined_class)->klass;
+	    if (!(flag & VM_CALL_FCALL_BIT) &&
+		(mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
+		int stat = NOEX_PRIVATE;
+
+		if (flag & VM_CALL_VCALL_BIT) {
+		    stat |= NOEX_VCALL;
+		}
+		val = vm_method_missing(th, id, recv, num, blockptr, stat);
 	    }
+	    else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
+		VALUE defined_class = mn->nd_clss;
 
-	    if (!rb_obj_is_kind_of(cfp->self, rb_class_real(defined_class))) {
-		val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
+		if (TYPE(defined_class) == T_ICLASS) {
+		    defined_class = RBASIC(defined_class)->klass;
+		}
+
+		if (!rb_obj_is_kind_of(cfp->self, rb_class_real(defined_class))) {
+		    val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
+		}
+		else {
+		    goto normal_method_dispatch;
+		}
 	    }
+	    else if ((noex_safe = NOEX_SAFE(mn->nd_noex)) > th->safe_level &&
+		     (noex_safe > 2)) {
+		rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id));
+	    }
 	    else {
 		goto normal_method_dispatch;
 	    }
 	}
-	else if (NOEX_SAFE(mn->nd_noex) > th->safe_level) {
-	    rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id));
+    }
+    else {
+	/* method missing */
+	if (id == idMethodMissing) {
+	    rb_bug("method missing");
 	}
 	else {
-	    goto normal_method_dispatch;
-	}
-    }
-
-    /* dispatch method */
-    else {
-	NODE *node;
-      normal_method_dispatch:
-
-	node = mn->nd_body;
-	switch (nd_type(node)) {
-	  case RUBY_VM_METHOD_NODE:{
-	    vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
-	    return Qundef;
-	  }
-	  case NODE_CFUNC:{
-	    val = vm_call_cfunc(th, cfp, num, id, recv, klass, node, blockptr);
-	    break;
-	  }
-	  case NODE_ATTRSET:{
-	    val = rb_ivar_set(recv, node->nd_vid, *(cfp->sp - 1));
-	    cfp->sp -= 2;
-	    break;
-	  }
-	  case NODE_IVAR:{
-	    val = rb_ivar_get(recv, node->nd_vid);
-	    cfp->sp -= 1;
-	    break;
-	  }
-	  case NODE_BMETHOD:{
-	    VALUE *argv = cfp->sp - num;
-	    val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv);
-	    cfp->sp += - num - 1;
-	    break;
-	  }
-	  case NODE_ZSUPER:{
-	    klass = RCLASS(mn->nd_clss)->super;
-	    mn = rb_method_node(klass, id);
-
-	    if (mn != 0) {
-		goto normal_method_dispatch;
+	    int stat = 0;
+	    if (flag & VM_CALL_VCALL_BIT) {
+		stat |= NOEX_VCALL;
 	    }
-	    else {
-		goto start_method_dispatch;
+	    if (flag & VM_CALL_SUPER_BIT) {
+		stat |= NOEX_SUPER;
 	    }
-	  }
-	  default:{
-	    printf("node: %s\n", ruby_node_name(nd_type(node)));
-	    rb_bug("eval_invoke_method: unreachable");
-	    /* unreachable */
-	    break;
-	  }
+	    val = vm_method_missing(th, id, recv, num, blockptr, stat);
 	}
     }
 

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

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