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